OpenCode 是什么
产品全貌:安装方式、七个内置 Agent 与各自的权限、从 TUI 到 ACP 的多种入口、不写死的模型提供方,以及与另外四本专栏的对照。
OpenCode 的 README 只有一句自我介绍:“The open source AI coding agent.”——开源的 AI 编码 Agent。这一篇先把它当成一个产品来看:怎么装、有哪些 Agent、从哪些入口用、模型从哪来。实现细节留给后面各篇。
开源与仓库
- 许可证是 MIT(根目录
LICENSE,根package.json的license字段)。 - 仓库已从
sst/opencode迁到anomalyco/opencode:README 的徽章、Homebrew tap(anomalyco/tap/opencode)和根package.json的repository字段都指向新地址。默认分支是dev(根AGENTS.md)。 - npm 包名是
opencode-ai,命令名是opencode。本专栏基准为v1.18.30。
安装
README 列了一长串安装方式,常用的是这几种:
curl -fsSL https://opencode.ai/install | bash # 官方安装脚本
npm i -g opencode-ai@latest # 或 bun / pnpm / yarn
brew install anomalyco/tap/opencode # macOS 与 Linux,更新最及时
scoop install opencode # Windows另有 choco、pacman / paru、mise、nix 等渠道。安装脚本按 $OPENCODE_INSTALL_DIR、$XDG_BIN_DIR、$HOME/bin、$HOME/.opencode/bin 的优先级选安装目录。
npm 装下来的 opencode 并不是程序本体。packages/opencode/bin/opencode 是一个 Node 小脚本:按操作系统与 CPU 架构拼出包名(形如 opencode-linux-x64,x64 还区分是否支持 AVX2 的 baseline 版,Linux 还区分 musl),在 node_modules 里找到对应的预编译二进制,spawn 它并转发 SIGINT、SIGTERM、SIGHUP。二进制由 packages/opencode/script/build.ts 调用 Bun.build 的 compile 选项生成——发行版是自带 Bun 运行时的独立可执行文件。
内置 Agent
README 说有两个可用 Tab 切换的主 Agent(build 与 plan),外加一个 general 子代理。packages/opencode/src/agent/agent.ts 里实际定义了七个:
| Agent | mode | 用途与权限要点 |
|---|---|---|
build | primary | 默认 Agent,按配置的权限执行工具;额外放开 question 与 plan_enter |
plan | primary | 计划模式:edit 一律 deny,只放行 .opencode/plans/*.md 与数据目录下的计划文件;禁止调用 general 子代理 |
general | subagent | 通用子代理,适合并行执行多个任务;禁用 todowrite |
explore | subagent | 只读探索:先 "*": "deny",再放行 grep、glob、list、bash、webfetch、websearch、read |
compaction、title、summary | primary(隐藏) | 分别负责上下文压缩、生成会话标题、生成摘要,工具全部 deny |
Tab 与 Shift+Tab 的绑定在 packages/tui/src/config/keybind.ts:130(agent_cycle 与 agent_cycle_reverse);子代理可以在消息里用 @general 这样的写法点名。
所有 Agent 先共享一套默认规则,再各自叠加(packages/opencode/src/agent/agent.ts:119):
const defaults = Permission.fromConfig({
"*": "allow",
doom_loop: "ask",
external_directory: {
"*": "ask",
...Object.fromEntries(whitelistedDirs.map((dir) => [dir, "allow"])),
},
question: "deny",
plan_enter: "deny",
plan_exit: "deny",
// mirrors github.com/github/gitignore Node.gitignore pattern for .env files
read: {
"*": "allow",
"*.env": "ask",
"*.env.*": "ask",
"*.env.example": "allow",
},
})兜底是 "*": "allow"——OpenCode 默认是放开的,危险面靠几处收口:同一工具连续三次以相同参数调用会触发 doom_loop 询问;访问工作区之外的目录要问(截断输出目录、临时目录、Skills 目录等白名单除外);读 .env 要问。用户配置里的 permission 与 agent 字段会在此之上合并(agent.ts:138、agent.ts:267):可以改内置 Agent 的模型、提示词、温度与步数上限,disable: true 能删掉一个内置 Agent,也能新增自定义 Agent。细节分别见权限系统与 Agent、命令与 Skills。
入口一览
packages/opencode/src/index.ts 用 yargs 注册了二十多个命令,与“怎么用它”直接相关的是这些:
| 入口 | 形态 |
|---|---|
opencode [project] | 默认命令:全屏 TUI,服务端跑在 Worker 线程里 |
opencode --mini | 精简的交互界面(split-footer 直出模式),服务端在进程内 |
opencode run [message..] | 非交互:发一条消息,把结果打到 stdout 后退出;--format json 输出原始事件 |
opencode serve | 无界面服务端,端口默认先试 4096 |
opencode web | 启动服务端并打开浏览器里的 Web 界面 |
opencode attach <url> | 用 TUI 连接一个已在运行的服务端 |
opencode acp | 作为 ACP(Agent Client Protocol)服务,经 stdin 与 stdout 接入编辑器 |
opencode github install、run | 安装、运行 GitHub agent |
opencode pr <number> | 拉取并检出 GitHub PR 分支,然后启动 opencode |
其余是管理类命令:mcp、providers、models、agent、session、export、import、stats、db、plugin、upgrade、uninstall、debug,以及把 OpenAPI 规格打到 stdout 的 generate(另有隐藏的 console,管账号登录与组织)。
命令行之外还有几种形态,复用同一套服务端 API:
- Web 界面:
opencode web起的服务端优先返回内嵌的 Web UI 资源,没有内嵌时把页面请求代理到https://app.opencode.ai(packages/opencode/src/server/shared/ui.ts)。界面代码在packages/app(SolidJS)。 - 桌面端:
packages/desktop是 Electron 应用,包装packages/app;主进程用utilityProcess.fork拉起本地服务端 sidecar(packages/desktop/src/main/server.ts)。 - VS Code 扩展:在仓库根的
sdks/vscode。 - GitHub Action:仓库根的
github/action.yml先用安装脚本装好 opencode,再执行opencode github run。 - Slack:
packages/slack,基于@slack/bolt与 SDK。
这些入口的启动差异见启动链路,ACP 与 GitHub 见 ACP、GitHub 与其他入口。
模型:不写死提供方
CONTRIBUTING 里有一句很能说明取向的话:
New providers shouldn't require many if ANY code changes, but if you want to add support for a new provider first make a PR to: https://github.com/anomalyco/models.dev
新增一家提供方,原则上不该改 OpenCode 的代码,而是去开放目录 models.dev 提 PR。客户端由 packages/core/src/models-dev.ts 取目录:
- 数据源默认是
https://models.opencode.ai(可用OPENCODE_MODELS_URL改),拉取其下的api.json; - 缓存为全局缓存目录里的
models.json,5 分钟内视为新鲜,后台每 60 分钟刷新一次; - 构建时还把一份目录快照编译进二进制(
OPENCODE_MODELS_DEV这个 define):读不到磁盘缓存就先用快照,两者都没有才联网拉取;OPENCODE_DISABLE_MODELS_FETCH可以关掉联网。
真正发请求默认交给 Vercel AI SDK:packages/opencode/package.json 直接依赖 ai 与近二十个 @ai-sdk/* 包(Anthropic、OpenAI、Google、Bedrock、Azure、Groq、Mistral、xAI 等),外加 OpenRouter、GitLab 等第三方 provider。各家差异由适配层抹平,自研的 packages/llm 则作为实验开关后的原生链路,见提供方目录与 models.dev、提供方适配层与模型调用层:AI SDK 与原生双轨。
和另外四本对照
- 相比《从 LLM 到 Coding Agent》的教学最小实现,OpenCode 多出的是“产品化”的那一圈:权限规则、多入口、提供方适配、会话持久化与事件同步。
- 《Kimi Code 源码解读》同为 TypeScript 生产实现,也经历了两代引擎(
agent-core与agent-core-v2),而且已经走完换代、删掉了 v1,正好对照两个团队怎么做迁移。 - 《MiMo Code 源码解读》拆的是小米从 OpenCode v1.14.19 分叉出来的 MiMo Code:底座相同,另加了检查点、分层记忆、Actor 子智能体与 Workflow 编排,正好看一个团队怎样在 OpenCode 之上做二次开发。
- 《Grok Build 源码解读》是 Rust 实现,适合对照同一类问题在另一种语言生态里的解法。
下一篇:Monorepo 全景——36 个 workspace 包各管什么,依赖怎么流,V1 与 V2 各住在哪里。