OpenCode 源码架构深度解读

一个 100% 开源的终端 AI 编程代理。Go + TypeScript 双引擎、客户端-服务器分离架构、LSP 深度集成、 75+ 模型提供商——解读其"开放、灵活、终端优先"的工程哲学。

MIT 开源 Go + Bun 双运行时 客户端-服务器架构 75+ 模型提供商 LSP 深度集成
Go
TUI 前端
Bun
后端引擎
75+
模型提供商
11+
内置工具
MCP
协议扩展

一、总体架构:客户端-服务器分离

与 Claude Code 的单进程架构截然不同,OpenCode 采用了经典的客户端-服务器(C/S)分离设计。 前端是用 Go 语言编写的终端用户界面(TUI),后端是运行在 Bun 上的 TypeScript HTTP 服务器。 两者通过 HTTP 请求和 Server-Sent Events (SSE) 进行通信。这种设计让前后端可以独立演进, 也意味着任何 HTTP 客户端(不仅仅是内置的 TUI)都可以与后端交互。

Go TUI 客户端
Bubble Tea 框架
终端渲染 & 交互
用户输入处理
SSE 事件监听
Agent 模式切换 (Tab)
HTTP POST 发送指令
SSE 流式推送结果
Bun 后端服务器
Hono HTTP 框架
Agent Loop 引擎
工具执行 (Tool Executor)
LLM Provider 抽象层
LSP Server 管理
MCP Client 桥接
Event Bus 事件总线
设计洞察:为什么不选单进程?

Claude Code 选择了单进程 TypeScript 架构以追求极致延迟,而 OpenCode 选择 C/S 分离以追求极致灵活性。 分离架构的代价是每次交互多一次 HTTP 往返(实测慢约 45~78%),但收益是:前端可以用任何语言重写(不只是 Go), 后端可以独立升级,甚至可以开发桌面 GUI 或 Web 前端来替代 TUI。这是"性能换灵活性"的经典权衡。

构建与分发

OpenCode 使用 bun build --compile 将 Bun 后端编译为独立可执行文件, 然后将 Go TUI 二进制嵌入其中。最终用户只需下载一个 opencode 命令即可运行, 启动时同时拉起后端服务器和前端 TUI。

二、Agent Loop:Plan / Build 双模式循环

OpenCode 的 Agent Loop 与 Claude Code 有根本性的不同——它不是一刀切的单一循环, 而是设计了两种工作模式:Plan(计划,只读分析)和 Build(构建,可执行操作)。 用户随时可以通过 Tab 键在两种模式间切换。

🔍
Plan 模式

只读分析模式。Agent 只能读取文件、搜索代码、查询 LSP 诊断,不能编辑文件或执行 Bash 命令。 适合在动手之前先理解代码库、制定方案。

Read 允许 Grep 允许 Glob 允许 LSP 允许 Edit 禁止 Bash 禁止 Write 禁止
🔧
Build 模式

完全执行模式。Agent 拥有全部工具访问权限,可以编辑文件、运行 Bash 命令、创建新文件。 适合实际编码、测试和部署。

Read 允许 Grep 允许 Glob 允许 LSP 允许 Edit 允许 Bash 允许 Write 允许

Agent Loop 执行流程

用户输入
或 @mention
上下文组装
System Prompt
+ 历史 + 工具
streamText
AI SDK 流式调用
Tool Call?
模型决策
权限检查
allow/deny/ask
执行工具
+ LSP 反馈
stopWhen?
停止条件

核心使用 AI SDK 的 streamText 函数进行流式模型调用。每次模型响应可能包含文本输出和工具调用, 系统依次执行工具并将结果注入上下文后再次调用模型,形成一个迭代循环。停止条件通过 stopWhen 参数配置, 支持最大步数限制和自定义触发器。

模式切换机制

当用户从 Plan 切换到 Build 模式时,系统会注入一条合成的系统提示:

// 模式切换时注入的系统提示 "<system-reminder> Your operational mode has changed from plan to build. You now have full access to edit files, run commands, and write code. </system-reminder>"

这种设计让模型能感知到自身权限范围的变化,从而调整行为策略——Plan 模式下倾向于输出分析和建议, Build 模式下倾向于直接执行操作。

三、工具系统:11+ 内置工具 + MCP 扩展

OpenCode 的工具系统比 Claude Code 更精简,核心内置 11 个工具。但通过 MCP 协议和插件系统, 可以无限扩展工具池。每个工具由描述、Zod 输入模式和 execute 函数组成,运行在 Bun 运行时中。

BashTool
执行 Shell 命令。支持超时控制和后台运行。
EditTool
精确字符串替换编辑文件。触发 LSP 诊断反馈。
WriteTool
创建或完整覆写文件内容。
ReadTool
读取文件内容,支持行号范围。
GlobTool
文件模式匹配搜索(如 **/*.ts)。
GrepTool
正则表达式内容搜索(基于 ripgrep)。
ListTool
列出目录内容。
WebFetchTool
获取网页内容并提取信息。
TodoWriteTool
创建和管理任务列表。
TodoReadTool
读取当前任务列表状态。
TaskTool
生成子代理执行复杂子任务。

工具定义示例

const EditTool = defineTool({ name: "edit", description: "Edit a file using exact string replacement", inputSchema: z.object({ file_path: z.string(), old_string: z.string(), new_string: z.string(), }), async execute(input) { // 执行文件编辑 await replaceInFile(input.file_path, input.old_string, input.new_string); // 触发 LSP 诊断反馈 const diagnostics = await LSP.diagnostics(input.file_path); return { success: true, diagnostics }; } });
MCP 工具扩展

OpenCode 完整支持 Model Context Protocol (MCP)。在配置文件中声明 MCP Server 后, 系统自动创建 MCP Client 并拉取远程/本地工具定义,合并到工具池中。这意味着你可以接入 Slack、GitHub、 数据库等外部服务的工具,而不需要修改 OpenCode 源码。

四、LSP 深度集成:编译器的眼睛

这是 OpenCode 相比 Claude Code 最显著的架构差异。OpenCode 不仅是一个"文本操作器"—— 它通过 Language Server Protocol 深度集成了编译器/语言服务器的能力,让模型在编辑代码后 能立即"看到"编译错误、类型问题等诊断信息。

Agent Loop
模型决定编辑
EditTool
执行文件修改
LSP.touchFile
通知语言服务器文件已变更
LSP.diagnostics
获取类型错误、语法问题
JSON-RPC
STDIO 双向通信
Language Server
pyright / gopls / tsserver...
诊断结果注入上下文
模型看到错误并自动修复

LSP 服务器通过 JSON-RPC 协议在 STDIO 上通信。系统支持启动多个语言服务器(如 pyright 用于 Python、 gopls 用于 Go、tsserver 用于 TypeScript),并通过全局 Event Bus 管理所有诊断状态。 每次文件编辑后,系统自动调用 LSP.touchFile 更新服务器模型, 然后用 LSP.diagnostics 获取最新问题并注入到模型上下文中。

为什么 LSP 集成如此重要?

没有 LSP 集成的 Agent(如 Claude Code)只能通过运行测试或手动检查来发现代码错误。 有了 LSP,Agent 每次编辑后都能获得即时、精确的编译器级别反馈——类型不匹配、未定义变量、 语法错误等——形成一个自动化的"编写→编译→修复"闭环。这大幅减少了"写了错的代码却不自知"的问题, 是 Agent 编程质量的质变性提升。

五、权限模型:三级细粒度控制

相比 Claude Code 的 7 种权限模式和 7 层安全防护,OpenCode 的权限系统更为简洁—— 采用三级控制(allow / deny / ask),支持按工具键和 glob 模式进行细粒度配置。

权限键 Plan 模式 Build 模式 说明
edit deny allow 文件编辑权限
write deny allow 文件创建/覆写权限
bash deny allow Shell 命令执行权限
glob allow allow 文件模式搜索
grep allow allow 内容正则搜索
lsp allow allow LSP 诊断查询
read allow allow 文件读取
skill allow allow 技能/知识查询

Glob 模式细粒度控制

权限键支持 glob 模式匹配,实现更细粒度的控制。例如可以配置为:

{ "permissions": { "edit": "allow", "bash": "ask", // 每次 Bash 执行需用户确认 "edit:*.env": "deny", // 禁止编辑 .env 文件 "bash:rm *": "deny", // 禁止 rm 命令 "bash:npm test": "allow" // 自动允许测试命令 } }
安全哲学差异:Git 快照 vs 层层拦截

Claude Code 的安全策略是"层层拦截"——7 层防护、7 种模式,在操作执行前反复检查。 OpenCode 的策略更偏向"Git 快照回滚"——允许大部分操作执行,但通过 git write-tree 在每个步骤前创建快照,出问题时用 git read-tree + git checkout-index 快速回滚。 前者更安全但交互更繁琐,后者更高效但需要用户信任 Git 兜底能力。

六、会话管理与上下文工程

OpenCode 的会话持久化使用 SQLite 数据库(而非 Claude Code 的 JSONL 文件), 上下文管理采用 90% 阈值自动摘要压缩策略。

上下文自动压缩

对话历史
累积
Token 计数
监控
超过 90%?
触发压缩
摘要提示
专用 prompt
压缩历史
保留摘要

当 token 使用量接近上下文窗口的 90% 时,系统自动使用一个专门的摘要提示(summary prompt) 将历史对话压缩为简短摘要,释放 token 空间继续对话。这比 Claude Code 的五层压缩管线更简单, 但也更粗粒度——Claude Code 可以精细地裁剪不同优先级的内容,而 OpenCode 则是"全有或全无"的摘要式压缩。

系统内置 Agent 类型

📦 build (默认)

主交互 Agent。拥有完整工具集,可执行所有操作。

🔍 plan

只读分析 Agent。限制为读取和搜索工具,不执行修改。

📝 compaction

隐藏系统 Agent。专门用于上下文压缩时的历史摘要生成。

🏷️ title

隐藏系统 Agent。自动为会话生成简洁标题。

📋 summary

隐藏系统 Agent。生成会话或任务的摘要信息。

七、Git 集成:快照式安全网

OpenCode 的安全策略核心不是"阻止操作",而是"确保可回滚"。它在每个 Agent 步骤开始前使用 Git 原生命令 创建工作目录快照,出问题时快速恢复到之前的状态。

git write-tree
创建当前工作目录快照
Agent 执行
编辑文件、运行命令
验证结果
检查是否出错
出错?
read-tree + checkout-index

用户也可以通过 TUI 的 /undo/redo 命令手动回退或重做操作。 这种基于 Git 的安全机制的优势是不需要复杂的权限系统——大部分操作都可以放心执行, 因为 Git 快照提供了完整的安全网。

八、子代理系统:YAML 配置的灵活委托

OpenCode 的子代理系统通过 Task 工具或 @mention 触发,支持完全自定义的 Agent 配置。 每个子代理运行在独立的会话中,拥有自己的模型、工具集和系统提示。

Build Agent
主交互 · 全工具集
Plan Agent
只读分析 · Tab 切换
↓ Task / @mention ↓
general
多步任务执行
独立会话 · 独立模型
explore
只读代码搜索
受限工具集
scout
外部文档研究
WebFetch 工具
自定义 Agent
YAML frontmatter
完全可配置

自定义 Agent 配置

# ~/.config/opencode/agents/reviewer.md --- description: Code review without edits mode: subagent permission: edit: deny bash: deny read: allow grep: allow model: claude-sonnet-4-20250514 temperature: 0.3 hidden: false --- You are a senior code reviewer. Focus on: - Security vulnerabilities - Performance bottlenecks - Code readability and maintainability - Test coverage gaps

通过 YAML frontmatter,用户可以精确控制子代理的模型选择、温度参数、工具权限和系统提示。 hidden: true 的子代理不出现在自动补全中,但模型仍可通过 Task 工具调用它。 使用 opencode agent create 命令可以交互式创建新 Agent。

九、模型提供商抽象:75+ 提供商统一接入

这是 OpenCode 作为开源项目最大的差异化优势。通过 AI SDK(ai-sdk.dev)的标准化抽象层, OpenCode 可以接入任何兼容的 LLM 提供商——从云端 API 到本地模型,无需修改一行代码。

Anthropic
Claude Opus / Sonnet / Haiku
OpenAI
GPT-4o / GPT-4.1 / o3
Google
Gemini 2.5 Pro / Flash
Mistral
Mistral Large / Codestral
xAI
Grok
Ollama
本地模型(免费)
LM Studio
本地模型(免费)
OpenAI 兼容
任何兼容端点

AI SDK 抽象了不同提供商之间的 API 差异——流式响应格式、工具调用协议、错误处理等全部统一。 用户只需在配置文件中切换 API Key 和模型名称即可。系统还会根据提供商注入特定的 System Prompt 优化。

模型自由的战略意义

Claude Code 被锁定在 Anthropic 生态中,用户无法使用其他模型。OpenCode 的提供商无关性意味着: 你可以用 Claude 做主 Agent、用 GPT-4o 做子代理、用本地 Llama 做代码搜索——按任务特性选择最优模型, 按预算灵活调配。本地模型(通过 Ollama)甚至可以完全免费运行。

十、配置系统:多层级 Markdown 驱动

OpenCode 的配置系统融合了 JSON 配置和 Markdown 文件两种方式,支持从全局到项目级的多层级覆盖。

⚙️
全局配置
~/.config/opencode/opencode.json — API Key、默认模型、MCP 服务器
📂
项目配置
./opencode.json — 项目特定的模型、权限、工具设置
📝
Agent 定义
~/.config/opencode/agents/*.md — 自定义子代理(YAML frontmatter)
📖
上下文文件
./AGENTS.md / CLAUDE.md — 项目级指令和代码规范

十一、Event Bus:实时事件驱动

OpenCode 的后端维护一个全局 Event Bus,所有关键事件(模型响应、工具执行、诊断更新、会话状态变更) 都通过 SSE 实时推送给所有连接的客户端。这意味着你可以同时运行 TUI、桌面 GUI 和监控脚本, 它们都能看到实时的 Agent 执行状态。

SSE 流式推送

模型的文本输出和工具调用结果通过 Server-Sent Events 流式传输到客户端,实现打字机效果。

多客户端广播

Event Bus 支持多个同时连接的客户端。TUI、移动端、脚本都可以独立监听事件流。

插件 Hook

通过插件系统注册 pre/post 工具调用 Hook,可用于日志记录、审计或自定义逻辑注入。

LSP 诊断广播

语言服务器的诊断信息变更通过 Event Bus 广播,确保所有客户端看到最新的代码问题。

十二、Claude Code vs OpenCode:架构对比总结

维度 Claude Code OpenCode
架构模式 TypeScript 单进程 Go TUI + Bun 后端(C/S 分离)
运行时 Bun Go (前端) + Bun (后端)
Agent 模式 单一 ReAct 循环 Plan / Build 双模式
模型支持 仅 Anthropic 模型 75+ 提供商(含本地模型)
内置工具数 54+ 11+(+ MCP 扩展)
LSP 集成 深度集成(JSON-RPC 诊断反馈)
安全防护 7 层纵深 + 7 种权限模式 3 级权限 + Git 快照回滚
上下文压缩 5 层压缩管线 90% 阈值自动摘要
记忆系统 CLAUDE.md 四级层级 AGENTS.md + 会话摘要
会话持久化 JSONL Append-Only SQLite 数据库
子代理配置 内置固定类型 YAML frontmatter 完全可配
扩展机制 Hooks + Skills + Plugins + MCP MCP + 插件 Hook
开源 闭源 MIT 完全开源
性能 基线(单进程低延迟) 慢约 45~78%(HTTP 往返开销)
一句话总结

Claude Code 是"为单一模型深度优化的精密堡垒"——安全防护层层叠叠、上下文管理精密到极致, 但你必须留在 Anthropic 的花园里。OpenCode 是"为多模型灵活适配的开放工坊"——安全防护更简洁(靠 Git 兜底), 上下文管理更粗放(90% 阈值摘要),但你可以用任何模型、改任何代码、部署到任何地方。 选择哪一个,取决于你更在意"安全与精致"还是"自由与灵活"。