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

模型: openai/gpt-5.4
生成日期: 2026-04-01
书名: Claude Code VS OpenCode:架构、设计与未来
章节: 第2章 — 三大系统概览
Token用量: 约 10,800 input + 2,600 output

2.1 OpenCode:开源基座

如果把 AI 编码智能体看成一台“软件工程机器”,那么 OpenCode 更像一套可拆解、可替换、可二次装配的底盘。它不是先从“某个神级模型”出发,而是先把运行时、会话、工具、权限、界面、协议和扩展点做成一组可以组合的工程构件。也正因此,它在三套系统中最像“基础设施”,而不是“成品应用”。

从代码库看,OpenCode 位于 https://github.com/anomalyco/opencode/tree/main,采用 TypeScript 5.8 与 Bun 1.3.10 作为主运行时,顶层以 Turbo 驱动 monorepo。这里的 monorepo 并不只是“把包放在一起”,而是把不同交付面共享在同一类型系统与依赖图内:packages/opencode 是核心引擎,packages/app 是 Web 前端,packages/desktop 是 Tauri 桌面封装,packages/sdk/js 提供 JS SDK,packages/plugin 则暴露插件开发接口。换言之,OpenCode 的关键价值不是某一个包,而是这些包围绕同一内核形成的“多界面单内核”架构。

它的技术选型非常说明问题。模型层使用 Vercel AI SDK,即 ai 与一组 @ai-sdk/* provider 适配器,把 20+ 提供者收敛到统一流式接口。这个抽象的意义不只是少写适配代码,更重要的是把“模型切换”从产品级能力降格为配置级能力。服务层使用 Hono:packages/opencode/src/server/server.ts 中直接以 new Hono() 组装 HTTP 服务、SSE、认证与 OpenAPI 路由。持久化层使用 Drizzle ORM + Bun SQLite,src/storage/db.ts 清楚展示了 bun:sqlitedrizzle-orm/bun-sqlite 的组合,数据库文件默认落到全局数据目录中的 opencode.db。验证层几乎被 Zod 贯穿:智能体定义、事件定义、消息结构、工具参数、MCP 状态,都先是 schema,再是实现。UI 层则统一押注 Solid.js,终端 TUI、Web App、桌面壳共享相近的响应式心智模型。

这套技术栈带来的第一个架构亮点,是基于实例的上下文管理。src/project/instance.tsInstance.provide() 和按目录缓存的 state,把“当前项目目录、worktree、project 元信息”绑定为一个运行时实例。这里的 instance 不是传统面向对象里的单例,而更像按工作目录分片的执行上下文。对于编码智能体而言,这意味着多项目、多工作树、重载与销毁都能成为一等公民,而不是临时拼接的全局变量。

第二个亮点是命名空间组织模式。OpenCode 广泛采用 export namespace X { ... } 组织复杂模块,把 schema、类型、状态、行为收拢到同一语义容器中,例如 AgentMCPMessageV2Database。这不是教科书里最常见的模块风格,但对大型 TypeScript 代码库很有效:读者进入单文件后,能同时看到领域对象的“数据定义+生命周期+查询入口”。这类模式可理解为“语义邻接”,即让同一概念的所有工程切面物理上靠近,以降低认知跳转成本。

第三个亮点是类型安全事件总线。src/bus/bus-event.ts 通过 Zod 定义事件 payload,再动态组装 discriminated union。事件在这里不是字符串约定,而是可校验、可推导、可生成 schema 的协议对象。对于智能体系统,这很关键,因为消息、工具执行、MCP 状态变化、UI 通知往往跨越多个子系统;如果没有类型化事件,总线很快就会退化成不可维护的“字符串广播器”。

第四个亮点是 Zod schema 的全链路渗透。OpenCode 的工具定义、Agent 信息、MCP 资源、HTTP 接口、消息 parts 都先被 schema 化,再进入运行时。这种做法本质上是把“弱约束提示工程”尽量转回“强约束软件工程”。对于 AI 系统而言,这是一种重要设计哲学:LLM 可以是不确定的,但系统边界最好是确定的。

在交付界面上,OpenCode 并不满足于单一 CLI。它同时提供 CLI、Solid.js TUI、基于 Solid.js + Tailwind + Vite 的 Web 应用、基于 Tauri + Rust 的桌面版,以及基于 Hono 的 HTTP API。很多项目会把多界面当作“包装层”,但 OpenCode 把它们做成并列的一组入口。这直接提升了平台适配能力:本地终端用户、浏览器用户、桌面用户、外部编程调用者,都能共享同一会话与工具底座。

Agent 层面,OpenCode 内置 4 个主要智能体:build 是默认执行者,plan 是只读规划模式,general 负责一般性子任务,explore 则是快速探索型子智能体。src/agent/agent.ts 中可以看到它们的权限规则直接由 PermissionNext 组合而成,例如 plan 禁止编辑工具,而 explore 只允许搜索、读取、web 获取等探索型能力。这种“Agent = prompt + permission profile + model override”的设计非常干净:智能体首先是能力配置,而不是人格扮演。

工具系统同样体现了 OpenCode 的工程理性。src/tool/registry.ts 中可见其核心工具集大约 20 个,包括 bashreadglobgrepeditwritetasktodowebfetchwebsearchcodesearchskillapply_patchlsp 等。每个工具都带 Zod 参数 schema,工具暴露给模型前还可经过插件层的 tool.definition 改写。这里的“上下文丰富”指的不是大段自然语言,而是目录、worktree、sessionID、权限上下文、模型信息等结构化执行语境。工具不只是函数,更是受权限系统和项目实例系统约束的能力对象。

会话持久化方面,OpenCode 采用 SQLite + Drizzle 持久化 session/message/part/todo/permission 等表。更值得注意的是 MessageV2:它不是单块文本,而是多部分结构,可拆成 textreasoningfileagentsnapshotpatchsubtaskstep-startstep-finish 等 part。所谓“多部分消息结构”,可以理解为把一次 agent 交互分解成一串有类型的原子事件,而不是把所有内容糊成一段聊天记录。这为重放、压缩、审计、可视化和局部恢复都提供了基础。

协议支持则进一步说明 OpenCode 的平台野心。MCP 客户端实现相当完整,src/mcp/index.ts 明确支持 stdio、SSE、Streamable HTTP 三种传输,并整合 OAuth 流程。与此同时,OpenCode 还引入 ACP,即 Agent Client Protocol,并在 src/acp/* 下实现与 Zed 编辑器的集成。这意味着它不仅能“调用外部工具”,还能被外部开发环境作为 agent 内核来接入。

最后是插件系统。packages/plugin/src/index.ts 暴露了一组非常关键的钩子:autheventtoolchat.messagechat.paramschat.headerstool.execute.beforetool.execute.afterexperimental.chat.messages.transform 等。特别值得注意的是,它允许插件以异步函数方式返回钩子处理逻辑,等于把宿主生命周期切开,交给外部扩展逐段介入。OpenCode 因而不是“可配置软件”,而是“可编排宿主”。这正是它能成为 Oh-My-OpenCode 基座的根本原因。

简言之,OpenCode 的核心竞争力不是某个炫目的 agent prompt,而是把运行时、协议、工具、权限、会话与多端 UI 稳定地焊接在一起。它像 Linux 内核而不像整机产品:学习门槛更高,但一旦掌握,就能承载远比单体 CLI 更复杂的 agent 系统。