Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

章节: 第9章 — OpenCode的独特贡献 书名: Claude Code VS OpenCode: Architecture, Design and The Road Ahead 模型: openai/gpt-5.4 Token 用量: ~2,900 tokens 生成日期: 2026-04-01

9.2 ACP智能体客户端协议

OpenCode 对 ACP(Agent Client Protocol)的支持,是它最有战略意义的设计之一。packages/opencode/src/acp/ 目录下的 agent.tssession.tstypes.ts 清楚表明:OpenCode 不只是一个“用户手动运行的 agent”,它还是一个可以被外部客户端程序驱动的 agent runtime。这个差异很关键,因为它意味着 OpenCode 从“工具”走向了“平台能力”。

ACP 在 OpenCode 中依赖 @agentclientprotocol/sdk 实现。它的基本通信方式可以概括为:JSON-RPC over stdio。这里需要解释两个术语。JSON-RPC 是一种轻量的远程调用协议,通信双方使用 JSON 描述“我要调用什么方法、传什么参数、返回什么结果、出现什么错误”。stdio 则是 standard input / standard output,也就是标准输入输出流,是本地进程之间最简单、最稳定的通信管道。把两者放在一起,本质上就是:外部客户端启动 OpenCode 进程,然后通过结构化 JSON 消息和它通信。

这和 MCP 要分清。MCP(Model Context Protocol)解决的是“agent 如何访问工具和外部资源”的问题;ACP 解决的是“外部客户端如何驱动 agent 本身”的问题。前者是 agent-to-tool,后者是 client-to-agent。它们不是竞争关系,而是不同层级的协议。

acp/types.ts 定义了 ACP 会话最基础的状态结构:session ID、工作目录、挂载的 MCP servers、可选的 model 信息、variant 和 mode ID。acp/session.ts 则把这些状态封装进 ACPSessionManager,提供 create、load、get、setModel、setVariant、setMode 等能力。为什么这很重要?因为 IDE 集成从来不只是“把 prompt 发进去”这么简单。真正可用的 editor integration 必须能恢复会话、切换模型、保留工作目录上下文、同步模式状态。

真正复杂的部分在 acp/agent.ts。这里的 ACP.Agent 类负责承接协议侧连接、持有 OpenCode SDK、管理 ACP session、订阅全局事件、转译权限请求,并把状态更新回推给客户端。换句话说,ACP 在 OpenCode 里不是一个“很薄的适配器”,而是一个真正的中介层。它把 OpenCode 内部运行时和外部客户端的交互协议分开了。

这层设计有几个特别重要的点。第一,ACP 会监听 OpenCode 的事件流,并把使用量、会话进展、权限请求等信息同步给客户端。这样一来,客户端可以实时显示 agent 状态,而不是被动等待文本输出。第二,ACP 显式处理权限。比如 agent 需要执行 edit 操作时,ACP 可以把权限请求抛给外部客户端,由客户端用自己的 UI 来展示确认流程,而不是强依赖终端里的交互提示。这对 IDE 很关键,因为 IDE 希望用原生对话框、侧边栏或 inline 审批,而不是让用户切回 shell。

第三,OpenCode 的 ACP 已经包含了面向具体编辑器的语义。agent.ts 中的 parseUri 明确处理了 zed:// URI,这表明 ACP 并不是停留在抽象层面的“未来标准”,而是已经在为 Zed 这类编辑器集成做准备。

为什么 ACP 重要?因为现在很多 agent 和 IDE 的结合方式都很别扭。要么把整套 agent 逻辑直接塞进 editor plugin 里,导致重复实现、重复维护;要么通过 CLI 做各种不稳定的桥接,靠解析日志、封装自定义命令凑合使用。ACP 提供了第三条路:让 agent 成为一个通过协议暴露能力的本地服务,而编辑器只是它的宿主或客户端。

这种模式带来的好处非常直接。对 IDE 厂商来说,不必为每个 agent 都写一整套定制逻辑。对 agent 开发者来说,也不必为每个编辑器重新发明集成方式。只要双方都实现 ACP,对接成本就会显著下降。更进一步,客户端可以专注在 UX 层——比如如何展示会话、如何审批权限、如何插入上下文;而 agent runtime 则专注在工具执行、上下文管理、模型调用和任务规划。

与 Claude Code 相比,这一点尤其突出。Claude Code 在工程化和体验上很强,但它并不是围绕一个开源可审查的“client-agent protocol”来展开其对外集成能力。Oh-My-OpenCode 虽然极大增强了编排与多智能体,但它更多是在继承和扩展 OpenCode 的宿主能力,而不是重新定义外部客户端协议层。因此,ACP 可以视为 OpenCode 自身非常独特的一项贡献。

更深层地看,ACP 代表的是 agent 生态的“第二波协议化”。第一波协议化主要是工具层,例如 MCP 让 agent 可以标准化访问外部能力。第二波则是运行时托管层:客户端如何启动 agent、附加会话、传入编辑器上下文、处理权限、接收流式更新。ACP 正是在这个方向上的一次早期但重要的尝试。

因此,对未来 agent 设计者而言,教训很明确:不要把 agent 和客户端界面死死绑在一起。应该在它们之间建立一个协议边界。一旦这个边界清晰,terminal、IDE、browser、notebook、自动化系统都可以共享同一个 agent engine。OpenCode 的 ACP 支持,正是在向这个方向迈出关键一步。