OpenCode 跑 code-reviewer 这个 Agent 时,真正决定能不能过鉴权的是请求里的 Key 和 Base URL。原文在 opencode.json 里给 code-reviewer 绑定了 anthropic/claude-sonnet-4-5,也写好了查 XSS/SQLi 和模块耦合的 prompt,剩下的问题只有一个:Key 从哪来。官方渠道在多 Key 环境里很容易把环境变量弄混,我干脆全走 TaoToken:先去 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 创建 API Key,再在 OpenCode 的 provider 配置里把 Base URL 指到 https://taotoken.net/api。下面按原文的目录节奏把这条路完整走一遍,保留 code-reviewer 的 prompt、tools 权限,只替换模型通道。
1. opencode.json 里 code-reviewer 的 model 字段决定鉴权走哪里
1.1 model 字段只决定找谁要答案,Key 和 Base URL 决定能不能进门
在原文的 opencode.json 中,code-reviewer 是 agent 对象下的一个实例,核心结构如下:
{ "$schema": "https://opencode.ai/config.json", "agent": { "code-reviewer": { "description": "专用于提供 Pull Request 级别代码审核工作的静态审查代理实例", "model": "anthropic/claude-sonnet-4-5", "prompt": "你被设定为严苛的代码质量审查算法实体。运算逻辑重点关注 XSS/SQLi 等安全防范、时间/空间复杂度性能损耗,以及模块的高内聚低耦合维护性分析。输出流规范:首先输出 200 字以内的缺陷统计摘要,然后按优先级倒序列举具体的 AST 优化或重构建议方案。", "tools": { "write": false, "edit": false, "bash": false } } } }这里 model 字段的完整值是 anthropic/claude-sonnet-4-5,它告诉 OpenCode 去哪个 provider 找哪个模型。OpenCode 启动后会按这个字段发起 LLM 请求,请求头里必须带上合法的 API Key,否则直接返回 401。同时工具侧 write、edit、bash 全被关掉,说明这个 Agent 只会读代码、给审查结论,不会擅自改文件,也不会在开发机上执行命令。对 PR 审查来说这是正确姿势:审查结果以文本形式输出,由你决定是否手动应用。
把 code-reviewer 理解为「一个只读的审查员」会有帮助。它在合并前帮你查 XSS、SQLi、模块耦合,但它自己不碰文件系统,也不跑编译命令。即使模型在回答里给出了一段修改代码,那段代码也只是 Markdown 文本,不会真的写入工作区。这种约束属于 OpenCode 的工具权限层,和模型通道是两个独立维度,后面换 Key 时不需要动它。
卡住请求的通常不是 prompt,而是 model、Key、Base URL 三者不匹配。比如本地环境变量里残留了另一个平台的 Key,OpenCode 会把请求发到默认 provider,结果 401;或者你想换一个模型跑审查,但 Key 只在该模型对应的平台上有效,切完之后同样 401。这类问题跟提示词写得好不好没关系,纯粹是通道配置的问题。
1.2 多 Key 切模型的成本,以及统一通道为什么能省掉这笔账
我的做法是把这层通道整个收敛到 TaoToken。TaoToken 在定位上是统一 API / 兼容通道,不是某个模型的官网,也不是破解入口。你在 opencode.json 里把 provider 的 Base URL 指成 https://taotoken.net/api,把 Key 换成在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 创建的 YOUR_API_KEY,code-reviewer 的 model 字段只要指向同一批模型 ID,就能复用同一把 Key。之后再新增 agent、mode 或者接 MCP 需要模型请求时,也继续用这把 Key,不用每个平台单独申请、单独维护。
注意一个最容易混的点:官网落地页和 API 接口是两个地址。浏览器打开的是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= ,用来注册、创建 Key、看模型广场和用量;填进 OpenCode 配置的是 https://taotoken.net/api ,末尾没有 /v1,也不要带 UTM 参数。后面所有示例都会严格区分这两个入口。
2. 从 TaoToken 拿 Key,把 opencode.json 的模型通道换过去
2.1 先去官网完成注册和创建 Key
准备材料和原文的流程一一对应:原文里打开官网、注册登录、获取 API Key 这些动作,现在换成打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 完成。注册后进入控制台的 API Keys 页面生成一把 Key,创建后立刻复制保存,页面刷新后就不会再完整显示。后面所有配置里出现的 YOUR_API_KEY 都替换成这把真实 Key。
如果你还没确定用哪个模型,可以在官网模型广场看一眼当时列出哪些模型 ID。这里不预设一个固定 ID 写死在文档里——模型市场上架情况会变化,一切以模型广场当时列表为准。原文里的 anthropic/claude-sonnet-4-5 如果还在列表里,code-reviewer 可以继续用它;如果已经换成了新版本,就把 agent 的 model 字段改成广场上对应的 ID。改的时候留意模型 ID 的拼写,多一个斜杠或少一个点都会在请求阶段变成 404。
2.2 在 opencode.json 里注册 TaoToken provider
在全局配置 ~/.config/opencode/opencode.json 或项目根目录的 opencode.json 中,通过 provider 对象把 TaoToken 注册成一个可用的模型通道。下面的配置保留了原文 code-reviewer 的权限设计和 prompt,只把模型通道换成 TaoToken:
{ "$schema": "https://opencode.ai/config.json", "provider": { "taotoken": { "npm": "@ai-sdk/anthropic", "name": "TaoToken", "options": { "baseURL": "https://taotoken.net/api", "apiKey": "YOUR_API_KEY" }, "models": { "anthropic/claude-sonnet-4-5": { "name": "Claude Sonnet 4.5" } } } }, "agent": { "code-reviewer": { "description": "专用于提供 Pull Request 级别代码审核工作的静态审查代理实例", "model": "taotoken/anthropic/claude-sonnet-4-5", "prompt": "你被设定为严苛的代码质量审查算法实体。运算逻辑重点关注 XSS/SQLi 等安全防范、时间/空间复杂度性能损耗,以及模块的高内聚低耦合维护性分析。输出流规范:首先输出 200 字以内的缺陷统计摘要,然后按优先级倒序列举具体的 AST 优化或重构建议方案。", "tools": { "write": false, "edit": false, "bash": false } } } }这里的 model 字段写法是taotoken/anthropic/claude-sonnet-4-5,前半段 taotoken 对应 provider 对象里的键名,后半段对应 models 里的模型 ID。OpenCode 解析到 agent 的 model 时,会先找到 taotoken 这个 provider,再拿着 baseURL 和 apiKey 去发请求。apiKey 字段里的 YOUR_API_KEY 是占位符,实际填写你在 TaoToken 控制台创建的那把 Key。
如果你不想把 Key 明文写进 opencode.json,也可以删掉 options.apiKey,改用你习惯的环境变量注入方式。无论用哪种方式,请求发出去时 OpenCode 都会把 https://taotoken.net/api 作为 API 入口。官网的注册与控制台是另一个入口,分开记,不要混着填。```json "options": { "baseURL": "https://taotoken.net/api" }
### 2.3 权限和 prompt 保持原样,不要为换 Key 额外放权 原文 code-reviewer 把 write、edit、bash 全部置为 false,这意味着它只能做静态阅读,不能对代码库执行写操作,也不能在容器里跑命令。换成新通道不改变这些限制,因为工具开关属于 OpenCode 的权限层,跟模型请求通道无关。所以你可以放心地把 prompt 里关于 XSS/SQLi、缺陷摘要、重构建议的要求原样保留。 第七节原文还提到 mode 级配置可以用 `{file:./prompts/code-review.txt}` 把超长 prompt 放到外部文件。这种宏展开发生在模型请求之前,不涉及网络鉴权,所以也不需要改动。唯一要确认的是 mode 或 agent 的 model 字段是否带上了 taotoken 前缀,否则 OpenCode 会拿着模型 ID 去默认的 provider 里找,又绕回原来的 Key。 ## 3. 用一份会主动犯错的样例代码跑通审查 ### 3.1 最小验证:一个带 innerHTML 和字符串拼 SQL 的小文件 配置保存后,别急着直接审查大仓库,先做一次最小验证。在项目里放一个故意带问题的文件,比如 src/pages/order.js: ```js function renderOrder(userInput) { document.getElementById("order-card").innerHTML = userInput; } function loadOrder(id) { const sql = "SELECT * FROM orders WHERE id = " + id; return db.query(sql); }这段代码有两个明显的审查点:innerHTML 直接拼用户输入会形成 XSS;字符串拼 SQL 存在注入风险。跑审查时先在终端启动 OpenCode,然后切到 code-reviewer 这个 agent,把目标文件喂进去,让它按原 prompt 的格式输出结果。如果一切正常,应该先看到类似「缺陷统计摘要:2 个问题,1 个 XSS、1 个 SQLi」的总述,再看到按优先级排序的重构建议。
第一次跑的时候建议开着一个小的终端窗口单独盯日志。OpenCode 在请求阶段会把 model、Base URL、Key 的鉴权结果打印到调试输出里。如果看到请求被拒绝,先不要怀疑 prompt 写得不对,按下面的顺序排查。
3.2 常见报错:401、404、Base URL 多写 /v1
最常撞上的是 401 Unauthorized。Key 填错、复制时带了空格、或者创建后没有替换成真实 Key 都会这样。回到刚才创建 Key 的官网控制台或模型对话页,重新生成一把 Key,再粘贴一次。如果用的是环境变量注入,还要确认环境变量已经重新加载,终端重启后再试。
第二个常见报错是 404。OpenCode 拿着 model 字段里的模型 ID 去请求模型服务,如果那个 ID 不在模型广场的当前列表里,接口会返回 404。不要凭记忆写模型 ID,更不要把别家平台的模型名原样搬过来。以官网模型广场当时显示的列表为准,必要时把 provider.models 里的键和 agent.model 的后半段同步改掉。
第三个和 Base URL 有关。有些人在 Anthropic 原生的地址后面加 /v1 加习惯了,但这里填的是 https://taotoken.net/api ,不要画蛇添足写成 https://taotoken.net/api/v1 。OpenCode 和底层 AI SDK 会按自己的路径规则拼接地址,多写 /v1 往往导致路径变成 /v1/v1,同样表现为 404。遇到 404 时先看 Base URL,再看 model ID,顺序不要反。
3.3 验证点:审查输出格式和只读权限是否生效
跑通之后,按原文的要求检查三点。第一点,输出是否先有缺陷统计摘要,再给优化建议;prompt 里写的「先摘要后建议」应当被严格遵守。第二点,code-reviewer 全程没有 write、edit、bash 调用,它只是读代码、输出 Markdown 结果;如果你在 TUI 里看到工具调用记录里出现了 bash,说明配置没生效,回去看 tools 布尔值。第三点,整次请求在控制台的用量记录里能查到,说明模型请求确实走了你配的这把 Key。
这三点都过,说明 code-reviewer 已经从「配好了」变成「能跑了」。剩下的问题才是真正把审查接到 PR 流程里:让它在合并前读取 diff 文件,输出摘要卡片,并把严重缺陷标成红色级别。输出格式已经由 prompt 约束好,模型通道稳定,后面的流程就只是工程问题。
4. 同一个 TaoToken Key 在新增 agent、mode、MCP 里如何复用
4.1 新增 agent 时复用同一个 provider
后续在 opencode.json 里加新的 agent,不需要再复制 provider 配置。只需要在 agent 对象里加上新名字,model 写成 taotoken/ 前缀即可。比如加一个专门维护 CHANGELOG 的 agent,model 同样以模型广场的列表为准,prompt 换成它自己的职责描述,Key 还是原来那一把。这样多 agent 体系只维护一个 Key,不会出现 A agent 能用、B agent 用另一个平台的 Key 然后 401 的分裂状态。
如果你要把 code-reviewer 同时用在多个项目里,就把 provider 配置放到全局 opencode.json,而不是每个项目各写一份。项目级配置里只保留 agent 和 prompt 的差异。这样某个模型被下架或者 Key 需要轮换时,只改全局一个文件,所有项目同步生效。
4.2 mode 级配置也走同一个通道
原文还定义了 mode.review 这种模式级配置,用{file:./prompts/code-review.txt}把超长 prompt 放到外部文件。模式级的 model 如果不单独写,默认会走 agent 或全局的 provider;如果你在某个 mode 里单独指定模型,记得同样以 taotoken/ 作为前缀。mode 和 agent 的区别在应用范围:agent 是角色,mode 是工作状态,但它们发起 LLM 请求时用的是同一个 provider 注册表。
这里提醒一句:mode 级配置里的 prompt 文件路径是相对于当前工作目录的。如果你把项目克隆到另一台机器,prompts 目录没有一并提交,OpenCode 会在加载阶段报文件缺失,跟模型通道无关。处理方式是把 prompts 目录提交进 Git,或者在 README 里写清楚路径要求。这不是 TaoToken 的问题,但排查时容易被误认为是请求失败。
4.3 MCP 的模型请求与 MCP 服务自身鉴权要分清
OpenCode 的 MCP 配置是另一套入口。原文里的 mcp 对象可以挂远程服务或本地子进程,MCP 服务器的地址、headers 属于服务自己的鉴权,和模型 Key 不是一回事。当 agent 通过 MCP 工具拿回上下文,再用模型做分析时,模型请求依然走 provider 里配的 Base URL 和 Key。也就是说,配置的这把 Key 负责「模型对话通道」,MCP 服务如果要求鉴权,应当在 MCP 的 headers 或命令参数里配它自己的凭证。
如果接的是本地 MCP 服务,比如一个读取 Git 仓库元数据的脚本,通常不需要额外 token;如果接的是远程服务,不要在 opencode.json 里硬编码生产环境的 Bearer Token。把包含敏感信息的文件加进 .gitignore,或者使用环境变量注入。原文对这一点已经给出过警戒,这里再强调一次:模型 Key 和 MCP token 分开管理,泄露面会小很多。
4.4 跑完看看用量,再决定要不要长期用
到这里,code-reviewer 已经在 OpenCode 里完整跑通,而且同一把 Key 可以继续服务后续新增的 agent、mode 和 MCP 场景。回到 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 控制台,看这次 PR 审查消耗的 Token 数;如果每个 PR 都要过一遍 XSS/SQLi 检查,长期用量会稳定上涨,建议打开 Coding Plan 评估套餐。要创建新 Key 或轮换旧 Key,去 控制台 API Keys 操作。想确认某条消息能正常返回,可以用 模型对话 当探针,发一条和审查 prompt 接近的测试消息,直接看摘要格式对不对。
如果以后把同一把 Key 用到 Claude Code 或者其他命令行工具,TaoToken 也有对应的 Claude Code 接入文档 可以对照。让 code-reviewer 真正变成合并前的常驻门禁,把每次审查的摘要贴回 PR 评论区,这套配置就算闭环了。