1. 为什么要在 OpenCode 里区分 Plan 和 Build
OpenCode 的 Plan / Build 双模式,本质是权限隔离,不是「简易版 / 完整版」的区别。Plan 模式只读规划:能读全部代码、搜索、分析架构、输出实施计划,只允许写.opencode/plans/*.md计划文档,禁止 write/edit/patch 改源码,也禁止执行 bash。Build 模式是完整权限代理:读写编辑新建文件、打补丁、跑 shell、跑测试、装依赖,直接改项目源码。
这个设计对本地开发者很友好:复杂重构先让 AI 出方案,你审阅确认后再切 Build 落地,避免 AI 乱改业务代码。但问题也出在这里——两个模式的工具权限不同,接入统一 Key/API 通道时,如果settings.json没配对,就会出现「Plan 能聊不能写计划」「Build 鉴权失败」「切了模式不生效」这类问题。
我试过把 OpenCode 接到 TaoToken 的统一通道上,Plan 和 Build 共用一套 Key,配置骨架其实不复杂,坑主要在字段层级和模式覆盖上。下面按「前置准备 → 配置骨架 → 验证 → 排障」的顺序走一遍,你可以直接抄。
2. TaoToken 前置:拿 Key、认通道、选对入口
TaoToken 在这里的角色是统一 Key/API 通道:你不需要为 Plan 和 Build 分别维护两套凭证,一个 Key 走同一个 base URL,模型和模式由 OpenCode 侧决定。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api (这个不加 UTM,配置里就写它)。
先做三件事:
第一,在控制台创建 API Key。入口走 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,创建后立刻复制,页面刷新后不再完整显示。Key 形如sk-开头的一串字符,后面配置里用环境变量引用,不要硬编码进仓库。
第二,确认你要用的模型名。OpenCode 的 Plan 和 Build 可以指向同一个模型,也可以分开。建议先用同一个模型跑通链路,再按需拆分。模型对话页可以用来快速验证 Key 是否可用:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
第三,如果你打算长期用 OpenCode 做编码和 Agent 任务,Coding Plan 比按量更省心,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,字段含义以文档为准。
注意:Key 只放环境变量,
settings.json里用${TAOTOKEN_API_KEY}这种引用形式。OpenCode 读取配置时会做变量展开,写死明文一旦提交就是事故。
3. settings.json 骨架:Plan / Build 共用通道
OpenCode 的配置文件按优先级分全局和项目级。全局一般在~/.config/opencode/settings.json,项目级在项目根目录.opencode/settings.json。项目级覆盖全局,模式相关的覆盖写在项目级更稳。
下面是一份可直接复制的骨架,核心是把 provider 指向 TaoToken 的 API 基址,然后给 Plan 和 Build 分别声明模型与权限:
{ "provider": { "taotoken": { "type": "openai-compatible", "baseURL": "https://taotoken.net/api", "apiKey": "${TAOTOKEN_API_KEY}", "models": { "default": { "name": "your-model-name", "contextWindow": 128000 } } } }, "model": "taotoken/default", "modes": { "plan": { "model": "taotoken/default", "tools": { "write": false, "edit": false, "patch": false, "bash": false }, "allowedWritePaths": [".opencode/plans/**"] }, "build": { "model": "taotoken/default", "tools": { "write": true, "edit": true, "patch": true, "bash": true } } } }几个字段说明一下。type用openai-compatible,因为 TaoToken 提供的是兼容 OpenAI 协议的接口,OpenCode 走这个类型最省事。baseURL结尾不要带/v1,OpenCode 会自己拼路径,多写一层会 404。apiKey用环境变量引用。modes.plan.allowedWritePaths是 Plan 模式唯一放行的写入目录,对应.opencode/plans/*.md,别把它删了,否则 Plan 连计划文档都存不下来。
环境变量在 shell 里导出:
export TAOTOKEN_API_KEY="sk-你的Key"想持久化就写进~/.zshrc或~/.bashrc,然后source一下。Windows 用系统环境变量面板,或者 PowerShell 里$env:TAOTOKEN_API_KEY="sk-..."。
提示:如果你在项目级和全局都写了
provider,项目级会整体覆盖同名 provider,不是深合并。要么只写一处,要么两处字段保持完整。
4. 验证请求:Plan 出计划、Build 改代码
配置写完先别急着上复杂任务,用最小用例验证两种模式都能通。
第一步,启动 OpenCode,确认它读到了配置。在项目根目录执行:
opencode进入交互界面后,先看模型标识是不是taotoken/default。如果显示的是别的模型,说明model字段没生效,回去检查 JSON 有没有语法错误——OpenCode 对 JSON 容错很低,多一个逗号就整段忽略。
第二步,切到 Plan 模式。快捷键Tab循环切换,或者直接输入斜杠命令:
/plan 重构用户登录模块,列出所有改动文件,说明风险点预期结果是:AI 读取相关文件、分析依赖、输出一份 markdown 计划,落到.opencode/plans/下。你可以打开那个文件确认内容。如果 AI 试图改源码,说明tools.write没关掉,Plan 的权限隔离没生效。
第三步,审阅计划。方案不对就继续对话修正,Plan 模式下改计划文档是允许的。确认无误后切 Build:
/build 执行刚才这份计划预期结果是:AI 按计划改源码、跑命令、可能装依赖。这一步如果报鉴权失败,问题在 Key 或 baseURL,不在模式配置。
第四步,跑测试验证结果。Build 完成后执行项目自带的测试命令,比如npm test或pytest,确认改动没破坏功能。
整个链路跑通后,你会看到 Plan 产出的是.opencode/plans/*.md,Build 产出的是真实源码变更。两者共用同一个 Key,但工具权限完全不同。
5. 常见报错排查:鉴权失败与模式不生效
5.1 鉴权失败(401 / 403)
报错长这样:401 Unauthorized或invalid api key。按顺序查:
先确认环境变量真的导出了。echo $TAOTOKEN_API_KEY看有没有值,为空说明 shell 没加载。再确认settings.json里写的是${TAOTOKEN_API_KEY}而不是别的变量名,大小写要一致。
然后查 baseURL。必须是https://taotoken.net/api,结尾不带/v1,不带斜杠。写成https://taotoken.net/api/v1会拼成/api/v1/chat/completions之外的路径,直接 404 或 401。
最后确认 Key 本身有效。去模型对话页发一条消息,如果那边也失败,就是 Key 的问题,重新在控制台创建一个。如果那边正常、OpenCode 失败,就是配置引用的问题。
5.2 模式不生效(切了 Plan 还能写代码)
现象是:/plan之后 AI 依然改源码。原因通常是modes字段没被识别。检查两点:
一是modes的层级。它必须在顶层,和provider、model平级,不能塞进provider里面。二是模式名拼写,必须是plan和build,小写。写成Plan或Planning都不会匹配。
还有一种情况:项目级配置覆盖了全局,但项目级只写了provider没写modes,导致模式配置丢失。解决办法是把modes也补进项目级,或者干脆只维护一份配置。
5.3 Plan 存不下计划文档
报错类似permission denied writing .opencode/plans/xxx.md。这是allowedWritePaths没配或路径写错。确认值是[".opencode/plans/**"],双星号表示递归匹配。另外确认.opencode/plans/目录存在,不存在就手动建一个:
mkdir -p .opencode/plans5.4 切换后模型没变
如果你给 Plan 和 Build 配了不同模型,切换后没生效,检查modes.plan.model和modes.build.model是否都写了完整标识taotoken/模型名。只写模型名不写 provider 前缀,OpenCode 可能回退到默认模型。
注意:改完
settings.json要重启 OpenCode 会话,热重载不一定覆盖所有字段。这是最容易忽略的一步。
6. 把两种模式用顺手的几个习惯
Plan 文档会持久保存在.opencode/plans/,这其实是白送的项目开发文档。复杂改动前先/plan,把方案和风险点留档,过几周回头看改动思路一目了然。小改动比如改配置、修单函数 bug,直接 Build 就行,不用走 Plan,省一轮交互。
如果你长期用 OpenCode 跑编码和 Agent 任务,建议把 Coding Plan 配上,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,比按量调用更可控。Key 的管理统一在 API Keys 页面:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,接入字段有疑问就翻文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
最后提醒一句:Plan 和 Build 共用一套 Key 没问题,但别把 Build 的完整权限当成默认工作流。先 Plan 后 Build,让 AI 的方案先过你的眼,这才是这套双模式真正值钱的地方。