opencode 是什么:终端里的开源 AI 编程 Agent 全景地图
本文基于 opencode 仓库 commit 7fe9938(2026-08-04)梳理,该项目仍在高频迭代,具体行为以仓库 https://github.com/anomalyco/opencode 最新代码与文档为准。
opencode 最值得先记住的一件事:它不是一个「终端里的聊天框」,而是一个自带 HTTP 服务端的本地进程,你在终端里看到的界面只是它的第一个客户端。 想明白这一点,它后面那些设计——桌面端、编辑器插件、SDK、可编程调用——就都是同一个东西的不同外壳,而不是零散功能的堆砌。
先做个命名上的澄清:opencode 是这个开源项目的名字,首字母小写,仓库在 anomalyco/opencode,采用 MIT 许可证(LICENSE 文件里写的是 Copyright 2025 opencode)。本文里凡是写「opencode」的地方都指这个项目,不是泛指「开源的代码」,也不是别的名字相近的模型或工具。
站内已经有几篇相邻的文章,分工不同:AI 编程工具横评是站在选型角度对比多家产品,开源 AI 工具盘点是把开源生态铺开看一遍,Agent 框架对比讲的是搭 Agent 时的框架取舍;这一篇不做横向排名,只把 opencode 这一个仓库拆开,告诉你它内部分了哪几块、每块解决什么问题、哪些事它明确不管。它也是本系列的入口。
一、它的形态:一个进程,两个角色
装完之后你敲的命令就一个词:opencode。README 里给的安装方式很多,最简单的是安装脚本:
curl -fsSL https://opencode.ai/install | bash
npm 包名是 opencode-ai,另外还有 Homebrew、Scoop、Chocolatey、pacman、AUR、mise、Nix 等渠道,也提供了独立的桌面应用(处于 BETA)。安装脚本落盘位置按 $OPENCODE_INSTALL_DIR、$XDG_BIN_DIR、$HOME/bin、$HOME/.opencode/bin 的优先级依次判断,如果你有多套二进制来源,这个顺序值得先看一眼。
真正有意思的是运行形态。文档里写得很直接:你运行 opencode 时,它会同时启动一个 TUI 和一个服务端,TUI 是那个跟服务端说话的客户端。服务端暴露的是 OpenAPI 3.1 规范端点,SDK 就是从这份规范生成的。你也可以只要服务端,不要界面:
opencode serve [--port <number>] [--hostname <string>] [--cors <origin>]
默认监听 127.0.0.1:4096。想加一层保护,设置 OPENCODE_SERVER_PASSWORD 就会启用 HTTP 基本认证,用户名默认是 opencode,可以用 OPENCODE_SERVER_USERNAME 覆盖。
这个「客户端/服务端分离」的取向决定了它的接入方式不止一种:终端 TUI 是一种,桌面应用是一种,编辑器侧通过 Agent Client Protocol 接入是一种(配置编辑器去跑 opencode acp,它会作为子进程用 stdio 上的 JSON-RPC 跟编辑器通信),直接调 HTTP 接口把它当服务用也是一种。对你的意义是:如果你打算把编码 Agent 编排进自己的流水线,而不只是坐在终端前面聊天,它留了正经的接口面,不用去逆向界面。
二、它把「写代码」拆成了哪几块
仓库是个 monorepo,packages/ 下有 32 个包。不用全看,按职责挑几块看就够了。
| 组成部分 | 它负责什么 | 对应仓库位置 | 你什么时候会碰到它 |
|---|---|---|---|
| 终端界面 | 你实际敲字、看输出、按 Tab 切 Agent 的地方,包名 @opencode-ai/tui | packages/tui/ | 每天用;改主题、改键位时 |
| 主程序与会话运行时 | 会话的推进、模型调用、工具调度都在这里 | packages/opencode/src/session/ | 排查「它为什么没继续干」时 |
| 工具层 | Agent 能对你机器做的所有动作的实现 | packages/opencode/src/tool/(25 个 .ts 与 15 个 .txt) | 想知道某个工具到底怎么执行时 |
| 提示词 | 按模型/模式分开维护的系统提示词文本 | packages/opencode/src/session/prompt/(14 份 .txt) | 想看清它给模型下了什么指令时 |
| 权限层 | 判定某次工具调用是直接跑、先问你、还是拒绝 | packages/opencode/src/permission/、packages/core/src/permission.ts | 第一次被弹窗打断时 |
| 服务端与协议 | HTTP 接口、路由、事件流的契约 | packages/server/、packages/protocol/ | 要编程调用它时 |
| 客户端与 SDK | 从公共接口生成的调用库 | packages/client/、packages/sdk/、packages/sdk-next/ | 要把它嵌进自己程序时 |
| 桌面端 | 非终端形态的外壳 | packages/desktop/ | 不想活在终端里时 |
| 文档站 | 官方文档源文件 | packages/web/src/content/docs/(36 份英文 .mdx) | 查配置项时(比翻博客快) |
顺带一个能说明这个项目气质的细节:根目录有 21 份 README 翻译(简体、繁体、韩、德、西、法、意、丹、日、波兰、俄、波斯尼亚、阿拉伯、挪威、巴葡、泰、土、乌克兰、孟加拉、希腊、越南),全仓受版本控制的文件有 6358 个。它不是一个几百行的玩具脚本,是一套有工程约束的代码库。
工具层那 25 个 .ts 里,你日常真正会感知到的是文档《Tools》一节列出的这批内置工具:bash、edit、write、read、grep、glob、apply_patch、skill、todowrite、webfetch、websearch、question,外加一个实验性的 lsp。有两个实现细节值得知道:grep 和 glob 底层用的是 ripgrep,默认尊重 .gitignore,所以被忽略的目录它默认搜不到——需要放行时在项目根建一个 .ignore 文件显式允许;websearch 只有在使用 opencode 自家 provider 或设置了 OPENCODE_ENABLE_EXA 环境变量时才可用,它连的是 Exa AI 的托管 MCP 服务。lsp 工具需要 OPENCODE_EXPERIMENTAL_LSP_TOOL=true(或 OPENCODE_EXPERIMENTAL=true)才出现。
Agent 这一层分两类。主 Agent 是你直接对话的对象,用 Tab 键循环切换,内置两个:build 是默认的全权限开发 Agent,plan 是受限的分析规划 Agent,默认把文件改动和 bash 命令都设成先问你。子 Agent 由主 Agent 调起,也可以用 @ 提及手动召唤,内置三个:general(多步任务与复杂检索)、explore(只读,快速摸代码库)、scout(只读,看外部依赖与上游实现)。另外还有三个隐藏的系统 Agent:compaction 负责把长上下文压成摘要,title 生成会话标题,summary 生成会话摘要,都自动运行、界面里选不到。
自定义 Agent 有两种写法:写进 opencode.json 的 agent 字段,或者在 ~/.config/opencode/agents/ 与 .opencode/agents/ 下放 Markdown 文件(文件名即 Agent 名,frontmatter 里写 description、mode、model、permission 等)。不想手写就跑 opencode agent create,它会交互式问你存哪、干什么、给哪些权限,然后生成文件——注意它的默认取向是「你没勾选的一律拒绝」。
三、上下文这块,它专门立了一套词汇
opencode 仓库根目录有一份 CONTEXT.md,专门给会话运行时定义术语,而且明确写了哪些说法要避免——比如它把喂给模型的那组结构化事实叫 System Context,并注明「避免叫 system prompt」;把某一次实际选进请求的对话叫 Session History,注明「避免叫 session context」。
这不是命名洁癖。它背后是一个具体的机制:每一条独立可观测的上下文事实是一个 Context Source,有稳定的 key、编解码器、加载器和渲染器;一个 Context Epoch 开始时渲染出的那份完整上下文叫 Baseline System Context,它在这个 Epoch 内原样保留、跨进程重启也照旧复用,因为这段前缀要拿去命中服务商的缓存;当某个 Context Source 的值变了(比如日期变了、可用技能变了、项目指令文件变了),它不会去改那段基线,而是在下一个安全的模型调用边界上追加一条时间线上的系统消息,告诉模型「这项现在的有效值是什么」。按 CONTEXT.md 的定义,一个 Epoch 在压缩(compaction)完成、会话发生迁移、或者出现无法沿用旧基线的上下文切换时才结束,届时重渲一份新的基线。
对你的意义有三点。第一,会话跑很久之后它的上下文不是被反复重写的一锅粥,而是一条可审计的时间线,出问题时能往回追。第二,它明确写了「上下文变化绝不会唤醒空闲会话」,都是在下一次自然的模型调用前懒加载比较——所以你改了 AGENTS.md 不会立刻生效,得等下一轮。第三,项目指令的加载路径是全局与逐级向上的 AGENTS.md 聚合成一个有序整体;如果你设了 OPENCODE_DISABLE_PROJECT_CONFIG,项目侧指令会被跳过,全局的仍然生效。
工具输出也走同一套克制:Core 执行完工具后,进入会话历史和回放给模型的是一份有界的投影,超限部分被截断(保留头尾),完整文本落到一个临时的托管输出文件里,模型看到的预览里会带上那个文件路径。也就是说,模型看到的从来不是你磁盘上的原始输出全文——排查「它为什么漏了日志里那一行」的时候,这是第一个要想到的原因。
项目指令用 AGENTS.md,在 TUI 里跑 /init 可以生成或就地改进这个文件;它会扫仓库里的重要文件,必要时反问你几个问题,产出构建/测试命令、目录结构、项目约定这类后续会话最需要的信息。技能则是 SKILL.md,按目录约定发现:.opencode/skills/<name>/SKILL.md、~/.config/opencode/skills/<name>/SKILL.md,以及兼容 .claude/skills/ 和 .agents/skills/ 的同名布局。这里有个容易忽略的点:注入上下文的只有技能的名称和描述,正文只有在通过受权限检查的 skill 工具加载时才会进来。
四、权限:它默认很松,这是你上手第一天要动的地方
这一节请当成安全提示读,别跳。
opencode 的权限用一套配置解决,每条规则解析成三种结果之一:allow(直接跑)、ask(问你)、deny(拦掉)。可配的键按工具名走,包括 read、edit(覆盖 edit、write、apply_patch 三个改文件的工具)、glob、grep、bash、task、skill、lsp、question、webfetch、websearch,另外两个是安全护栏:external_directory(工具碰到项目工作目录之外的路径时触发)和 doom_loop(同一个工具调用带着完全相同的输入重复三次时触发)。
默认值是:大部分权限默认 allow;doom_loop 和 external_directory 默认 ask;read 默认允许,但 .env 类文件默认被拒——文档里给出的默认形态是这样:
{
"permission": {
"read": {
"*": "allow",
"*.env": "deny",
"*.env.*": "deny",
"*.env.example": "allow"
}
}
}
把这句翻译成人话:开箱即用的状态下,它可以在你的机器上直接跑 shell 命令、直接改你的文件,不用问你。 这是效率取向的选择,代价你必须自己认领。要收紧就用对象语法按模式匹配,规则最后一条命中的生效,所以通配的 "*" 要放最前面:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"npm *": "allow",
"rm *": "deny",
"grep *": "allow"
},
"edit": {
"*": "deny",
"packages/web/src/content/docs/*.mdx": "allow"
}
}
}
反方向也有:--auto 启动会自动批准所有「本该问你」的请求,显式的 deny 仍然强制生效。opencode run --auto "..." 同理。这个开关在无人值守脚本里很好用,在你自己那台装着生产密钥的机器上就不太好用。关于权限放太松之后具体会以什么形式出事,展开可以看权限给太大之后会发生什么。
五、边界与代价:它放弃了什么,什么时候别用它
任何设计都有账要还,opencode 这几笔账写在明面上。
它默认信任你的工作目录。 权限模型是围绕「当前工作目录」建起来的,目录外的访问要靠 external_directory 显式放行。反过来说,目录之内的东西,默认就在它的作用面内。如果你的仓库里躺着未加密的凭证、客户数据、还没脱敏的样本,那它们随时可能被读进上下文再发给模型服务商。这不是 bug,是这个设计的必然结果。
它会真的改你的文件。 edit、write、apply_patch 三个工具都归 edit 权限管,默认允许。TUI 里有 /undo 和 /redo,可以多次回退,但这是它自己的撤销栈,不等于版本控制的安全网。在一个没提交、没 stash 的工作区里放手让它干,出事的时候你能追回什么,取决于你事前做了什么。
代码会离开你的机器。 只要它调模型,读到的文件内容就会进请求体。凭据存在 ~/.local/share/opencode/auth.json(用 /connect 添加)。模型侧的数据留存、训练使用、并发与配额规则各家不同且会调整,以官方最新说明为准——你要做的判断是:这个仓库允不允许出网。
分享功能是公开的。 /share 会给当前会话生成一个公开链接,把对话历史同步到项目方的服务器,任何拿到链接的人都能看。默认是手动模式(不会自动分享),但配置里可以改成 auto,也可以设成 disabled 把这个功能整个关掉——后者写进项目的 opencode.json 再提交进 Git,就是一个团队级的开关。在企业仓库里用之前,先确认这个开关的状态。
它明确不管的事。 它不是 CI,不替你保证测试通过;它不是代码审查系统,plan Agent 给的是分析和计划,不是审批结论;它不做部署编排;opencode serve 默认只监听回环地址,服务端文档给出的保护手段就是「设一个环境变量启用 HTTP 基本认证」这一层,组织级的集中配置、身份对接这些都不在这个命令的默认能力里——想把它开给别人用,认证、网络边界、访问记录都得你自己补。
插件、自定义工具和 MCP 是另一条要自己把关的进入路径。 文档明确写了自定义工具是在配置里定义、可以执行任意代码的函数,MCP 服务端则是把外部服务接进来的通道。这意味着装一个来源不明的插件或 MCP,等于给一个已经能读你仓库、能跑 shell 的进程再加一段你没审过的代码。要接之前先看它读什么、往哪发,别把「工具多」当成收益本身;websearch 连的 Exa AI 托管 MCP 服务也属于这一类外部依赖,只是它是内置的。
什么场景不适合。 你的日常主要是在 IDE 里做小范围补全和局部重构,那终端形态的收益不明显,装了大概率还是回去用编辑器内联补全;你所在的环境禁止代码出网且没有可用的自托管模型,那它的核心能力用不上;你要的是「一句话生成整个项目然后不看」,那任何这类工具都会让你在两周后付出更大的代价,这个判断跟具体工具无关。终端类 Agent 之间到底该怎么选,可以看终端 Agent 选型。
六、上手与避坑清单
每条都写清楚为什么会踩,以及怎么避。
一、先改权限,再干活。 为什么会踩:默认配置里 bash 和 edit 都是允许,第一次跑起来它可能已经改了一批文件、跑了几条命令,你才反应过来。怎么避:进项目第一件事是在 opencode.json 里把 bash 设成对象语法,"*": "ask" 打头,再逐条放行 git *、npm * 这类你确认无害的前缀,并把 rm * 显式 deny。记住最后命中的规则生效,通配符放最前面。
二、在干净的工作区里让它动手。 为什么会踩:它的 /undo 是会话级撤销,跟你的分支状态是两套东西;一旦中间夹了手动改动,回退边界就模糊了。怎么避:让它开工前先把工作区提交或暂存,改完先看 diff 再决定要不要留。
三、先 /init 再提问。 为什么会踩:没有 AGENTS.md 的仓库,它只能靠现场搜索猜你的构建命令和目录约定,问一次错一次。怎么避:跑 /init 生成一份,人工补上「跑测试的准确命令」「哪些目录不许动」,然后提交进 Git 让团队共享。改完之后别指望立刻生效——上下文是在下一次模型调用前才重新采样的。
四、复杂改动先切 plan。 为什么会踩:直接让它上手实现一个跨模块的需求,它会一边猜一边改,改到一半方向错了,回退成本很高。怎么避:按 Tab 切到 plan,让它先出方案,你改完方案再切回 build 执行。
五、别用一个 Agent 干所有事。 为什么会踩:探索型任务(找文件、读依赖)会塞进大量无关内容,把主会话的上下文撑爆,后面真正干活时反而记不住关键约束。怎么避:把只读的摸底工作交给 explore、把查上游依赖交给 scout,主会话只留结论。子会话之间可以用配置的键位在父子会话间来回切。
六、搜不到文件时先想 ripgrep 的忽略规则。 为什么会踩:grep、glob 默认尊重 .gitignore,你让它「看看 dist 里生成了什么」,它会一口咬定没有。怎么避:在项目根加 .ignore 显式放行需要检索的目录。
七、想编程调用就用服务端,别去套壳终端。 为什么会踩:拿脚本去解析 TUI 输出,界面一改你就全线崩。怎么避:起 opencode serve,走它的 HTTP 接口或生成的客户端;要嵌进编辑器就走 opencode acp。
八、准备给这个项目提 PR 的话,先读 AGENTS.md。 为什么会踩:它的仓库有几条不写在显眼处的硬约束——默认分支是 dev(本地可能压根没有 main 引用);测试不能从仓库根目录跑,有一道叫 do-not-run-tests-from-root 的守卫,得进到 packages/opencode 这类包目录里跑;类型检查要在包目录里用 bun typecheck,别直接敲 tsc。怎么避:动手前把根目录那份 AGENTS.md 从头读一遍,它连分支命名(最多三个词、连字符分隔、不带 feat/ 前缀)和提交信息格式都规定了。
收个尾
把 opencode 放回一句话:它是一个把编码 Agent 拆成「服务端 + 可替换客户端」的开源项目,工具层、权限层、上下文层各自有明确边界,默认配置偏向效率而不是保守,安全边界留给你自己划。
你可以拿这几条自检一下要不要投入时间:你的工作是不是经常需要跨文件、多步骤的改动(是的话终端形态才划算);你的仓库允不允许把代码内容发给模型服务商;你愿不愿意花半小时把权限配置写对,而不是一路点「同意」。三条都过了,再往下走。
接下来建议按这个顺序读仓库:先 packages/web/src/content/docs/permissions.mdx 把权限模型吃透,再 packages/web/src/content/docs/agents.mdx 搞清楚 Agent 与子 Agent 的分工,然后 packages/opencode/src/tool/ 挑几个你天天用的工具看实现,最后如果你在意它长会话为什么还稳,去读根目录的 CONTEXT.md——它把术语、边界条件和「什么时候不做什么」逐条写成了短句,比看代码更快对上它的心智模型。
这个系列的其余文章
这篇是总览。想往下挖,按下面两条线走:先把它用顺手,或者直接读代码。
上手与使用
- opencode 安装上手:开源终端编码 Agent 的装法与避坑
- opencode 怎么接模型:终端编码 Agent 的供应商层与认证机制
- 开源终端 Agent opencode 的两条模型接入路线怎么选
- 开源终端 Agent opencode 的配置从哪读,改错一处为何全变
- 终端编码 Agent opencode 命令行:交互模式与脚本化执行
- 开源终端 Agent opencode 界面用熟:键位、主题与区块含义
- 开源终端 Agent 项目 opencode 的多 agent 怎么配
- 终端 AI 编程 Agent opencode 的权限闸门怎么设
- opencode 读哪些规则文件:终端编码 Agent 的规则加载顺序
- 给 opencode 写自定义命令:把重复指令固化成一条斜杠命令
- 开源终端 Agent opencode 接 MCP:两类接法与认证避坑
- 终端编码 Agent opencode 的 skills 用法与分工
- 把开源编码 Agent opencode 挂到代码托管平台:权限与边界
- opencode 的诊断与格式化两条线:语言服务器怎么报错、格式化器何时跑
- 开源终端编码 Agent opencode 跑不动:按模型、认证、Windows、代理证书的顺序排查
结构与机制
- 终端 Agent 项目 opencode 仓库结构导读:32 个包里哪些是主干,改功能从哪进
- opencode 会话全流程:消息组织、单轮步骤与中断重试的落点
- opencode 上下文压缩拆解:压缩与溢出是两条线,压完之后你会丢什么
- opencode 为什么备了 14 份系统提示词:开源终端编码 Agent 的提示词分家现实
- opencode 工具层拆解:实现与描述分家,注册表决定模型看见什么
- 开源终端 Agent opencode 怎么改你的代码:覆盖、替换、打补丁三条路径的失手点
- 开源编码 Agent opencode 找代码三件套:读取、按名找、按内容找
- 开源项目 opencode 的 shell 工具:命令怎么解析、哪些会被权限层拦下
- opencode 怎么把活派给子 agent:task 工具与探索型子代理
- opencode 的 plan 模式在拦什么:模式切换本质是改工具可用面
- opencode 的 code mode 支线:让模型写程序串工具的代价
- 终端编码 Agent opencode 的语言服务器集成:拉起、诊断回灌与失效表现
- opencode 扩展指南:插件钩子与自定义工具,两条路怎么选
- 开源终端 Agent opencode:服务端、SDK 与会话分享
- 开源终端 Agent opencode 的 ACP 层拆解:重映射的代价
- opencode 怎么住进编辑器:扩展只是启动器,Agent 还在终端
- Agent 改坏了代码怎么退回去:opencode 的快照与回滚机制,和你自己 git commit 的边界
- opencode 会话数据存在哪:本地存储层与同步层是怎么拆开的
- 拆解终端编码 Agent opencode:事件清单如何撑起 TUI 与插件
- 开源项目 opencode 怎么把一个 Agent 内核挂上四五套界面
- 把开源终端 Agent opencode 铺给团队:策略层锁得住什么、锁不住什么
- 开源终端编码 Agent 项目 opencode 的安全边界:它明说不做沙箱,你该在外面补什么
- 开源终端编码 Agent opencode:什么时候别用它干活
- opencode 开源终端编码 Agent 拆解:服务端分离、双主智能体与权限规则
全部文章也汇总在 opencode 开源专题。另一个方向的开源项目——不做编码内核、专做能力分发与共享的那种——见 OpenWork 是什么:把技能与 MCP 打包成能力的开源桌面应用,它甚至把这个项目当引擎接了进去。