OpenCode 2 架构解读:一个后台服务管所有会话

OpenCode 2 把架构整个翻了一遍:本机只跑一个共享的后台服务,终端、桌面端、网页和脚本都连它;发消息变成先写进会话「收件箱」;MCP 工具默认通过 Code Mode 调用。对同时开好几个 Agent 会话的人来说,这些改动直接关系到内存占用、断线后会不会丢消息,以及工具清单会吃掉多少上下文。本文根据官方 v2 文档和仓库里的设计规范整理,未实测。
一个后台服务,替代一会话一进程
按 v2 文档的说法,OpenCode 默认会为你的用户账号发现或启动一个共享后台服务,所有本地客户端都连到它,由它负责会话、配置、集成、权限和工具执行。开 5 个会话,背后还是这一个服务。
很多 CLI 编码工具的做法是每开一个终端会话就起一个独立进程,会话多了,内存和 MCP 子进程会跟着翻倍。共享服务把这部分开销收拢到一处,客户端只负责显示。
不想共享也可以:
opencode --standalone # 本次用私有服务
opencode --server http://localhost:4096 # 连指定服务
opencode service set disabled true # 默认不用共享服务
opencode pair # 生成一次性链接,在浏览器里打开网页端
官方文档写明,pair 生成的链接只能用一次,5 分钟后过期,而且必须开着共享服务。
steer 和 queue:运行中插话的两种方式
Agent 跑着的时候你想补一句,以前的选择只有打断重来或干等。v2 的设计规范里,每条输入先作为一条持久记录写进会话收件箱,再决定什么时候交给模型:
| 模式 | 默认快捷键 | 何时送达 | 适合 |
|---|---|---|---|
| steer(默认) | Enter | 当前这一轮的下一个安全步骤边界 | 纠偏:「别改那个文件」「用 pnpm」 |
| queue | Ctrl+X 再按回车 | 会话空闲后,一次送达一条 | 下一个独立任务 |
快捷键按官方仓库 issue 里的说明,可能随版本调整。送达之前,待处理的消息可以在两种模式之间切换,也可以删掉。规范还写明:同一个输入 ID 重复提交是幂等的,以第一次为准。网络抖动导致客户端重试,不会让 Agent 收到两遍同样的指令。
steer 用来调整正在做的事,queue 用来排下一件事,分开之后,压缩上下文时任务状态也不容易乱。
断线重连:按序号补事件
v2 给会话里会改变存储状态的事件编了持久序号(durable.seq)。客户端记住最后收到的序号,重连时带上 after,服务端把之后的持久事件补发过来,再接着推实时事件。
for await (const e of client.sessions.events({ sessionID, after: lastSeq })) {
if (e.durable) lastSeq = e.durable.seq
}
有个细节要注意:逐字输出的文本、推理增量这类「实时增量」不进回放。重连时可能看不到半截文字,只能等到这一段结束时那条完整的持久事件。官方的建议是图形界面重连后丢掉本地状态,重新拉一次权威状态;做集成的话就持久化序号,并让外部副作用幂等。另外,实例级的全局事件订阅只推实时事件,不回放,也不会自动重连。
Code Mode:工具调用改由一段 JS 完成
v2 文档里,execute 工具在 Code Mode 下运行 JavaScript,Agent 可以在一段代码里组合调用多个工具,中间结果不必都塞进模型上下文,适合并行的独立调用和对结果做二次处理。这个运行时不能直接访问文件系统,也不能 import 或用定时器,只提供 fetch,其余操作都要通过它目录里的工具。
MCP 服务器默认就走这条路:工具按服务器名归到命名空间下,例如 tools.context_7.resolve_library_id(...)。某个服务器的工具必须直接出现在模型原生工具列表里时,单独关掉:
{
"mcp": {
"servers": {
"context7": {
"type": "remote",
"url": "https://mcp.context7.com/mcp",
"codemode": false
}
}
}
}
这样接了十几个 MCP 服务器,提示词里不必列出几百个工具定义。至于 v2 把工具清单压到具体多少 token、Code Mode 用的是哪种 JS 解释器,官方文档里没有找到明确数字,这里不下结论。读、改文件和 shell 这些内置主力工具,文档里仍是直接调用的独立工具。
后台任务:子代理和 shell 都能放后台
v2 的 shell 工具设 background: true 后会立刻返回,跑完再通知会话,适合起开发服务器;subagent 也可以后台运行,子会话结束时通知父会话,默认嵌套深度为一层。API 里还有 POST /api/session/{sessionID}/background,可以把正在前台跑的工具挪到后台。
升级前要注意的坑
- 旧版本管理器装到的还是 1.x:官方文档写明 mise 需要 2026.10.9 或更新的版本,旧版装的是 OpenCode 1;GitHub Releases 页面目前的正式版本号也还在 1.19.x,以官方安装文档为准。
- 权限一刀切会连带误伤:对
execute设 deny,会把 Code Mode 和只能通过它访问的 MCP 工具一起禁掉。 - 依赖实时流的集成:全局事件流没有回放,要可靠就改用会话级的带序号事件。
之前我们写过 用 Python 写 MCP 服务器并接进 OpenCode,升级到 v2 后要留意 Code Mode 的默认行为;安全方面可以回顾 OpenCode Console 密钥泄露事件。
最后
如果你同时开着好几个 Agent 会话、电脑内存吃紧,可以先试共享后台服务;先用 opencode --standalone 和默认模式各跑一天对比一下。