1. 为什么需要 Oh My OpenCode:多代理协作的真实痛点
如果你最近在折腾 AI 编程工具,大概率会遇到一个尴尬局面:Claude Code 写前端很稳,但让它做深度重构就容易跑偏;GPT 系列逻辑强,可一旦涉及 UI 细节就开始糊弄;本地想接个 MCP 工具查文档,配置半天还报local proxy failed。工具越装越多,效率反而被切碎了。
Oh My OpenCode(仓库名 oh-my-openagent)想解决的就是这件事。它是一个基于 OpenCode 平台的 TypeScript 插件,核心能力是把 Claude、GPT、Kimi、GLM、Gemini 这些模型编排成一支"开发小队",每个代理负责自己最擅长的环节。你只需要输入ultrawork,系统就会自动规划、分派、并行执行,直到任务完成。
它适合谁?三类人最值得试:一是已经在用 Claude Code、但想让多个模型协同干活的开发者;二是想接入 MCP 工具链、又不想手动管理一堆配置的人;三是做多模块项目、希望 AI 能持续工作而不是干一半就停的团队。这篇我会从零跑通一个多代理协作示例,包含可复制的代理配置、MCP 注册步骤,以及用 Claude Code 验证整条编排链路的操作。
先说清楚一个前提:Oh My OpenCode 本身不提供模型,它是个编排层。你需要有模型 API 的访问能力,而统一管理这些 Key、方便切换模型,可以用 TaoToken 这类聚合入口来简化配置。下面进入实操。
2. 前置准备:TaoToken 接入与 OpenCode 环境搭建
在写代理配置之前,得先把"模型从哪来"这件事解决。Oh My OpenCode 要调用多个模型,如果每个模型都单独去申请 Key、单独配 Base URL,配置文件会变得非常难维护。我的做法是统一走一个兼容 OpenAI 协议的入口,把模型 ID 集中管理。
TaoToken 的 API 地址是https://taotoken.net/api,兼容 OpenAI 的/v1/chat/completions格式。你需要在控制台生成一个 API Key,然后把它作为环境变量注入,而不是硬编码进配置文件。这样做的好处是:切换模型时只改 Model ID,不用动 Key。
第一步,设置环境变量。在~/.zshrc或~/.bashrc里加一行:
export TAOTOKEN_API_KEY="sk-你的实际Key"然后source ~/.zshrc让它生效。验证一下:
echo $TAOTOKEN_API_KEY能打印出 Key 就说明环境变量没问题。
第二步,确认 OpenCode 已安装。Oh My OpenCode 是 OpenCode 的插件,所以底座必须先就绪:
opencode --version如果提示 command not found,先去 OpenCode 官方文档装好再回来。Node.js 建议 18 以上,包管理器推荐 Bun,因为项目自带bun.lock和bunfig.toml。
第三步,理解配置文件的层级。Oh My OpenCode 支持两级配置:项目级放在.opencode/oh-my-opencode.jsonc,用户级放在~/.config/opencode/oh-my-opencode.jsonc。项目级优先级更高,适合团队共享;用户级适合放个人偏好。JSONC 格式允许写注释和尾随逗号,这点对写复杂配置很友好。
这里有个容易踩的坑:很多人把 API Key 直接写进oh-my-opencode.jsonc,然后提交到了 Git。正确做法是配置文件里只写"apiKeyEnv": "TAOTOKEN_API_KEY"这种引用,真实 Key 留在环境变量里。这样配置可以安全地进版本库。
环境就绪后,我们进入核心部分——代理编排配置。
3. 可复制的代理编排配置:JSONC 片段与 MCP 注册
Oh My OpenCode 的编排逻辑围绕几个核心代理展开:Sisyphus 是总指挥,负责规划和任务分派;Hephaestus 是深度执行者,适合端到端研究型任务;Prometheus 是规划师,在动手前做需求访谈。你要做的是告诉系统:每个代理用哪个模型、走哪个 Base URL、并发上限是多少。
下面是一份可以直接改用的~/.config/opencode/oh-my-opencode.jsonc片段。注意路径要和你的实际环境一致:
{ // 统一模型入口,所有代理默认走这里 "providers": { "taotoken": { "baseURL": "https://taotoken.net/api", "apiKeyEnv": "TAOTOKEN_API_KEY", "type": "openai-compatible" } }, // 代理级别的模型映射 "agents": { "sisyphus": { "provider": "taotoken", "model": "claude-opus-4-6", "temperature": 0.3, "role": "orchestrator" }, "hephaestus": { "provider": "taotoken", "model": "gpt-5.3-codex", "temperature": 0.2, "role": "deep-worker" }, "prometheus": { "provider": "taotoken", "model": "kimi-k2.5", "temperature": 0.5, "role": "planner" } }, // 类别驱动的路由:任务类型 -> 代理 "categories": { "visual-engineering": { "agent": "hephaestus", "model": "claude-opus-4-6" }, "deep-research": { "agent": "hephaestus", "model": "gpt-5.3-codex" }, "quick-fix": { "agent": "sisyphus", "model": "glm-5" }, "complex-logic": { "agent": "sisyphus", "model": "claude-opus-4-6" } }, // 后台任务并发控制,防止触发速率限制 "backgroundTasks": { "globalLimit": 5, "perProvider": { "taotoken": 5 } } }这份配置的关键点有三个。第一,providers里定义了统一的baseURL和apiKeyEnv,所有代理共享,改一处即可全局生效。第二,agents里给每个代理指定了 Model ID,这里填的是示例 ID,你要换成 TaoToken 控制台里实际可用的模型名。第三,categories实现了"任务类别 → 代理 → 模型"的三级路由,Sisyphus 分派任务时选的是类别,不是模型,这样路由逻辑和模型解耦,换模型不用改业务逻辑。
接下来是 MCP 服务注册。MCP(Model Context Protocol)让代理能调用外部工具,比如查文档、搜代码。Oh My OpenCode 内置了 Exa、Context7、Grep.app 三个 MCP 服务器,但如果你想接自己的 MCP,需要在配置里注册。下面是一个自定义 MCP 的注册片段:
{ "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"], "enabled": true }, "my-docs": { "command": "node", "args": ["./mcp/my-docs-server.js"], "env": { "DOCS_ROOT": "./docs" }, "enabled": false } } }command和args是启动 MCP 服务的命令,enabled控制是否随会话启动。这里有个设计亮点:Oh My OpenCode 支持"技能自带 MCP",也就是 MCP 按需启动、任务结束就关闭,不会一直占用上下文窗口。这对长会话特别重要,否则上下文很快就被工具描述塞满了。
配置写完后,用opencode启动,插件会自动加载。如果配置有语法错误,启动时会报failed to parse config,这时候检查 JSONC 的括号和逗号即可。
4. 验证编排链路:用 Claude Code 跑通多代理协作
配置就绪后,最关键的一步是验证整条链路真的通了。我建议分三层验证:先验证单个模型能通,再验证代理能启动,最后验证多代理协作。
第一层,验证模型连通性。用 curl 直接打 TaoToken 的接口,确认 Key 和 Base URL 没问题:
curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-opus-4-6", "messages": [{"role": "user", "content": "回复 OK 两个字母"}] }'如果返回里有choices字段和正常内容,说明模型侧通了。如果报 401,说明 Key 有问题;如果报model not found,说明 Model ID 写错了,去控制台核对。
第二层,验证代理启动。在项目目录下启动 OpenCode,然后输入:
ultrawork 在当前目录创建一个 hello.ts,输出 Hello OpenCode正常情况下,你会看到 Prometheus 先进入访谈模式,问你要不要用 TypeScript 严格模式、要不要加测试。回答后,Sisyphus 接管,分派任务,最后文件被创建。这个过程你能在终端看到代理的思考流。
第三层,验证多代理协作和 MCP。给一个稍微复杂的任务:
ultrawork 给 hello.ts 加一个函数,读取 package.json 的 name 字段并打印,然后写一个对应的测试这个任务会触发类别路由:读文件属于深度研究,写测试属于复杂逻辑。你会看到不同代理被激活,MCP 工具(如果配了 Context7)可能被调用来查 Node.js 文档。
如果你用的是 Claude Code 作为前端入口,想让它调用 Oh My OpenCode 编排好的代理,可以在 Claude Code 的配置里把 Base URL 指向同一个入口,Model ID 填 Sisyphus 对应的模型。这样 Claude Code 负责交互,Oh My OpenCode 负责后端编排。验证方法是:在 Claude Code 里发一个需要多步的任务,观察是否有多代理的并行输出。
实测下来,最容易出问题的是并发限制。如果你把globalLimit设得太高,比如 20,而 API 侧有速率限制,就会看到大量429 Too Many Requests。这时候把perProvider降到 3 到 5 之间,稳定性会明显提升。
5. 常见报错排查:401、local proxy failed 与 OAuth 问题
编排链路跑起来后,报错是难免的。我把几个高频错误和排查路径整理出来,对照着看能省不少时间。
401 Unauthorized。这个最常见,八成是 Key 没生效。排查顺序:先echo $TAOTOKEN_API_KEY确认环境变量在当前 shell 里存在;再确认配置文件里写的是apiKeyEnv而不是把 Key 写死在apiKey字段;最后确认 Base URL 结尾没有多余的斜杠,https://taotoken.net/api和https://taotoken.net/api/在某些客户端里行为不一致。如果都对了还报 401,去控制台看 Key 是否被禁用或额度耗尽。
local proxy failed。这个错误通常出现在 MCP 服务启动失败时。MCP 是通过本地子进程启动的,如果command指向的可执行文件不存在,或者args里的包没装,就会报这个。排查方法:把command和args拼成一条命令,在终端里手动跑一遍。比如npx -y @upstash/context7-mcp,看是否能正常启动。如果报模块找不到,先npm install -g装上。另外,enabled: true的 MCP 如果启动超时,也会触发这个错误,可以先把非必要的 MCP 设为false逐个排除。
reading choices 相关报错。类似cannot read property 'choices' of undefined,这通常是响应格式不符合预期。原因可能是 Base URL 指向了一个不兼容 OpenAI 格式的端点,或者模型返回了错误结构。排查:用第 4 节的 curl 命令直接打接口,看返回的 JSON 顶层有没有choices。如果没有,说明这个端点不是 OpenAI 兼容格式,需要换入口。另外,如果 Model ID 填了一个不存在的模型,有些网关会返回一个错误对象而不是标准响应,也会导致这个报错。
OAuth 相关错误。如果你在配置里用了需要 OAuth 的模型提供商,可能会看到OAuth token expired或invalid_grant。Oh My OpenCode 支持 OAuth 流程,但 token 需要定期刷新。排查:检查~/.config/opencode/下的凭证缓存文件是否过期,删掉后重新走一次授权流程。如果你用的是 API Key 模式(像 TaoToken 这样),就不会遇到 OAuth 问题,这也是我推荐 API Key 入口的原因之一——少一层授权状态管理。
代理不工作 / 任务卡住。有时候配置没问题,但代理启动后一直不动。这通常是categories里的类别名和任务实际匹配不上,导致路由失败。排查:把temperature临时调低,让 Sisyphus 的输出更确定;或者在配置里加一个default类别兜底:
"categories": { "default": { "agent": "sisyphus", "model": "claude-opus-4-6" } }这样即使类别没匹配上,也有代理接手。
哈希锚定编辑被拒绝。如果你看到hash mismatch, edit rejected,这不是 bug,是保护机制。说明文件在代理读取后被外部修改了。解决办法:让代理重新读取文件再编辑,或者确认没有其他进程在同时改这个文件。这个机制虽然偶尔打断流程,但它避免了"基于陈旧内容编辑"导致的代码损坏,长期看是值得的。
6. 从编排到落地:把多代理协作接入你的日常开发
跑通示例只是开始,真正有价值的是把它变成日常习惯。我自己的用法是:把 Oh My OpenCode 当成一个"任务路由器",而不是一个聊天窗口。遇到一个需求,先想清楚它属于哪类任务,然后用ultrawork描述目标,让系统去决定用哪个模型、开几个代理。
对于长期编码和 Agent 类任务,建议用 Coding Plan 来管理额度,避免按次调用带来的成本波动。如果你主要想验证某个模型的表现,可以直接在模型对话里试;而接入和排障相关的文档,都在接入文档里能找到。这几个入口分工明确:验证模型走对话,长期编码走套餐,配置问题查文档。
有几个实践细节值得注意。第一,/init-deep命令值得在项目初期就跑一次,它会生成分层的AGENTS.md,让代理理解项目结构,后续任务的准确率会明显提升。第二,技能权限要收窄,比如 Git-Master 技能默认能执行提交和变基,如果你不希望代理自动提交,就在配置里限制它的权限范围。第三,定期清理会话历史,长会话的上下文膨胀会拖慢响应,也会增加成本。
最后说一个我踩过的坑:一开始我把所有代理都指向同一个最强模型,结果成本和延迟都上去了,效果却没有更好。后来按类别拆分,快速修复用轻量模型,复杂逻辑用强模型,整体吞吐反而提升了。编排的价值不在于用最强的模型,而在于让合适的模型做合适的事。你可以先从两三个代理开始,跑顺了再逐步扩展。