anomalyco/opencode:204.7k stars 的开源 AI 编码 Agent,客户端 / 服务端分离让 TUI、桌面、Web 共享同一个大脑
上个月我换了一台新 Mac,配置完之后第一件事是装 Claude Code,第二件事是装 Codex CLI,第三件事是装 opencode。三件并排放,桌面图标长得不一样,启动后长得也不一样,但干的事情大半是重叠的:这周我要么在一个里改文件,要么三个里选一个改。
三件里面,Claude Code 是闭源商业产品,Codex 是 OpenAI 的官方客户端,而 opencode 是个 MIT 开源项目。204.7k stars,26.7k forks,当日新增 725 stars,TypeScript 写,单一 monorepo。
让我留下来的不是它” 也能像 Claude Code 一样用”。是它把” 一个 agent 工具” 这件事拆成了” 一个服务端” 加” 多个客户端”。
一、为什么需要第三个 AI 编码 Agent
先说清楚背景。2025 年下半年到现在,AI 编码 Agent 这一档已经拥挤到能写综述了。终端系有 Claude Code、Codex CLI、Gemini CLI、opencode;IDE 插件系有 Cursor、Copilot、Cody、Windsurf;桌面系有 Cursor、Claude 桌面、opencode 桌面。每家都差不多能干同一件事:让模型在真实代码库里改文件、跑命令、提交。
这种密集度下,新来者想要被注意,必须在某个具体的点上做得不一样。opencode 选的点是部署形态,这个选择让它在” 想用 AI 改代码但不想被供应商绑死” 这个细分需求上立住了。
它假设你不是” 在 IDE 里写代码” 这一种人。你可能想要在终端里跑(TUI),可能想要一个独立窗口(桌面应用),可能想要在你的 Web 应用里嵌入一个会话(控制台),可能想要在 CI 里跑(无头),可能想要把它的能力当成后端服务接到自己的产品里(SDK)。
传统 AI 编码 Agent 的做法是把 TUI、桌面、Web、SDK 写四份共享部分四份维护。opencode 的做法是写一个服务端(packages/opencode),其他都是它的客户端。TUI(packages/tui)、桌面(packages/desktop)、Web 控制台(packages/console)、官方 Web 站(packages/web)、HTTP API(packages/server)、第三方 SDK(packages/sdk),全都在跟同一个服务端说话。
这种拆分带来一个具体好处:会话状态跟着服务端走,不跟着客户端走。你在 TUI 里开了一个会话,改了 12 个文件,跑到一半合上笔记本。第二天打开桌面应用,会话从断点续上。你在云开发机上跑一个 opencode serve,从家里笔记本的 IDE 插件连过去,连的是同一份 session。SDK 可以把你的产品接到 opencode 的服务端,不用嵌整个 CLI。
这种拆分我以前只在 GitHub 自身的 hub(hub clone 下来的不止 CLI 还包括 daemon)和某些带桌面端的命令行工具里见过。opencode 是把这种拆分当一等设计目标来做的。
二、产品形态:一个 TUI、一个桌面应用、一个控制台
README 写得很克制,连个截图说明都没有,但放了三张主界面的图在 docs 站点。
TUI 是默认入口。终端原生,双面板布局,左边是会话列表,右边是消息流。键盘驱动,Tab 在主 agent 之间切换,@ 唤起子 agent,/ 触发斜杠命令。主题可以换,仓库的 .opencode/themes/ 目录里已经放了官方主题仓库的引用,README 把” 自己写一个主题” 列为欢迎贡献的方向。
桌面应用 还标着 BETA。opencode.ai/download 提供 Apple Silicon / Intel 的 DMG、Windows EXE、Linux 的 deb /rpm/ AppImage。装完就是一个独立窗口。同一个服务端进程。
Web 控制台 在 opencode.ai 站点上。如果你有 opencode 服务端跑在某个机器上(本地或者远程),可以在浏览器里连过去用。控制台和桌面是同一份 UI 库(packages/ui)渲染的,看着像一家的东西。
官方 Web 站 是营销页,不是产品。packages/web 是放官网的,不是产品本体。这种” 产品 + 官网 + 控制台是三个包” 的拆分是 monorepo 项目的常态,但 opencode 把这条线画得特别清楚。
HTTP API 走 packages/server,所有功能都通过 HTTP 暴露。第三方 SDK 走 packages/sdk,从 server/ 自动生成 client(script/schema.ts 跑 httpapi-codegen)。也就是说任何语言只要能发 HTTP 请求,就能拿 opencode 当后端用。
npm 包名是 opencode-ai,所以 npx opencode-ai@latest 就是入口二进制。
三、Agent 体系:两个主、三个子
opencode 的 agent 抽象是我翻 docs 时最先注意到的东西,因为它的设计比大多数同类产品都更精细。
主 agent 两个:Build 和 Plan。 Tab 键切换。两者最大的差别不是模型,是权限。
Build 是默认,文件编辑、bash 命令、补丁、应用全部开绿灯。开发用。Plan 是只读,所有写操作默认 ask(询问确认),bash 命令也 ask。它存在的目的就是当你想让模型看完代码、给建议、写计划,但不真的让它改文件。
Plan 模式切过去,模型仍然能读文件、跑命令、调用工具,但它不会直接动你的代码。这是个细节,但解决了” 我想用 AI 帮我看看这个模块怎么改,但我信不过它一次写对” 这种实际场景。
子 agent 三个:General、Explore、Scout。 主 agent 可以通过 @general、@explore、@scout 在消息里调用。
- General 是通用子 agent,能跑多步任务、有完整工具访问(除 todo),可以并行跑多个单元工作。Claude Code 里那个
general-purpose子 agent 的对位。 - Explore 是只读搜索子 agent,针对在陌生代码库里做调研设计。
- Scout 文档里有定义但没在 README 突出。
子 agent 的可发现性写在提示词里,所以主 agent 在合适的时候会自动派工,不合适的时候也会显式 mention 让用户决定。这个设计跟 Claude Code 的” 工具描述里写明使用条件” 思路是同一条线,但 opencode 把粒度拆得更细。
举一个具体场景。打开一个陌生仓库,我想知道” 这个项目里的 WebSocket 客户端是怎么做心跳重连的”,我开 TUI,按 Tab 切到 Plan agent,消息里写:
1 | @explore 找出 ~/projects/foo/src 里所有跟 WebSocket 重连相关的代码, |
Plan agent 不会改文件,但可以读文件、跑命令、调用工具。它把任务派给 Explore(也是只读搜索子 agent),Explore 在代码库里 grep 一圈、查 LSP 拿到类型信息、汇总出一份报告给 Plan,Plan 整理完回我。整个过程我没授权任何写操作,重连策略和所有调用方都列在屏幕上。
然后我按 Tab 切到 Build agent,写:
1 | 按 explore 的发现,把退避改成指数退避,上限 30 秒,加单测。 |
Build 改了三个文件,加了一个单测文件,跑了一遍测试。中途要 bash 跑 npm test 和 git add 都被 permission 拦下来问了我一次。这是 Plan 和 Build 配合的典型用法。
自定义 agent 在 opencode.jsonc 里的 agent 段配置,可以指定模型、权限、提示词、可用工具。这块跟 Claude Code 的 subagent 配置几乎一一对应。
四、模型层:75+ 提供商,AI SDK + Models.dev 双源
Provider 这块 opencode 走的是 Vercel AI SDK 加 Models.dev 联合的方案。
Vercel AI SDK(ai-sdk.dev)把每个提供商的鉴权、消息格式、工具调用、流式响应统一成一套接口。Models.dev 维护一个持续更新的模型目录,包含每个模型的上下文窗口、最大输出、价格、是否支持工具调用、是否支持图像输入等等。opencode 在启动时从 models.dev 拉最新数据,运行时按需查表。
这套组合的结果是支持 75+ 个 LLM 提供商。OpenAI、Anthropic、Google、xAI、DeepSeek、Qwen、GLM、Mistral、Cohere、Groq、Together AI、Fireworks、Cerebras、Hugging Face、Perplexity、本地 Ollama、LM Studio、vLLM、llama.cpp,几乎覆盖了所有能叫出名字的厂商。
凭据通过 /connect 命令配,存在 ~/.local/share/opencode/auth.json。这个路径在 XDG Base Directory 规范下,macOS 上是 ~/Library/Application Support/opencode/。
自定义 baseURL 支持设 proxy:
1 | { |
模型选择策略在 provider 配置里可以分层指定:provider 级别一个默认,agent 级别可以覆盖。给 Plan agent 配一个便宜模型,给 Build agent 配一个贵但准的模型,是常见做法。
自带统计。 仓库根目录的描述里有一句”track your daily, weekly, and monthly token usage and costs across all your providers”。这个能力由 packages/stats 包实现,会在控制台里画图表。free tier 用户的 token 行为可以本地看,企业版(packages/enterprise)应该可以集中看团队的。
模型选择的实际取舍
75+ 个 provider 听起来像好处,但在你真正选模型的时候,问题会变具体。
我自己的分层。Plan agent 配 claude-haiku-4-5 或 gpt-5-nano 一档,cost 低、context window 大、主要任务是读代码做总结。Build agent 配 claude-sonnet-4-5 或 gpt-5,贵但准,改代码的主力。Explore 子 agent 配跟 Plan 一样的便宜模型,搜索任务对推理深度要求低。
长上下文任务。如果你的项目超过 100k tokens,闭源大模型(Claude、GPT、Gemini Pro)默认 200k-1M 上下文,本地模型(Qwen3-Coder、DeepSeek-Coder)通常 32k-128k。这种情况下 Plan agent 用本地模型基本就废。
工具调用可靠性。各家模型对 tool call 的支持稳定度差别很大。Claude 和 GPT 系列的 tool call 协议遵循得最稳,DeepSeek 和 GLM 在某些边缘 case 上会给出格式错的 tool call。opencode 这种 Vercel AI SDK 抽象层会做一层 retry,但 retry 多了 token 涨得快。
多模态。改 UI 任务常需要模型” 看截图”。Claude、Gemini、GPT-4o 之后的模型都支持。opencode 工具集里有 webfetch,能拉 URL 但不能读本地图片。截图分析得通过外部 MCP server 加,官方有 mcp-server-screenshot 之类的实现。
自定义 provider
如果 75+ 个 provider 没覆盖你的模型,比如公司内部部署的 LLM,可以自己写一个 provider adapter。packages/core/src/config/provider.ts 是配置加载入口:
1 | { |
Vercel AI SDK 有 openai-compatible 这个 npm 包,对接任何 OpenAI 兼容的 API。你只要提供 baseURL 和 API key,剩下交给 SDK。这套机制让你能在不改 opencode 源码的情况下加新模型。
五、客户端 / 服务端架构:30+ 个包怎么搭起来的
项目根目录是一个标准的 Bun monorepo,pnpm /bun workspaces 风格。packages/ 下面 30+ 个包,按职责切片。
packages/core 是基础设施层。Drizzle schema、SQLite 迁移、配置加载、插件系统、LLM provider 适配、agent 配置、命令系统、工具输出格式化、文件监视器、Markdown 渲染、LSP 配置、MCP 配置 —— 所有跨客户端共享的能力都在这里。
packages/opencode 是服务端本尊。负责会话、Agent 循环、文件操作、工具调用、MCP 客户端。bin/opencode 是入口二进制,能跑在 headless 模式也能起 TUI。
packages/tui 是 TUI 客户端。SolidJS 渲染(packages/ui 提供组件库)。packages/desktop 是 Tauri 桌面壳子。packages/console 和 packages/web 是 SolidStart 应用,一个面向产品控制台,一个面向营销站。
packages/llm 把 AI SDK 包了一层,加了 opencode 自己的 session 管理、stream 转换、tool call 解析。packages/schema 是 zod schema 源头,server 和 SDK 都从这里生成 TypeScript 类型。
packages/sdk 是第三方 SDK,目前看只有 JavaScript 实现,从 packages/server 的 OpenAPI 自动生成 client。packages/sdk-next 看名字是实验下一代。packages/python 有发布流水线(publish-python-sdk.yml),应该有 Python SDK 在路上。
packages/identity 是身份认证包。packages/slack 是个 Slack 集成。packages/codemode 跟” 代码即上下文” 那种 agent 设计相关。
packages/storybook 是 UI 组件的开发环境。packages/containers 是 Docker 镜像构建。packages/effect-drizzle-sqlite 和 packages/effect-sqlite-node 是基于 Effect 框架的 SQLite 绑定(这个项目大量用 Effect)。
这种分法让” 做一个新客户端” 的成本是” 找一个 HTTP 客户端”+” 渲染 packages/ui 组件”。理论上任何能发 HTTP 的环境都能接到 opencode。我在自己的几个小项目里验证过,浏览器里的 SolidStart 应用通过 fetch 直接调 server 端点,能在 50 行内复刻一个简化版 TUI 出来。
服务端和客户端的协议走 HTTP + Server-Sent Events 流式响应,跟 OpenAI 的 Chat Completions API 风格类似。packages/server 的中间件是 hono,日志走 pino。
数据持久层:Drizzle + SQLite
会话状态要存,统计要存,配置变更要追踪。opencode 选了 Drizzle ORM 加 SQLite 的组合,没用 Prisma 也没用 Postgres。
为什么是 Drizzle。Drizzle 是 TypeScript 写的 SQL-first ORM,类型推导从 schema 直接出,迁移用 SQL 文件管理,运行时开销几乎为零。在 Bun runtime 上 Drizzle 跑得比 Prisma 快一个量级。opencode 的 packages/core/src/account/sql.ts 和 packages/core/src/account.ts 用 Drizzle 定义了账户、会话、消息、文件变更的 schema。
为什么是 SQLite。单机部署是 opencode 的典型形态,会话和统计数据量不大(一个用户一辈子能有多少个 session?几千条),SQLite 完全扛得住,部署成本为零。packages/core/src/ 下面所有 *.sql.ts 文件就是 schema 定义。
迁移。packages/core 下面有 script/migration.ts 和 drizzle.config.ts,自动生成 + 应用迁移。packages/opencode/migration/ 目录里已经放了几个历史迁移,包括 20260511173437_session-metadata 这种带时间戳的命名。每次 schema 改一次,agent 自动跑 migration 升级本地数据库。
多用户和企业。packages/enterprise 是给多用户企业场景准备的。SQLite 显然是单机,enterprise 包换成了多用户后端(猜测是 Postgres 或类似),身份认证走 packages/identity 包。opencode.ai 控制台让你登录看团队统计和共享 session,这部分逻辑在 enterprise 包里。
这种” 单机 SQLite + 企业 Postgres” 的双层设计是 SaaS 工具常见的折中。开源版本完全单机、自包含、零配置;企业版本集中、可审计、可计费。两套代码共享同一个 Drizzle schema,差异在 connection 层。
跑一个独立的 server
opencode serve 命令启动一个无头的 HTTP 服务,端口默认 4096,默认绑 127.0.0.1:
1 | opencode serve --port 4096 --hostname 0.0.0.0 --cors https://app.example.com |
CORS flag 可以重复传,多次指定多个 origin。
当你跑 opencode(不带参数),TUI 起来的同时会自动起一个 server,随机端口、127.0.0.1。这个 server 是 TUI 在跟自己对话。TUI 是 server 的 client。opencode serve 显式起一个独立的 server 进程,可以被任何 HTTP 客户端(包括另一台机器上的 TUI 或者一个远程 IDE 插件)连。
发现机制有 mDNS 选项。--mdns 开启后,opencode 在局域网内广播 _opencode._tcp 服务,其他设备可以自动发现。--mdns-domain opencode.local 改广播名。
认证用 HTTP Basic Auth:
1 | OPENCODE_SERVER_PASSWORD=your-password opencode serve |
默认用户名 opencode,用 OPENCODE_SERVER_USERNAME 覆盖。这条对 opencode serve 和 opencode web 都生效。
server 暴露的 OpenAPI 3.1 规范文档在 /doc 路径下,比如 http://localhost:4096/doc。可以直接拖到 Swagger UI 看,也可以用它生成任意语言的 client。packages/sdk 里的 JavaScript SDK 就是这么来的。
/tui endpoint 是个有趣的彩蛋:可以通过 server 驱动 TUI。你可以预先填好 prompt 然后触发 TUI 开始执行。官方 IDE 插件(opencode.ai/docs/ide)就是用这个机制把 server 接到 IDE 里的。
六、扩展性:MCP、插件、命令、主题、技能 + 权限 + 工具集
翻 packages/core/src/config/ 目录,会发现 opencode 把” 用户能改的东西” 拆成了一打独立的概念,每个都有自己的加载、合并、优先级规则。这一节把扩展机制、权限系统、内置工具一起讲完,因为它们是同一层。
扩展机制
MCP 服务器 通过 mcp 段配置,支持本地 stdio 和远程 SSE 两种传输。装上之后 MCP 工具自动出现在主 agent 的可用工具列表里。docs 里特意标了一条警告:MCP 工具加进上下文有 token 成本,GitHub MCP 那种会很快撑爆 context。
插件 通过 plugin 段配置,仓库根目录的 .opencode/plugins/ 已经放了一个 tui-smoke.tsx 当示例,主题插件 smoke-theme.json 也是同源。插件系统是 opencode 自己的,不复用 Claude Code 的 marketplace 协议。
命令(slash command)通过 command 段配置。仓库根目录的 .opencode/command/ 已经放了 8 个内置命令:ai-deps、changelog、commit、issues、learn、rmslop、spellcheck、translate。每个 command 是一个 prompt 模板,触发后模型按模板工作。这是把” 团队最佳实践” 固化成可重用命令的常见模式。
技能(skill)通过 skill 段配置。仓库根目录的 .opencode/skills/ 已经放了 effect 和 rtl-aware-development 两个技能。技能比命令的颗粒度更细,模型按需激活。
主题 通过 theme 段配置。TUI 和桌面都支持换主题。packages/ui 的样式系统允许用户做完整覆盖。
配置文件搜索路径有优先级:./opencode.jsonc > ./.opencode/opencode.jsonc > 用户全局 ~/.config/opencode/opencode.jsonc > 内置默认。config 包里的 reference.ts 处理这套合并。
LSP(Language Server Protocol)通过 lsp 段配置。opencode 内置了对常见语言的 LSP 客户端,自动调用类型信息、跳转到定义、查找引用。这是它跟” 普通 LLM 改文件” 分水岭最大的功能之一:模型能拿到真实的类型而不是自己猜。代价是冷启动慢,TypeScript 项目第一次跑要 30 秒到 2 分钟起 tsserver。
AGENTS.md 自动加载。opencode 在会话开始时读仓库根目录的 AGENTS.md(如果有),把里面的内容作为 agent 的额外指令。packages/core/src/config/markdown.ts 负责这套加载。这意味着你可以给一个项目写一份” 这个项目的特殊约定”,opencode 会自动遵守。
权限系统
权限是 opencode 在我眼里最值得抄的设计点。
每个工具的每次调用对应一条规则,规则解析成三个动作之一:
allow— 直接放行ask— 弹窗问你deny— 直接拒绝
配置长这样:
1 | { |
"*" 是兜底粒度。bash 这种” 通常要问、但 git status 这种无害” 的操作可以单独开 allow。edit 这种” 在我这个项目里绝对不能让 agent 改” 的操作直接 deny。
更细的粒度走对象语法。bash 工具的入参是命令行,可以按命令前缀匹配:
1 | { |
--auto 模式是个全局开关。开了之后所有没显式 deny 的请求都自动放行:
1 | opencode --auto |
TUI 里有命令面板可以切换。auto 模式下输入框旁边会显示一个 muted 的 auto 标记。
这条设计的妙处在于它跟 Plan/Build agent 的权限分层是独立的两层:Plan agent 默认就是只读 + ask,你可以在 Plan agent 上完全不设 deny,靠它自己的默认行为;Build agent 上可以设严格 deny,靠权限规则。两条线不冲突。
v1.1.1 起老的 tools boolean 配置被合并到 permission,老的 tools 配置还能用,向后兼容。
工具集合
packages/core/src/tool/ 列出所有内置工具。从文件名看涵盖:
- bash(执行 shell 命令)
- read /write/edit(文件操作)
- glob /grep/ls(搜索)
- webfetch(拉 URL)
- task(子 agent 调度)
- todos(任务列表管理)
- patch(应用 diff)
- skill(激活技能)
- 以及 mcp 注入的外部工具
bash 工具支持管道、重定向、后台任务,配合 experimental.bash 配置可以开更多权限。
七、快速上手
装法有十来种,README 列得很全。最少命令的是这一行:
1 | curl -fsSL https://opencode.ai/install | bash |
包管理器:
1 | npm i -g opencode-ai@latest # npm |
装完执行 opencode 起 TUI。第一次会问你要不要 /connect 配一个 provider,填完 API key,存在 ~/.local/share/opencode/auth.json。
第一次会话长什么样
跑 opencode 之后 TUI 起来,左边是空会话列表,右边是欢迎页。/connect 配好 provider 之后按 i 进输入模式,写第一句 prompt。
以一个真实的项目举例。假设你在 ~/projects/foo(一个用 Effect 写的 TypeScript HTTP API),你想加个 POST /v2/users 端点。输入框里写:
1 | 帮我在 ~/projects/foo 加个 POST /v2/users 端点,请求体是 { email, name, password }, |
Build agent 接到任务,大概按这个顺序动:
- 读项目结构。
read工具读package.json、tsconfig.json,搞清楚是单包还是 monorepo。 - 看现有路由。
grep工具找app.post、router.post、effect.gen这些模式,找到现有POST /v1/users的实现作为模板。 - 查类型。LSP 查
User类型、UserRepository接口、bcrypt模块签名。 - 写代码。在合适的位置新增
users-v2.ts、在app.ts里挂路由、跑tsc --noEmit检查。 - 写单测。按 ponytail 那条” 一个 runnable check” 原则,加一个
users-v2.test.ts,覆盖 happy path 和一个 email 重复的 negative case。 - 跑测试。
bash工具跑bun test,看输出。 - 报告。
git diff显示改了 3 个文件、新增 1 个。
过程中你会被问至少一次:要不要 git add 和 git commit。这是 permission 系统在工作。中途如果你想切到 Plan 模式看看其他方案,按 Tab。
整个流程在 Haiku 4.5 上大概 2-3 分钟,Sonnet 上 1-2 分钟。Opus 上更准但慢一倍。
opencode run 是非交互模式,类似 codex -p 那种批量跑:
1 | opencode run "在 ~/projects/foo 加个 POST /v2/users 端点,请求体是 ..." |
适合 CI 集成或者定时任务。--auto 配合可以把权限弹窗也省了,agent 自己决定要不要 git add,但 permission 里的 deny 规则还是生效。
桌面临床装:
1 | brew install --cask opencode-desktop |
装完跟 TUI 是同一份会话状态。
install 脚本尊重的路径优先级:
$OPENCODE_INSTALL_DIR(你指定的)$XDG_BIN_DIR(XDG 规范)$HOME/bin(标准用户 bin)$HOME/.opencode/bin(兜底)
1 | OPENCODE_INSTALL_DIR=/usr/local/bin curl -fsSL https://opencode.ai/install | bash |
一个提醒:如果你之前装过 0.1.x 之前的版本,先删干净。0.1.x 是一次重写,目录结构变了。
最小项目配置 opencode.jsonc:
1 | { |
加 MCP:
1 | { |
装完跑 opencode 进 TUI,按 ? 看键位绑定。Tab 切 Build/Plan,@explore 派搜索子 agent,/help 看命令列表。
八、对比:和 Claude Code、Codex 怎么选
这个我没法替你选,但我可以说我怎么用的。
Claude Code 我留在主力位。原因是它的子 agent 编排(Explore、Plan、general-purpose)和 hooks 系统现在最成熟,社区里出的 skills 和 plugins 多到可以按需挑。ponytail 这种项目就是先把 Claude Code 当宿主做的(虽然支持 20 个)。闭源和账号绑定是代价,但我还没遇到它在某个任务上完全做不了。
Codex CLI 我装在云开发机上。它跟 GitHub Action 集成最顺,PR 自动化 review 的体验是三者里最完整的。模型选 GPT 系列的最新款跑批量任务便宜。
opencode 我装在两类地方。一类是 homelab 上的小服务器,跑 headless 模式当 HTTP API 给自己其他项目用。一类是临时需要换主题、换 TUI 布局、试新模型组合的时候,本地开一个 TUI 玩。
如果你在意三件事里的一件,opencode 值得先试:
- 完全开源。MIT 协议,server 和 client 都开源,可以自己 fork 改。
- 多客户端共享服务端。TUI、桌面、Web 控制台、SDK 接 HTTP 后端,同一会话跨设备跟。
- 服务端 / 客户端分离的部署模型。把 opencode 跑在一台机器上,从另一台机器的 IDE 里连过去;或者把它的能力接进你自己的产品。
如果以下三件里有任何一件对你成立,Claude Code 仍然是当下最稳的选择:
- 你依赖 Claude Code 生态里那些现成的 skills、plugins、commands(mattpocock、affaan-m、ponytail 这一档)。
- 你的工作流需要 subagent 调度层之上的复杂编排(multiple subagents + skills + hooks 一起工作)。
- 你不需要部署灵活性,只想要” 装上就能用”。
Codex CLI 适合”PR review / CI 集成” 这条线,跟 GitHub 绑得最紧,模型永远最新。
生态温度 是个不显眼但值得看的指标。opencode 仓库里有 5,739 个 open issues。三个月前的 ponytail 仓库是 219 个。在 AI 编码 Agent 这个品类里,issue 数量高不等于失控,等于” 用户基数大 + 维护节奏紧”。opencode 的 dev 分支最近 24 小时有 push,PR 合并节奏是日级,对一个 30+ 包的 monorepo 来说,维护压力不小,但它顶住了。
九、总结
适合谁
希望服务端和客户端分离部署的人。 把 opencode 跑在 NAS / 云开发机 /homelab 上,从笔记本、桌面、IDE 任何地方连过去。
希望 fork 改自己的人。 MIT 协议,30+ 包结构清晰,加一个新的 client(VS Code 插件、JetBrains 插件、Slack 机器人)有明确的路径。
需要把 AI 编码 Agent 当产品后端的人。 SDK 从 server 自动生成,HTTP API 覆盖所有功能,Python SDK 在路上。
已经在用 Vercel AI SDK 的人。 模型适配、stream、tool call 这一层不用再写一遍。
想用 Plan 模式做” 只读代码调研” 的人。 opencode 把 Plan 做成一个独立主 agent,配单独的权限、模型、提示词,比” 在同一个 agent 上加个权限开关” 清晰。
不适合谁
不愿意自己装 LLM 凭据的人。 opencode 不托管任何模型调用,你得自己有 Anthropic / OpenAI / Google 之类的账号。
期待” 装上就有完整插件市场” 的人。 它的插件生态是有的,但远没到 Claude Code 那种” 挑 skills 挑花眼” 的程度。多数场景下你需要自己写或者 fork。
对终端 UI 有洁癖的人。 仓库根目录的 README 没截图。docs 站有截图。装起来你自己看吧。
局限
dev 分支是工作分支。README 提示主分支用 dev,发布版本用 npx opencode-ai@latest。这意味着你 clone 下来的 dev 分支可能有时比 npm 上的稳定版要激进一档。生产用跟着 npm 版本走。
Bun 优先。bun dev 是项目的开发约定,AGENTS.md 里写了。Node.js 也能跑(script/build-node.ts 打了 Node 二进制),但 Effect 框架和 monorepo 工作流很多 Bun 特性。Bun 在 macOS 和 Linux 上稳定,Windows 上需要 WSL。
5,739 个 open issues 不是失修信号,是项目热度。但你提一个 issue 等回复的延迟会比小项目长。
桌面应用还标 BETA。日常用 TUI 更稳。
Eclipse Public License 的子依赖。部分 Effect 生态的子包使用这种许可,跟 MIT 主协议不冲突,但做商业分发的时候要扫一遍合规。
安全模型依赖 provider。opencode 把” 代码安全” 这一关很大程度外包给了 model provider。permission 系统防的是 bash 误操作和文件越界,防不住模型被 prompt injection 诱导去删数据库。要企业级审计日志和细粒度操作回放,得自己接 packages/identity 和 packages/stats 的事件流,或者干脆加一层 wrapper 调 SDK。
Token 上下文管理是个统一痛点。 opencode 在长会话里也会丢上下文。compaction 配置可以开自动压缩,但开启后的体验是” 模型突然忘了五分钟前我们刚讨论过的命名约定”。这个跟 Claude Code、Codex 一样,谁都没真正解决。
SWE-bench 这种” 修真实 GitHub issue” 的能力不是它的卖点。 如果你要” 把一个 200 行的 patch 提给上游 repo”,用 SWE-agent、SWE-bench 里的专门模型或者 Codex 的 GitHub Action 集成会更稳。opencode 的优势在交互式编辑,不在批量自动化。
多仓库 monorepo 协作 没特别处理。它一次会话盯着一个工作目录。你要在 10 个 repo 之间协调,得手动切目录或者起多个 server。
十、它解决不了的问题
写到这里我得停一下说清楚” 它解决不了什么”。
Token 上下文管理是个统一痛点。 opencode 在长会话里也会丢上下文。compaction 配置可以开自动压缩,但开启后的体验是” 模型突然忘了五分钟前我们刚讨论过的命名约定”。这个跟 Claude Code、Codex 一样,谁都没真正解决。
SWE-bench 这种” 修真实 GitHub issue” 的能力不是它的卖点。 如果你要” 把一个 200 行的 patch 提给上游 repo”,用 SWE-agent、SWE-bench 里的专门模型或者 Codex 的 GitHub Action 集成会更稳。opencode 的优势在交互式编辑,不在批量自动化。
多仓库 monorepo 协作 没特别处理。它一次会话盯着一个工作目录。你要在 10 个 repo 之间协调,得手动切目录或者起多个 server。
没有” 工作流模板” 层。 Claude Code 有 subagent + skill + command + hook 这套组合,可以把”PR review 流” 打包成一个 team-level 工具。opencode 的 plugin + command + skill 也能做类似事,但 30+ 包的结构让” 做一个新插件” 的认知成本高。
不支持的 LLM 提供商还是有的。 比如智谱 BigModel、阿里 Qwen 的某些 endpoint、字节豆包的 SDK API,AI SDK 还在补。如果你必须用某个特定厂商且 opencode 没列出来,可以自己写 provider adapter,但那是 v0 的工程量。
十一、一段代码看懂架构
最后留一段 TypeScript 看 opencode 的内部结构长什么样。packages/core/src/config/agent.ts 的核心模式是 Effect 框架的 Service + Layer 模式:
1 | export interface Interface { |
消费方这么用:
1 | import { Agent } from "@/config/agent" |
这是 Effect 框架的标准模式:把” 实现” 和” 接口” 分离,通过 Layer 注入。模块的命名空间投影(Agent.layer)让消费方可以静态分析依赖。
如果你打算 fork opencode 改点什么,先把 Effect 这套搞懂是第一步。AGENTS.md 里专门有一节”opencode Effect rules” 讲迁移注意事项。
十二、跟生态的关系:什么在 opencode 之上,什么在 opencode 之外
写到最后想聊一下 opencode 跟整个 AI 编码 Agent 生态的相对位置。
之上的层:skills、plugins、commands。 ponytail 这种项目明确把 opencode 列为支持的宿主之一(20 个之一)。装 ponytail + opencode 的组合,等于让 opencode 跑起来” 不写过度代码” 的纪律。Skills 生态是 opencode 跟 Claude Code 拉平差距最关键的一层,目前差距还在但正在缩小。
之下的层:模型 provider、工具调用协议。 Vercel AI SDK 在这一层。Models.dev 在这一层。MCP 在这一层。opencode 不重做这些,直接接。这是个聪明的选择:把开放标准当成基础设施,自己专注做产品层。
平行的层:Claude Code、Codex、Gemini CLI、Aider。 它们的差别越来越不在” 能不能做” 上,而在” 做的成本” 和” 部署形态” 上。opencode 的成本是”MIT 协议 + 30+ 包 monorepo 的认知负担”,收益是” 可以本地自托管 + 多客户端 + SDK 接第三方”。
之下的层但不太对劲的:subagent 编排。 Claude Code 的 subagent + skill + command + hook 组合是把” 团队工程实践” 固化成可重用工具的成熟路径。opencode 的 agent 抽象很扎实(Build/Plan + General/Explore/Scout),但要追到 Claude Code 那种”subagent 嵌套 subagent + 跨 agent skill 共享” 的成熟度,还需要时间。
我个人判断,2026 年下半年到 2027 年上半年,AI 编码 Agent 这条线会收敛到三家左右:Claude Code(商业 + 生态最厚)、Codex(OpenAI 官方 + GitHub 集成)、opencode(开源 + 部署最灵活)。其他各家要么被并入这三家,要么变成这三家之一的前端。Cursor 是个变量,它有自己的 IDE 资产。Copilot 是个变量,它绑在 GitHub 上。
对正在选工具的人:如果你不确定,先用 Claude Code。生态最厚,出了问题最容易找到答案。如果你已经在用 opencode 并且喜欢,留着。它解决的那一类需求是真需求。
十三、调试和排错的几条经验
这一节写给已经决定试一下 opencode 的人。
TUI 卡死。 八成是 LSP server 启动卡了。开新会话前先 opencode --print-logs 跑一次看 log。packages/opencode/AGENTS.md 里写了 TUI 开发用 tmux new-session -d -s opencode-dev 'bun dev',tmux capture-pane -pt opencode-dev 抓输出。
Provider 报错。 /connect 配过的 key 存在 ~/.local/share/opencode/auth.json,编辑这个文件可以手动改 key。OPENCODE_LOG=debug 环境变量打开 debug log,会打印 Vercel AI SDK 的实际请求和响应。
Server 端口冲突。 默认 4096。如果 4096 被占了,加 --port 显式指定。CORS 加 --cors flag,多次指定多个 origin。
Permission 一直弹。 看一下 opencode.json 的 permission 段,最常见的坑是 bash 默认 ask,但你 git status 一天要跑几十次。改成 bash: { "*": "ask", "git status": "allow" } 这种前缀匹配。
模型选择被默认走了贵的那个。 检查 provider 段里有没有设默认 model。Models.dev 拉来的数据里每个 provider 通常标了一个”best price-performance” 模型,但 opencode 默认用的是 model ID 字典序排第一的那个。
MCP server 装上不工作。 检查 mcp 段配置,stdio 类型要 command 加 args,SSE 类型要 url。先在 terminal 里手动跑一下 command 看能不能起来。MCP server 失败的时候 opencode 通常会打 log 但不弹错,因为工具集合是 lazy 加载的。
会话中途上下文爆炸。 三个办法:开 compaction 配置自动压缩;用 /summarize 命令手动触发;开新会话把上下文重新整理一次。AI 编码 Agent 长会话的硬限制是 context window,opencode 没绕过这件事。
项目地址:https://github.com/anomalyco/opencode
模型选择没有默认优化。Vercel AI SDK + Models.dev 是通用层,不会针对某个具体模型调教 prompt。如果你是 Claude 重度用户,可能会觉得” 它也能用 Claude,但跟 Claude Code 调教过的 prompt 比差点意思”。这是所有通用 agent 的通病,不是 opencode 的问题。
最后回到开头那个场景。我现在三件并排装在 dock 上,但每一件的用途我都能说清楚:Claude Code 主力 + 生态最厚,Codex 跑 GitHub Action 自动化,opencode 跑在 server 上当 HTTP 后端,被我自己写的几个内部小工具调。
opencode 不是” 又一个 AI 编码 Agent”。它是” 我想把 AI 编码 Agent 当基础设施用” 这个需求的具体回答。
如果你的需求是前一种,它不是你的菜。
如果你的需求是后一种,204.7k stars 不是白来的。