1. 为什么我把 opencode 的项目规划、测试、审查串成了一条线
opencode 是一个跑在终端里的 AI 编码代理,能读你的仓库、改文件、跑命令,适合把「项目规划、测试补全、代码审查」这三件重复度极高的事交给它。但很多人卡在第一步:每个阶段都要单独配一次模型通道,Key 散落在环境变量、配置文件、CI 里,换一个模型就要改一遍,最后干脆放弃。
我这次的做法是:用 TaoToken 统一 Key 和 API 通道,让 opencode 的规划、测试、审查三个阶段共用同一套接入配置。TaoToken 是一个聚合式 AI 模型 API 服务,官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,它把多家模型的调用收敛成一个 OpenAI 兼容入口,opencode 只要认这个入口,就能在三个阶段里自由切换模型,而不用动业务代码。
这篇文章适合三类人:一是已经在用 opencode 但配置总是打架的开发者;二是想把 AI 拉进真实项目流程、又不想被 Key 管理拖累的团队;三是刚接触 opencode、想找一个能直接复制的落地骨架的人。下面我会给出可复制的 config.toml 骨架、settings.json 片段,以及规划、测试、审查三步的验证动作,每一步都有命令和预期结果,照着做就能复现。
2. TaoToken 前置:先把统一 Key 和 API 通道准备好
2.1 注册与拿 Key
打开 https://taotoken.net/api 这个 API 入口页,注册后进入控制台。控制台地址是 https://taotoken.net/console ,登录后左侧找「API Keys」,新建一个 Key。建议按用途拆:一个给本地 opencode 用,一个给 CI 用,方便出问题时单独吊销。
拿到 Key 后先别急着写进项目,先在终端验证一次通道是否通:
curl https://taotoken.net/api/v1/models \ -H "Authorization: Bearer $TAOTOKEN_API_KEY"返回里能看到可用模型列表,说明 Key 和通道都正常。这一步很关键,因为后面 opencode 报错时,你要能区分是「Key 问题」还是「opencode 配置问题」。
2.2 为什么用统一 Key 而不是每个阶段单独配
opencode 的规划阶段可能想用推理强的模型,测试阶段想用代码补全快的,审查阶段想用上下文长的。如果每个阶段都单独配 Key 和 base_url,配置文件会迅速膨胀,而且模型切换时容易漏改。TaoToken 的做法是:所有阶段都指向同一个 base_url,只在模型名上做区分。这样你只需要维护一份接入配置,模型选择变成配置里的一个字段。
注意:不要把 Key 硬编码进 config.toml 或 settings.json 后提交到仓库。用环境变量注入,配置文件里只写变量名。
3. 可复制配置:config.toml 骨架与 settings.json 片段
3.1 opencode 的 config.toml 骨架
opencode 读取项目根目录或用户目录下的 config.toml。下面这份骨架把 provider 指向 TaoToken 的 OpenAI 兼容入口,并预置了三个阶段用的模型别名:
# config.toml [provider.taotoken] type = "openai" base_url = "https://taotoken.net/api/v1" api_key_env = "TAOTOKEN_API_KEY" [provider.taotoken.models] planner = "claude-sonnet-4-20250514" tester = "gpt-4.1" reviewer = "claude-sonnet-4-20250514" [agent] default_provider = "taotoken" default_model = "planner" [agent.plan] provider = "taotoken" model = "planner" [agent.test] provider = "taotoken" model = "tester" [agent.review] provider = "taotoken" model = "reviewer"这里api_key_env指向环境变量,而不是直接写 Key。base_url用https://taotoken.net/api/v1,这是 OpenAI 兼容路径,opencode 的 openai 类型 provider 能直接识别。
3.2 settings.json 配置片段
如果你用的是带 settings.json 的编辑器侧集成,或者 opencode 的某些插件读取 settings.json,可以加这一段:
{ "opencode.providers": { "taotoken": { "type": "openai", "baseUrl": "https://taotoken.net/api/v1", "apiKeyEnv": "TAOTOKEN_API_KEY", "models": { "planner": "claude-sonnet-4-20250514", "tester": "gpt-4.1", "reviewer": "claude-sonnet-4-20250514" } } }, "opencode.agent": { "defaultProvider": "taotoken", "defaultModel": "planner" } }3.3 环境变量注入
在 shell 里设置,或者写进.env后由启动脚本加载:
export TAOTOKEN_API_KEY="你的Key"如果你用 direnv,可以在项目根目录放.envrc:
export TAOTOKEN_API_KEY="你的Key"然后direnv allow。这样每次进项目目录自动注入,不用手动 export。
4. 三步验证:规划、测试、审查各跑一次
4.1 规划阶段:生成任务拆解
进入你的项目目录,启动 opencode:
opencode在会话里输入:
我有一个项目想法:做一个在线笔记应用。 请分析需求,生成功能清单、技术选型建议,并拆成带优先级和依赖关系的任务清单。 保存为 docs/plan.md 和 docs/tasks.md。预期结果:opencode 会在docs/下生成两个文件。plan.md里应该有核心功能模块(用户系统、笔记管理、协作、高级功能)和技术选型;tasks.md里应该是带优先级、预计工时、依赖关系的任务表。如果只生成了一个文件,或者任务清单没有依赖关系,说明模型没按格式输出,可以在 prompt 里补一句「用 Markdown 表格输出,列包含任务名、优先级、工时、依赖」。
这一步验证的是:TaoToken 通道是否通、planner 模型是否可用、opencode 是否能写文件。
4.2 测试阶段:补全用例
接着在同一个会话里输入:
基于 docs/tasks.md 里的任务,为 notes 模块生成 pytest 测试用例。 要求: 1. 覆盖创建、读取、更新、删除、搜索五个场景 2. 使用 pytest-asyncio 3. 遵循 AAA 模式 4. 保存为 tests/test_notes.py预期结果:tests/test_notes.py生成,里面应该有五个测试函数,每个都有 arrange、act、assert 三段。然后运行:
pytest tests/test_notes.py -v如果测试通过,说明 tester 模型生成的代码可执行;如果失败,把报错贴回 opencode,让它修。这一步验证的是:tester 模型是否可用、生成的测试是否能跑。
4.3 审查阶段:输出 diff 建议
在会话里输入:
审查 src/ 目录下的所有 Python 文件,检查: 1. PEP8 规范 2. 类型注解完整性 3. 安全漏洞(SQL 注入、明文密码等) 4. 性能问题(N+1 查询等) 输出审查报告,按高/中/低优先级分组,每条给出文件行号和修复建议。预期结果:opencode 输出一份审查报告,高优先级问题里应该能看到类似「SQL 注入风险」「密码明文存储」这类条目,每条带文件路径和行号。如果报告里只有笼统描述没有行号,说明模型没读文件内容,可以在 prompt 里明确「先读取文件再审查」。
这一步验证的是:reviewer 模型是否可用、opencode 是否能读多文件并给出结构化建议。
5. 本篇常见错排查
5.1 401 Unauthorized
最常见的原因是环境变量没注入。先确认:
echo $TAOTOKEN_API_KEY如果为空,说明 shell 没加载。检查.envrc是否direnv allow,或者手动source .env。如果变量有值但还是 401,去控制台确认 Key 是否被吊销或过期。
5.2 404 Not Found
base_url 写错是主因。opencode 的 openai 类型 provider 需要 base_url 以/v1结尾。确认 config.toml 里是https://taotoken.net/api/v1,不是https://taotoken.net/api。后者是入口页,不是 API 路径。
5.3 模型名不识别
如果你在 config.toml 里写的模型名不在 TaoToken 的可用列表里,会报 model not found。先用第 2.1 节的 curl 命令拉一次模型列表,把返回里的模型名复制进配置。不要凭记忆写。
5.4 opencode 不读 config.toml
opencode 的配置查找顺序是:项目根目录 > 用户目录。如果你在项目根目录放了 config.toml 但没生效,检查文件名是否拼错(是 config.toml 不是 config.yaml),以及是否在正确的目录启动 opencode。可以在会话里输入/config查看当前加载的配置。
5.5 测试阶段生成的用例跑不起来
常见原因是缺少 fixture 或依赖。先看报错是 ImportError 还是 AssertionError。ImportError 说明生成的测试引用了不存在的模块,让 opencode 补 conftest.py;AssertionError 说明测试逻辑和实现不匹配,把实现代码贴给 opencode 让它对齐。
6. 把三个阶段串成日常流程
配置好之后,我自己的日常是这样跑的:早上进项目,先让 opencode 读一遍昨天的 diff,生成当天的任务拆解;写完代码后,让 tester 模型补测试并跑一遍;提交前,让 reviewer 模型审查改动文件,只输出高优先级问题。三个阶段共用同一个 Key 和 base_url,切换模型只改 config.toml 里的一个字段。
如果你主要做长期编码和 Agent 任务,可以看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。如果只是想先验证模型对话效果,用模型对话入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。接入过程中遇到报错,先查 API Keys 和接入文档:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 和 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。
最后补一个我踩过的坑:opencode 在审查阶段如果一次读太多文件,上下文会爆。我的做法是分目录审查,先src/models/,再src/routers/,每次只让 reviewer 看一个目录。这样报告更细,也不会因为上下文截断漏掉问题。