OpenCode 源码解读
逐层拆读开源编码 Agent「OpenCode」的 TypeScript 源码——连 TUI 也是客户端的服务端架构、Effect 化的内核、两代会话引擎并存,一边讲怎么用,一边讲怎么实现。
OpenCode(命令行叫 opencode)自称“开源的 AI 编码 Agent”:默认形态是跑在终端里的全屏 TUI,能读写代码、跑 shell、搜文件、抓网页,并根据反馈决定下一步。它不绑定任何一家模型厂商——提供方与模型清单来自开放目录 models.dev,调用默认走 Vercel AI SDK。同一个核心还以 Web 界面、Electron 桌面端、VS Code 扩展、ACP 编辑器集成、GitHub Actions 里的 agent 等形态出现。
项目最早在 sst/opencode 下开发,现已迁到 anomalyco/opencode(旧地址自动跳转)。整个项目用 TypeScript 写成、跑在 Bun 上,是一个 36 个 workspace 包的 monorepo:全仓不含测试近 50 万行,其中与 agent 直接相关的十来个包(CLI 与服务端、Effect 内核、模型协议层、TUI、契约层等)合计约 17 万行。
这个专栏把它逐层拆开读。
源码基准
本专栏所有引用以下述快照为准:
| 项 | 值 |
|---|---|
| 仓库 | github.com/anomalyco/opencode |
| commit | 3104c1428ec91f809e5ab86631300de41eb6952e(即 v1.18.30 标签) |
| 版本 | opencode v1.18.30 |
| 快照日期 | 2026-09-09 |
| 许可 | MIT |
| 运行要求 | 从源码开发需 Bun 1.3.14;发行版是 Bun 编译出的独立可执行文件 |
所有路径都相对仓库根,例如 packages/opencode/src/session/prompt.ts;文中指向 GitHub 的源码链接都固定在 v1.18.30 标签上。
读者预设:默认你会读 TypeScript(async、泛型、联合类型、interface)。OpenCode 重度使用 Effect,这套写法对多数读者是陌生的,怎么读这份源码会先把必需的惯例讲清楚,之后的篇目只在关键处就地补一句。读过《从 LLM 到 Coding Agent》会更顺,但不是硬前提。
这个专栏怎么读
每一章尽量走两条线:
- 怎么用——这个功能在
opencode里长什么样、怎么配置; - 怎么实现——翻到对应包的源码,看它在底层到底怎么做。
侧重结构与数据流:讲清“一件事经过哪些包、数据怎么流、边界契约是什么”,而不是逐行贴代码——关键处才引一小段源码点睛。
和另外四本的关系
站里已有四本相关专栏,五本互为印证:
| 专栏 | 视角 |
|---|---|
| 《从 LLM 到 Coding Agent》 | 教学最小实现:一个 Coding Agent 在裸 LLM API 之上该做哪些事 |
| 《Grok Build 源码解读》 | Rust 生产实现:xAI 的终端 Agent 怎么做 |
| 《Kimi Code 源码解读》 | TypeScript 生产实现:DI × Scope 引擎、vendored 的 pi-tui 与自研嵌入式数据库 |
| 《MiMo Code 源码解读》 | 在 OpenCode 之上二次开发:小米为长程任务加的检查点、分层记忆、Actor 与 Workflow |
| 本专栏 | TypeScript + Effect 生产实现:服务端优先、提供方中立 |
OpenCode 与 Kimi Code 同为 TypeScript,却走了两条很不一样的路:Kimi Code 用 DI 容器组织服务,TUI 框架和数据库都自己写;OpenCode 把几乎所有服务都写成 Effect 的 Service 与 Layer,TUI 基于 OpenTUI + SolidJS,存储直接用 SQLite + Drizzle。MiMo Code 则是小米从 OpenCode v1.14.19 分叉出来独立演进的版本,底座与本专栏相同,新加的是检查点、分层记忆、Actor 与 Workflow 等面向长程任务的机制。几本对照着读,最能看出哪些是本质约束,哪些只是工程口味。
它有什么特别的
读之前先知道这份源码值得看的地方:
- 连 TUI 也是客户端。默认的
opencode命令把服务端放进一个 Bun Worker 线程,TUI 只通过 SDK 发 HTTP 请求(进程内经 RPC 隧道转发)并订阅事件流;加上--port就变成真正对外监听的服务。Web、桌面端走的是同一套 API。 - Effect 全面化。依赖注入、并发、资源作用域、错误通道都交给 Effect v4(beta):用
Context.Service与Layer组装服务,用Effect.fn("Domain.method")给每个操作命名——读懂这套惯例是读懂源码的前提。 - 两代会话内核并存。
packages/opencode/src/session里是现役的 V1 主循环;packages/core/src/session里是正在迁移的 V2:持久化收件箱、“受理”与“执行”分离、Context Epoch。同一套能力的两种架构可以直接对比。 - 提供方中立。模型目录来自 models.dev,调用默认走 Vercel AI SDK,再用近两千行的
provider/transform.ts抹平各家差异;另有自研的packages/llm按“协议、端点、认证、分帧”四个维度重新建模模型调用,以实验开关的形式逐步接入。 - 契约驱动的 API 分层。
schema → protocol → server / client的依赖方向写进了仓库规则,OpenAPI 文档与客户端代码都从 HttpApi 定义生成。 - 可扩展面很宽。配置文件、用 Markdown 定义的 agent 与命令、Skills、MCP、LSP、格式化器、npm 插件(钩子与自定义工具)一应俱全。
路线图
- 第 0 部分 · 导论与全景——它是什么、Monorepo 全景、怎么读这份源码、启动链路、一条消息的生命周期。
- 第 1 部分 · 会话引擎——会话与消息模型、主循环、流处理器、系统提示词、上下文压缩、模型调用层、快照与撤销。
- 第 2 部分 · 工具系统——工具契约与注册表、文件工具、Shell、子代理与待办、联网与 Code Mode、权限。
- 第 3 部分 · 模型与提供方——models.dev 目录、提供方适配层、认证与提供方插件、
packages/llm协议层。 - 第 4 部分 · 扩展机制——配置系统、Agent 与命令与 Skills、MCP、LSP 与格式化器、插件。
- 第 5 部分 · 服务形态与客户端——HTTP 服务端、事件与同步、SDK 与协议、终端界面、ACP 与 GitHub 等其他入口。
- 第 6 部分 · V2 架构演进——Effect 运行时与 Location、V2 会话内核、V2 工具与权限、SQLite 存储与事件投影、新 CLI 与守护进程、收尾复盘。
准备好了,就从 OpenCode 是什么 开始。