Trending 排名:#8|快照日期:2026-09-06|Stars:205,405(9 月 7 日 API 补充核验)|Forks:26,785|主语言:TypeScript|License:MIT
GitHub:github.com/anomalyco/o…
AI 编程工具最容易被做成两种形态:一种是把模型对话框嵌进编辑器,另一种是在终端里包一层 prompt → shell → prompt 循环。演示都不难,真正难的是把会话、模型、工具权限、终端进程、子 Agent、断线重连和上下文压缩放进同一套可恢复的运行时。
OpenCode 已经跨过了“终端聊天工具”这条线。它同时提供 TUI、非交互 CLI、Web、桌面应用、JavaScript SDK、ACP、MCP 和无头 HTTP Server;TUI 既能连进程内服务,也能通过 attach 接入另一台机器上的服务端。源码里最值得看的不是提示词,而是这套控制面如何把一次模型调用变成可持久化、可观察、可授权、可继续的工程任务。
这篇分析基于 2026 年 9 月 6 日保留的 Trending 快照,以及 9 月 7 日对 dev 分支 57ef3828431790c53f8f333c7ffbfe88770a1812 的源码审计。历史快照只保留了完整榜单和排名,没有保存 OpenCode 当时的总 Stars/Forks;文中的 205,405 Stars、26,785 Forks 和社区数据均明确采用次日 API 补充值,不把它们伪装成历史时点数据。
📋 项目概览
| 项目 | 内容 |
|---|---|
| 项目名 | anomalyco/opencode |
| 一句话 | 开源 AI 编程 Agent:同一套后端支撑终端、桌面、Web、SDK 和远程客户端 |
| Trending | 2026-09-06 本机快照 #8 |
| Stars | 205,405(2026-09-07 API 补充核验) |
| Forks | 26,785(2026-09-07 API 补充核验) |
| 语言 | TypeScript 为主,另有 TSX、CSS、Shell、SQL 等 |
| License | MIT |
| 默认分支 | dev |
| 版本 | 当前源码与最新 Release 均为 v1.18.29 |
| 运行时 | Bun 1.3.14;发布包 opencode-ai 提供平台二进制 |
| 接口 | TUI、CLI、HTTP/OpenAPI、SSE、WebSocket、JavaScript SDK、ACP、MCP |
🔥 为什么值得关注
OpenCode 的价值不只在“开源替代”。如果客户端、Agent 循环和工具执行都挤在一个进程里,那么 UI 退出通常意味着任务退出,远程接入也只能重新做一套。OpenCode 把交互面和执行面拆开:opencode serve 可以单独启动服务;opencode attach <url> 让 TUI 接入现有服务;opencode run --attach 则让脚本复用同一个远端控制面。Web 和桌面端也围绕同一套 API 工作,而不是各自维护一套 Agent 逻辑。
第二个值得关注的点是状态模型。会话不是一串只存在内存里的消息。源码通过 SQLite + Drizzle 保存 session、message、part、token、cost、permission、revert 和父子关系;工具调用从 pending、running 到 completed/error 的变化会持续写入 part。模型流中出现 reasoning delta、text delta、tool call、tool result 时,SessionProcessor 把它们投影到持久状态并发布事件。客户端断开后,权威状态仍在服务端,而不是终端渲染缓冲区里。
第三个点是安全边界写进了运行时。默认的权限决策不是简单布尔开关,而是按 permission + pattern 匹配规则,最后一条匹配规则生效;动作分为 allow、ask、deny。内置 plan Agent 默认拒绝编辑,并在 shell 前询问。需要特别强调:这仍然是应用级授权,不是容器或虚拟机隔离。获得允许后,命令会以 OpenCode 进程所属用户的系统权限执行。
🏗️ 核心特性
1. 一套后端,多种客户端
当前 CLI parser 注册了 TUI、run、serve、web、attach、mcp、acp、agent、session、export、import、models、stats、github、pr、plugin、db 等入口。它们不是彼此孤立的子产品。
opencode run 的源码注释明确区分三种模式:
| 模式 | 服务位置 | 适合场景 |
|---|---|---|
opencode run | 本地进程内服务 | 一次性脚本、CI、命令行自动化 |
opencode --mini | 本地进程内服务 | 轻量交互式终端 |
opencode run --attach URL | 远程或常驻 HTTP 服务 | 复用服务器上的会话、模型和工作目录 |
opencode attach URL | 远程或常驻 HTTP 服务 | 完整 TUI 连接已有服务 |
opencode serve | 独立无头服务 | Web、桌面、SDK、远端终端的控制面 |
attach 支持 --dir、--continue、--session、--fork、Basic Auth 用户名和密码。远程目录不必存在于客户端本机,参数会直接传给服务端。这意味着 OpenCode 不是把本地文件上传给云端模型,而是让 Agent 在服务端工作区内执行。
2. Provider 层不是写死一家模型
packages/opencode/package.json 直接依赖 Anthropic、OpenAI、Google、Azure、Amazon Bedrock、Cerebras、Cohere、Groq、Mistral、Perplexity、Together AI、xAI、OpenRouter 和 OpenAI-compatible 等 AI SDK provider,同时还有 GitLab workflow provider。
模型调用进入 Session/llm.ts 后,会并行解析 provider、配置、认证和模型实例,再交给请求预处理层统一处理 system prompt、messages、tools、headers、temperature、top-p、top-k、输出上限与 provider options。默认执行路径基于 Vercel AI SDK;实验性的 native LLM runtime 如果不支持目标 provider,会记录具体原因并回退到 AI SDK,而不是静默失败。
这个抽象的实际意义是:上层 SessionProcessor 只消费统一的流事件,不需要为每家模型重写 reasoning、文本、工具调用和 usage 处理。但“支持 provider”不等于所有模型行为完全一致。工具 schema、thinking 字段、缓存计费、上下文窗口和认证方式仍会经过 provider transform 做兼容。
3. 权限是规则集,不是一个 YOLO 开关
权限服务对每个请求执行如下匹配:
(permission, pattern)
│
▼
合并 Agent 规则 + Session 规则 + 已批准规则
│
▼
从后向前找最后一条 wildcard 匹配
│
├─ deny → 立即拒绝
├─ allow → 立即执行
└─ ask → 发布 Permission.Asked,等待用户回复
│
├─ once 只放行本次
├─ always 写入会话内 approved 规则
└─ reject 拒绝并清理同会话待决请求
源码还会把被全局 deny 的工具从模型可见工具集合里移除。编辑类 edit、write、apply_patch 会统一映射到 edit 权限;MCP 资源读取也会映射到 read 权限。这样做比“模型先调用、执行时再报错”更干净,因为明确禁止的工具不会继续消耗模型选择空间。
但 --auto 的含义也要看清:当前 help 写的是“自动批准未被显式拒绝的权限”,并标注 dangerous。它没有创建操作系统沙箱,也不会把 shell 放进容器。对于陌生仓库,更稳的做法仍是使用临时 clone、干净工作树、低权限账号或容器。
4. 子 Agent 是独立子会话
task 工具并不是一次隐藏的 generateText()。它会创建或恢复一个带 parentID 的子 Session,记录子 Agent 名称、模型、权限和 task id,然后通过与普通会话相同的 SessionPrompt.prompt() 路径运行。
几个实现细节很关键:
- 模型继承:子 Agent 没有指定模型时,继承父消息的 provider/model/variant。
- 权限收窄:子会话从父会话派生权限,并默认阻止子 Agent 再调用 task,除非配置明确放开。
- 深度上限:默认
subagent_depth为 1;达到上限会返回错误,不允许无限递归。 - 可恢复:传入
task_id可以继续之前的子会话,而不是重新开始。 - 后台模式:实验性 background subagent 会立即返回 job/session id;完成后,运行时把结果作为 synthetic user part 注入父会话,再触发父会话继续处理。
- 取消传播:父任务中断时,会取消子 Session 和 BackgroundJob,而不是只停止 UI 等待。
这套设计的成本是状态机复杂度明显上升,但换来的能力很具体:父 Agent 可以把长搜索交给子会话,自己继续做不冲突的工作;子结果回来后仍能进入统一的消息历史和事件流。
5. 上下文压缩保留“最近工作面”
长会话不能简单把最旧消息逐条删除。OpenCode 的 compaction 逻辑会:
- 按 user turn 划分历史;
- 计算可用上下文预算;
- 默认保留最近 2,000~15,000 tokens,目标约为可用窗口的 25%;
- 对更早历史生成摘要;
- 对历史工具输出做裁剪,普通旧输出最多保留 2,000 字符;
- 保护
skill工具输出不被普通 prune 规则直接清掉; - 保留 compaction 前后的消息关系,避免重复压缩已完成摘要。
PRUNE_MINIMUM=20,000 和 PRUNE_PROTECT=40,000 是工具输出裁剪的阈值,不是“会话最多 4 万 Token”。实际溢出判断还取决于模型上下文和输出预算。压缩解决的是上下文容量,不代表任务已经完成,也不等于长期记忆。
6. Snapshot、Revert 与可审计工具状态
SessionProcessor 在模型流开始前先抓 workspace snapshot。注释给出的理由很实在:AI SDK 可能在发出 step-start 事件前就执行工具,如果到事件到达时才拍快照,回滚基线可能已经被修改。
每个工具调用都会持久化为 part,并保留:
- tool 名称和 call id;
- 输入参数;
- pending/running/completed/error 状态;
- 开始和结束时间;
- 输出、附件与 metadata;
- 权限拒绝、问题拒绝和执行错误;
- 与 assistant message、session 的关联。
这使“撤销一次 Agent 修改”不再依赖模型自己记得改了哪些文件。不过 Snapshot 是版本与文件状态机制,不应被描述为强隔离:允许的 shell 命令仍可能修改工作区外文件或访问网络,能否回滚取决于被跟踪的范围。
🔬 技术架构深度解析
从输入到持久状态
OpenCode 当前执行链可以概括为:
TUI / Web / Desktop / CLI run / JS SDK / ACP
│
▼
进程内调用,或 HTTP + SSE + WebSocket
│
▼
Effect HTTP Server / OpenAPI Router
├─ /global/* 与控制面
├─ 实例路由:按 directory / workspace 解析上下文
├─ 事件 SSE
├─ PTY WebSocket
├─ Basic Auth / CORS / schema / lifecycle middleware
└─ 内嵌 Web UI fallback
│
▼
SessionPrompt
├─ 解析文件、命令、Agent 与模型
├─ 装配 system prompt / instructions / skills
├─ 合并内置工具、插件工具和 MCP 工具
├─ 创建 assistant message
└─ 驱动 Agent loop
│
▼
LLM Service
├─ provider + auth + model
├─ request transform / plugin hooks
├─ AI SDK runtime
└─ experimental native runtime → 不支持时回退
│
▼
SessionProcessor
├─ reasoning/text delta
├─ tool call/result/error
├─ permission/question wait
├─ usage/cost/finish reason
├─ overflow → compaction
└─ snapshot/summary/revert
│
▼
SQLite WAL + Event Bridge
├─ session / message / part
├─ token / cost / parent-child / permission
└─ SSE/TUI/Web/SDK 增量更新
server.ts 使用 Effect 的 Layer 组合服务依赖,路由层显式装配 Database、Provider、Agent、Skill、Permission、Session、BackgroundJob、Compaction、LLM、LSP、MCP、ToolRegistry、Workspace 等服务。它不像传统 Express 项目那样从全局单例四处取对象,依赖图更容易在测试里替换;代价是 Effect 类型和 Layer 组合有较高学习成本。
HTTP Server 是边界,不是常驻守护进程本身
opencode serve 会启动无头服务并执行 Effect.never 保持进程存活。attach 能让客户端断开后重新连接,但源码没有把 serve 自己变成 systemd、launchd 或 Windows Service 管理器。终端退出后任务是否继续,取决于这个 server 进程是否仍被 tmux、容器、进程管理器或系统服务托管。
网络默认值相对保守:hostname 为 127.0.0.1,端口传 0 时先尝试 4096,再回退到随机空闲端口。服务端检测不到 OPENCODE_SERVER_PASSWORD 时会直接打印 unsecured warning。本次验证在 127.0.0.1:41096 启动 v1.18.29,GET /global/health 返回:
{"healthy":true,"version":"1.18.29"}
GET /doc 同时返回 OpenAPI 3.1 JSON。若改为 0.0.0.0、局域网或反向代理暴露,必须配置密码并限制网络入口;只设置 CORS 不能替代服务端认证。
SQLite 是权威会话库
当前数据库层使用 Effect + Drizzle SQLite,并在启动时设置:
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA busy_timeout = 5000;
PRAGMA cache_size = -64000;
PRAGMA foreign_keys = ON;
PRAGMA wal_checkpoint(PASSIVE);
默认数据库是数据目录下的 opencode.db;开发 channel 可以使用带 channel 名的数据库,OPENCODE_DB 也能指定绝对路径或 :memory:。WAL 和 busy timeout 有助于 UI、事件处理和后台任务并发访问,但这不等于多机分布式数据库。远程客户端共享的是同一个服务端数据库,不是多节点自动复制。
Session 行里除了标题和目录,还保存 provider/model/variant、token 四类计数、cost、summary diff、share URL、permission、revert、父会话 id、创建/更新时间等。模型上下文只是从这些持久对象投影出来的一种视图。
工具循环如何收口
Agent loop 的关键不是“能调用 shell”,而是要在流式模型、异步工具和持久状态之间保持一致。SessionProcessor 对每个工具 call 建立 Deferred,持续更新 running metadata,收到 result 后落盘 completed,收到权限拒绝或异常后落盘 error。它还定义了 DOOM_LOOP_THRESHOLD = 3,用于识别重复工具调用形成的死循环风险。
会话处理结果被压缩为三种控制信号:
| 结果 | 含义 |
|---|---|
continue | 本轮还有后续步骤,继续 Agent loop |
compact | 上下文溢出,先压缩再继续 |
stop | 正常完成、被拒绝、取消或不可恢复错误 |
这比根据 assistant 最后一段文本猜“是不是做完了”可靠,但它仍然没有证明任务结果正确。OpenCode 提供的是执行和状态基础设施,项目自己的测试、构建、lint、验收命令仍需由使用者定义和运行。
代码规模与集中度
审计时把 git ls-files -z 写到文件后解析,shell 行数与 Python 解析结果都为 6,620 个跟踪文件。只统计 .ts/.tsx 物理行,结果如下:
| 指标 | 数值 |
|---|---|
| 跟踪文件 | 6,620 |
.ts/.tsx 文件 | 3,329 |
.ts/.tsx 物理行 | 681,593 |
| 生产代码(排除测试和生成目录) | 456,640 行 |
| 测试代码 | 191,271 行 |
| 生成代码 | 33,682 行 |
workspace package.json | 40 个 |
主要包的 .ts/.tsx 物理行分布:
| Package | 行数 |
|---|---|
packages/opencode | 179,867 |
packages/app | 170,914 |
packages/core | 68,017 |
packages/console | 43,361 |
packages/ui | 33,854 |
packages/tui | 31,831 |
packages/sdk | 30,332 |
packages/session-ui | 21,434 |
packages/llm | 20,527 |
packages/stats | 18,049 |
最大的 TypeScript 文件之一是生成的 SDK 类型文件 packages/sdk/js/src/v2/gen/types.gen.ts,有 13,625 行;把它混进“核心手写逻辑规模”会失真。真正值得警惕的集中点是 session/prompt.ts 约 1,631 行、provider/provider.ts 约 2,068 行、lsp/server.ts 约 1,983 行:它们承载了大量协调逻辑,未来修改最容易牵动协议、状态和兼容层。
当前验证结果
本次使用与仓库声明一致的 Bun 1.3.14 安装依赖,bun install --frozen-lockfile 成功安装 4,693 个 package;packages/opencode 的 tsgo --noEmit 类型检查通过。发布包 v1.18.29 的 --version、根 --help、serve --help、attach --help、run --help 均已实际执行。
随后单独运行 session/compaction.test.ts、tool/task.test.ts、permission-task.test.ts,结果为 98 pass、1 skip、0 fail,285 次断言,耗时 29.51 秒。这些用例覆盖上下文溢出、尾部保留、旧工具输出裁剪、子 Agent 深度、权限派生、后台任务、父子取消传播等本文重点机制。完整 packages/opencode 测试也启动过,但运行约 3 分钟后没有留下最终汇总和可信退出码,因此不能宣称“全量测试通过”。
需要注意根目录 bun test 被项目明确设计为失败,并输出 do not run tests from root;正确入口是具体 workspace,例如 bun run --cwd packages/opencode test。测试结果必须以整个命令的退出码和最终汇总为准,不能因为某个后续文件的绿色输出就忽略前面的失败。
项目没有给出可复现的“比 Claude Code 快多少”一类 benchmark,因此本文不做速度、Token 节省或修复成功率对比。代码规模、类型检查、服务启动、健康检查和三组焦点测试,只能证明当前构建与控制面基础路径,不代表任意模型和仓库任务都能正确完成。
📖 README 核心内容摘要
README 把 OpenCode 定位为“The open source AI coding agent”,安装路径覆盖 npm/bun/pnpm/yarn、Homebrew、Scoop、Chocolatey、pacman、AUR、mise 和 Nix,并提供 macOS、Windows、Linux 桌面包。
默认交互里有两个主要 Agent:
build:面向实际开发,拥有完整工具能力;plan:只读分析模式,默认拒绝文件编辑,执行 shell 前询问。
另有用于复杂搜索和多步骤任务的 general 子 Agent,可在消息中通过 @general 调用。源码显示 Agent 不只是一段 system prompt,它还可以绑定 model、permission、mode、steps 等运行时属性。
README 安装示例很短:
npm install -g opencode-ai@latest
opencode
如果要固定到本文审计版本:
npm install -g opencode-ai@1.18.29
opencode --version
当前源码的 package.json、GitHub Release 和实际发布包三者都显示 1.18.29,版本面是一致的。源码默认分支是 dev,因此直接 clone 后看到的内容可能领先于某个旧安装包;生产使用更适合固定版本,而不是每天跟随 dev。
生态层面,OpenCode 同时提供:
| 集成 | 作用 |
|---|---|
| MCP | 接入外部工具和资源服务器 |
| ACP | 以 Agent Client Protocol 服务端方式被编辑器/客户端调用 |
| LSP | 为 Agent 提供语言语义与诊断能力 |
| Plugin | 扩展认证、工具、事件和 UI 行为 |
| JavaScript SDK | 调用会话、模型、事件、权限等 HTTP API |
| GitHub / PR 命令 | 拉取 PR 分支并进入 Agent 工作流 |
| Export / Import | 迁移或备份会话 JSON |
这些接口共享控制面,但信任边界不同:MCP Server 和插件可能执行第三方代码;LSP 会拉起语言服务进程;PTY 和 shell 直接接触系统;远程 HTTP 则增加网络认证问题。不能因为核心仓库采用 MIT License,就默认所有插件、模型和远程服务都同样可信。
🚀 快速上手
本地交互
npm install -g opencode-ai@1.18.29
mkdir opencode-demo && cd opencode-demo
git init
opencode
首次运行仍要配置可用的模型 provider 和凭据。OpenCode 不自带免费模型推理额度,开源的是 Agent 运行时,不是模型服务。
非交互任务可以这样运行:
opencode run --model provider/model \
"阅读当前项目,只总结构建命令和测试入口,不修改文件"
--model 的当前 parser 要求 provider/model 格式。为了让脚本消费事件,可以追加 --format json;需要继续上次会话时使用 --continue,指定已有会话则使用 --session <id>。
启动控制面并远程接入
export OPENCODE_SERVER_PASSWORD='replace-with-a-strong-password'
opencode serve --hostname 127.0.0.1 --port 4096
另一个终端:
opencode attach http://127.0.0.1:4096 \
--username opencode \
--password "$OPENCODE_SERVER_PASSWORD" \
--dir /path/to/project
健康检查:
curl -u "opencode:$OPENCODE_SERVER_PASSWORD" \
http://127.0.0.1:4096/global/health
如果跨机器使用,建议通过 SSH Tunnel、Tailscale 或受控反向代理转发,不要把无密码的 serve --hostname 0.0.0.0 直接暴露到公网。attach 提供的是客户端认证参数,不会替你配置 TLS、网络 ACL 或进程守护。
从源码验证
git clone --branch dev --depth 1 https://github.com/anomalyco/opencode.git
cd opencode
npx -y bun@1.3.14 install --frozen-lockfile
npx -y bun@1.3.14 run --cwd packages/opencode typecheck
npx -y bun@1.3.14 run --cwd packages/opencode test
最后一条是完整 workspace 测试,耗时和资源占用明显高于 CLI smoke test。不要在根目录直接运行 bun test,仓库脚本会故意退出 1,提醒贡献者选择具体 workspace。
📊 增长速度与社区热度
OpenCode 仓库创建于 2025-04-30。到 2026-09-07 API 核验时约 494.4 天、205,405 Stars,按公开仓库创建时间粗略摊平约 415 Stars/天。这个数字只是生命周期可见度基线,不能当作最近 24 小时增量。
9 月 6 日的本机快照在 18:07 记录 OpenCode 为 Trending #8,但没有保留它的总 Stars、Forks 和 today 增量。另一份同日公开归档在不同采样时刻记录它为 #5、552 stars today。Trending 会在一天内动态变化,因此本文保留本机快照的 #8 作为主排名,只把 +552 作为同日独立观测,不把两次采样拼成一个虚构的统一时点。
次日 API 数据显示 26,785 Forks、794 Watchers,仓库元数据的 open_issues_count 为 5,707。这个字段包含 open issues 和 open PR,不能直接解释为 5,707 个 Bug。GitHub 搜索另显示已合并 PR 约 8,636 个;贡献者接口至少有 5 页,首页前列包括 thdxr、adamdotdevin、rekram1-node、kitlangton 等。最近 30 天 commits 接口有 4 页,第一页 100 条中已出现 22 个不同作者标识,能确认项目仍处于高频开发。
最新 Release v1.18.29 发布于 2026-09-04;9 月 7 日 dev HEAD 的提交时间为当天 01:11(UTC-5),说明默认分支继续向前推进。对于依赖 CLI 参数或远程 API 的团队,固定 release、保留配置备份、升级前跑 help 和健康检查,比直接跟随 dev 更稳妥。
今日 GitHub Trending 完整榜单
下面是本机 2026-09-06 18:07 快照保存的全部 16 个仓库。该快照没有为非榜首仓库保留历史总 Stars/Forks/today 字段,因此表格只展示确定存在的排名、仓库和主语言。
| Rank | Repository | Language |
|---|---|---|
| 1 | mattpocock/skills | Shell |
| 2 | affaan-m/ECC | JavaScript |
| 3 | DietrichGebert/ponytail | JavaScript |
| 4 | cathrynlavery/diagram-design | HTML |
| 5 | NousResearch/hermes-agent | Python |
| 6 | fmtlib/fmt | C++ |
| 7 | anthropics/skills | Python |
| 8 | anomalyco/opencode | TypeScript |
| 9 | ruvnet/ruflo | TypeScript |
| 10 | humanlayer/skills | JavaScript |
| 11 | magnitudedev/magnitude | TypeScript |
| 12 | humanlayer/humanlayer | Go |
| 13 | nvm-sh/nvm | Shell |
| 14 | blader/humanizer | Python |
| 15 | BraveOPotato/FckSignups | CSS |
| 16 | bikini/exploitarium | Python |
🎯 适用场景
| 场景 | 为什么适合 | 需要注意 |
|---|---|---|
| 终端内日常编码 | TUI、LSP、shell、文件编辑和会话恢复都在一个工作流 | 模型质量与费用取决于 provider |
| CI/脚本自动化 | opencode run --format json 可输出结构化事件 | 必须限制权限,并用测试命令做确定性验收 |
| 远程开发机 | serve + attach 把 UI 和执行环境拆开 | 自己负责 TLS、认证、网络 ACL 和进程守护 |
| 多前端团队 | Web、Desktop、TUI、SDK 共用 HTTP 控制面 | API/CLI 版本要固定,避免客户端与 dev 漂移 |
| 大型代码库探索 | LSP、搜索、plan Agent、子会话和 compaction 减少单上下文压力 | 压缩会损失细节,关键结论应落到文件或测试 |
| 多模型评估 | Provider 层统一上层会话和工具事件 | 各模型的 tool/thinking/context 语义仍不完全一致 |
| 自定义 Agent 平台 | Plugin、MCP、ACP、SDK、OpenAPI 提供扩展入口 | 第三方插件和 MCP Server 扩大供应链风险 |
不太适合的情况也很明确:如果你只想要一个零配置、完全托管的 IDE 助手,OpenCode 的 provider、权限、服务和升级维护会显得更重;如果任务必须在强隔离环境执行,单独部署 OpenCode 还不够,需要把整个 server 放进容器、虚拟机或受限执行账号。
💡 总结
OpenCode 最值得借鉴的,不是“又一个会写代码的聊天框”,而是把编程 Agent 做成了可连接的控制面:客户端可以替换,模型可以切换,工具有权限规则,会话和工具状态落到 SQLite,子 Agent 有父子关系、深度限制、取消传播和后台结果回注,上下文溢出也有独立 compaction 路径。
它的代价同样真实。仓库有 6,620 个跟踪文件、超过 45 万行非测试非生成 TypeScript/TSX,核心 prompt、provider、LSP 文件已经很集中;默认分支更新快,Effect + AI SDK + 自研协议栈的调试门槛不低。权限系统也不是沙箱,远程 server 更不是开箱即用的安全云服务。
如果要把它用于真实项目,我会从固定 v1.18.29、临时工作区、默认 ask 权限和一个可执行测试门开始;确认模型、插件、MCP、远程目录和网络边界后,再逐步放开自动化。OpenCode 已经提供了 Agent 工程化所需的大部分控制面,但最终结果是否可信,仍要靠项目自己的构建、测试、评审和部署规则收口。