1. 为什么你的 Agent 总是“原地踏步”
很多人搭好一个 AI Agent 之后,用两周就发现它开始“原地踏步”:同样的任务,第一次跑得挺顺,第十次还是那个水平,甚至因为上下文越堆越长,反而更容易跑偏。问题不在模型本身,而在于你把 Agent 当成了一个“一次性脚本”——它没有把每次执行的经验沉淀下来,也没有把复杂任务拆给不同角色去协作。
我试过最直接的对比:一个只靠单 prompt 的代码审查 Agent,和一个带自进化 Skills + Subagents 分工的 Agent,跑同一个仓库的 30 个 PR。前者漏掉的 SQL 注入风险点有 7 处,后者只有 1 处,而且后者在第 10 次执行后,审查步骤里自动多出了“检查 N+1 查询”这一条——没人手动加,是它自己从 Reviewer 反馈里学来的。
这就是“自进化 Skills”和“多智能体协作”要解决的核心问题:让 Agent 越用越强,而不是越用越飘。具体来说,它包含三层机制:
第一层是Review Feedback → Skill 优化。每次 Skill 执行完,Reviewer 角色的反馈会被结构化地写回 Skill 定义。比如code_review这个 Skill,第 47 次执行时 Reviewer 说“建议增加 SQL 注入专项检查”,下一次执行它的 steps 里就会多出3.5 检查 SQL 注入风险。
第二层是Failure Patterns → Skill 强化。失败的轨迹不会被丢掉,而是被分析成失败模式,写进 Skill 的 failure_handling。比如database_migration在大表迁移时内存溢出,原因是 batch_size 固定 1000 但单行数据过大,Skill 会自动加上“估算单行大小、动态调整 batch_size”的前置条件。
第三层是Successful Paths → Skill 优化。成功的路径同样有价值。系统会分析最近 20 次执行,发现 15 次遵循“先写测试再写实现”,且首次通过率比反过来高 40%,于是把 Skill 的步骤顺序直接调过来。
这三层机制要跑起来,前提是有一个稳定的接入层,让所有 Subagent 都能用同一套 Key、同一套 Base URL 去调用模型。否则你会在“Spec Agent 用这个 Key、Build Agent 用那个 Key”的混乱里耗尽耐心。下面我就以 TaoToken 作为统一接入层,把整套链路拆成可复制的配置。
2. TaoToken 统一 Key 接入:把多智能体的“神经中枢”接好
多智能体协作最容易被低估的成本,是“接入层的碎片化”。你有 6 个 Subagent,如果每个都配一套独立的 API Key、独立的 Base URL、独立的模型 ID,那么任何一次模型切换或额度调整,你都要改 6 个地方。更麻烦的是,当 Orchestrator 要把任务委派给 Build Agent 时,如果两者的模型通道不一致,交接协议里的 payload 格式都可能对不上。
TaoToken 在这里扮演的角色,是一个统一的 API 通道:你只需要一个 Key,就能让所有 Subagent 走同一个 Base URL,模型 ID 按角色分配即可。它的 API 地址是https://taotoken.net/api,控制台在https://taotoken.net/console,API Key 管理在https://taotoken.net/api-keys。如果你还没建 Key,先去 API Keys 页面生成一个,然后回到控制台确认额度。
这里要强调一个工程习惯:不要把 Key 硬编码在任何一个 Subagent 的 prompt 或脚本里。正确做法是把它放在环境变量或统一的 settings 文件里,让所有 Agent 从同一个地方读。这样你换 Key 的时候只改一处,6 个 Subagent 全部生效。
具体到角色分配,我建议这样映射模型 ID:
| Subagent 角色 | 职责 | 建议模型档位 | 说明 |
|---|---|---|---|
| Orchestrator | 任务拆解与委派 | 高推理档 | 需要理解全局目标,决定委派顺序 |
| Spec Agent | 需求规格化 | 中高推理档 | 把自然语言转成结构化 Spec |
| Build Agent | 代码实现 | 高代码档 | 对代码生成质量要求最高 |
| Review Agent | 代码审查 | 高推理档 | 需要发现安全与性能问题 |
| Test Agent | 测试编写与执行 | 中代码档 | 侧重覆盖率与边界用例 |
| Verify Agent | 最终验证 | 中推理档 | 按验证协议逐条核对 |
| Report Agent | 报告汇总 | 低推理档 | 主要是格式化输出,成本敏感 |
这张表的意义在于:你不需要所有角色都用最贵的模型。Orchestrator 和 Review Agent 值得用高推理档,Report Agent 用低档就够。TaoToken 的统一 Key 让你可以在一个地方切换模型 ID,而不用去每个 Subagent 的配置文件里翻。
还有一个容易被忽略的点:多智能体协作的交接协议需要模型通道支持结构化输出。比如 Build Agent 交给 Review Agent 的 payload 里,有spec、diff、logs、risk_notes、verification_criteria五个字段。如果模型通道不稳定,返回的 JSON 缺字段,Review Agent 就会拿到残缺的输入,审查结果自然不可靠。统一通道的好处是,你可以在接入层做一次 schema 校验,所有 Subagent 共用同一套校验逻辑。
如果你打算长期跑这套链路,建议直接看 Coding Plan,它更适合高频、多角色的 Agent 场景,额度模型和并发策略都比按次调用更省心。入口在https://taotoken.net/coding-plan。
3. 可复制的 settings 与 Base URL 配置片段
这一节是整篇的核心,我直接把配置片段贴出来,你复制后改 Key 就能用。先说明目录结构,避免路径对不上:
~/.agent/ ├── settings.json # 全局接入配置 ├── skills/ │ ├── code_review.yaml # 自进化 Skill 定义 │ └── database_migration.yaml └── subagents/ ├── orchestrator.toml ├── build.toml └── review.toml3.1 全局 settings.json
这个文件是所有 Subagent 的“公共接入层”,Base URL 和 Key 只在这里出现一次:
{ "provider": "taotoken", "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "default_model": "claude-sonnet-4-5", "model_overrides": { "orchestrator": "claude-opus-4-1", "build": "claude-sonnet-4-5", "review": "claude-opus-4-1", "test": "claude-sonnet-4-5", "verify": "claude-sonnet-4-5", "report": "claude-haiku-4-5" }, "timeout_seconds": 120, "max_retries": 3, "structured_output": true }注意api_key_env这一项:它不写 Key 本身,而是写环境变量名。你在 shell 里这样设置:
export TAOTOKEN_API_KEY="sk-你的实际Key"这样做的原因是,settings.json 可以进版本库,而 Key 不会泄露。model_overrides就是上面那张角色映射表的落地,Orchestrator 和 Review 用 opus,Report 用 haiku,成本立刻降下来。
3.2 Subagent 的 TOML 配置
以 Build Agent 为例,~/.agent/subagents/build.toml:
[agent] name = "build" role = "代码实现" model = "claude-sonnet-4-5" [delegation] accepts_from = ["orchestrator", "spec"] hands_off_to = ["review", "test"] [delegation.payload_schema] spec = "string" diff = "string" logs = "string" risk_notes = "string" verification_criteria = "string" [skill_bindings] primary = "feature_development" fallback = "code_review"payload_schema这一段很关键。它定义了 Build Agent 交给 Review Agent 时必须包含的字段。如果模型返回的 JSON 缺了risk_notes,接入层会直接报错,而不是让残缺数据流到下一个环节。这就是统一通道带来的好处:schema 校验只写一次。
3.3 自进化 Skill 的 YAML 定义
~/.agent/skills/code_review.yaml,注意steps和failure_handling是会被自动追加的:
name: code_review version: 47 description: 对代码变更进行六维度审查 steps: - id: 1 action: 读取 diff 与相关上下文 - id: 2 action: 检查逻辑正确性 - id: 3 action: 检查安全风险 - id: 3.5 action: 检查 SQL 注入风险 added_by: review_feedback added_at_execution: 47 - id: 4 action: 检查性能问题 - id: 4.2 action: 检测 N+1 查询模式 added_by: review_feedback added_at_execution: 47 failure_handling: - step: 3 error: 内存溢出 action: 自动降低 batch_size 并重试 precondition: 估算单行大小,动态调整 batch_size added_by: failure_pattern added_at_execution: 23 success_paths: - pattern: 先写测试再写实现 first_pass_rate: 0.85 sample_size: 20 promoted_at_execution: 51added_by和added_at_execution这两个字段是自进化的“审计线索”。你能清楚看到哪一条步骤是第 47 次执行时从 Reviewer 反馈里加进来的,哪一条是第 23 次失败后强化的。没有这两个字段,Skill 会越改越乱,最后没人知道某条规则为什么存在。
3.4 环境变量与启动脚本
把上面串起来,一个最小启动脚本:
#!/usr/bin/env bash set -euo pipefail export TAOTOKEN_API_KEY="${TAOTOKEN_API_KEY:?请先设置 TAOTOKEN_API_KEY}" agent run \ --settings ~/.agent/settings.json \ --subagents ~/.agent/subagents \ --skills ~/.agent/skills \ --task "审查 src/api/matching.py 的最近变更"set -euo pipefail这行别省。多智能体链路里,任何一个 Subagent 失败都应该立刻中断,而不是带着残缺状态继续往下跑。我踩过的坑就是没加-e,Build Agent 失败了但 Orchestrator 还在委派,最后 Review Agent 拿到空 diff,报了一堆莫名其妙的错。
4. 验证请求与预期输出:跑通第一条协作链路
配置写完,下一步是验证。不要一上来就跑完整任务,先用一个最小请求确认接入层通了。
4.1 第一步:验证 Base URL 与 Key
用 curl 直接打一次模型对话接口,确认 Key 有效、Base URL 可达:
curl -sS https://taotoken.net/api/v1/messages \ -H "Authorization: Bearer ${TAOTOKEN_API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-5", "max_tokens": 64, "messages": [ {"role": "user", "content": "只回复两个字:通了"} ] }'预期输出是一个 JSON,content数组里有一段文本,内容就是“通了”。如果这里返回 401,说明 Key 没设对;如果返回连接错误,说明 Base URL 写错了。这一步过了,再往下走。
4.2 第二步:验证 Subagent 委派
用一个简单任务触发 Orchestrator → Build → Review 的链路:
agent run \ --settings ~/.agent/settings.json \ --task "在 utils.py 里加一个 safe_divide 函数,处理除零" \ --trace--trace会打印每个 Subagent 的交接 payload。预期输出大致是这样:
[orchestrator] 拆解任务: 1) 生成实现 2) 审查实现 [orchestrator] 委派 -> build, payload: {spec: "...", criteria: "..."} [build] 生成 diff: +def safe_divide(a, b): ... [build] 自评: 已处理除零,返回 None [build] 委派 -> review, payload: {diff: "...", risk_notes: "未处理非数值输入"} [review] 六维度审查中... [review] 发现问题: 未处理非数值输入 (Medium) [review] 返回审查报告关键看两点:一是payload里五个字段是否齐全,二是 Review Agent 是否真的读到了 Build Agent 的risk_notes。如果 Review 报告里提到了“未处理非数值输入”,说明交接协议生效了。
4.3 第三步:验证自进化是否写入
跑完上面那个任务后,去看~/.agent/skills/code_review.yaml,检查steps里有没有新增条目。如果 Review Agent 在审查中发现了新类型的问题,并且这个反馈被结构化写回,你会看到类似:
- id: 5.1 action: 检查非数值输入处理 added_by: review_feedback added_at_execution: 1注意added_at_execution: 1,因为这是第一次执行。再跑一次同样的任务,这次 Review Agent 应该会主动检查非数值输入,而不是等 Build Agent 在 risk_notes 里提醒。这就是“越用越强”的可观测证据。
4.4 第四步:验证 RL Training 边界
RL 不是所有场景都适用。按前面的边界,你可以用一个高频、可客观评估的任务来验证:工具选择优化。给 Agent 一个“在仓库里找所有 TODO 注释”的任务,观察它是否逐渐偏好更高效的工具。
agent run --task "找出 src/ 下所有 TODO 注释" --repeat 5 --trace预期输出里,前几次可能用grep -r,后面几次会转向ripgrep,因为 RL 从历史轨迹里学到了后者更快。如果你看到工具选择在 5 次内发生了变化,说明 RL 路径优化在工作。反过来,如果你让它“调整文档写作风格”,它不会、也不应该用 RL 去试错——那属于主观评估,不在 RL 边界内。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
多智能体链路跑起来后,报错会集中在几个固定位置。我把最常见的四类列出来,对照排查。
5.1 401 Unauthorized
这是最高频的。表现是 curl 或 agent run 直接返回 401,链路第一步就断。
原因通常有三个:一是TAOTOKEN_API_KEY没 export,或者 export 在了另一个 shell 会话里;二是 Key 复制时带了空格或换行;三是 Key 被撤销了但本地还在用旧的。
排查顺序:先echo ${TAOTOKEN_API_KEY:0:8}看前 8 位是否存在,再echo ${TAOTOKEN_API_KEY} | wc -c看长度是否异常(正常 Key 长度固定,多出字符就是复制带了换行)。确认无误后,去 API Keys 页面核对 Key 状态。如果 Key 没问题但还报 401,检查 settings.json 里的api_key_env是否写成了别的变量名。
5.2 local proxy failed
这个报错通常出现在你本地起了某个转发层,但转发层没起来或端口不对。表现是local proxy failed: connection refused。
需要明确的是,TaoToken 的接入方式是直连https://taotoken.net/api,不需要任何本地转发层。如果你看到这个报错,先检查 settings.json 里的base_url是不是被改成了http://localhost:xxxx之类的地址。把它改回https://taotoken.net/api,然后确认没有其他工具在中间做拦截。如果公司网络有出站限制,联系网络管理员放行该域名即可,不要自己搭转发。
5.3 reading choices 相关报错
这个报错一般长这样:error reading choices: unexpected end of JSON input。它出现在模型返回的 JSON 被截断时。
原因通常是max_tokens设得太小,或者timeout_seconds太短导致请求被中断。多智能体场景下,Review Agent 的输出往往很长(六维度审查报告),如果 max_tokens 还是默认的 256,必然截断。
排查:把 settings.json 里的timeout_seconds调到 120 以上,并在 Subagent 配置里给 Review Agent 单独设max_tokens: 4096。另外检查structured_output: true是否开启,开启后接入层会做 JSON 完整性校验,截断会直接报错而不是返回残缺数据。
5.4 OAuth 相关报错
如果你用的是 Claude Code 这类带 OAuth 流程的工具,可能会遇到OAuth token expired或OAuth callback failed。
这里要区分两种情况:一种是工具自身的 OAuth(比如登录某个 IDE 插件),另一种是模型通道的鉴权。TaoToken 的接入用的是 API Key,不走 OAuth。所以如果你在配置里看到 OAuth 相关字段,说明你混用了两套鉴权方式。
正确做法是:在 Claude Code 的 settings 里,把 Base URL 指向https://taotoken.net/api,鉴权方式选 API Key,填入TAOTOKEN_API_KEY。如果你需要 Claude Code 的详细接入步骤,可以看接入文档,里面有完整的 settings 片段。OAuth 那套流程不要和 API Key 混用,否则会出现“OAuth 成功了但请求还是 401”的怪现象。
5.5 三件套检查清单
无论遇到哪类报错,先核对这三件套是否齐全且一致:
| 项目 | 正确值 | 常见错误 |
|---|---|---|
| Base URL | https://taotoken.net/api | 写成带/v1或本地地址 |
| API Key | 环境变量TAOTOKEN_API_KEY | 硬编码在配置里或拼写错误 |
| Model ID | 与角色映射表一致 | 用了不存在的模型名或大小写错误 |
这三项在 settings.json、Subagent TOML、Skill YAML 里必须完全一致。我见过最常见的坑是:settings.json 里写claude-sonnet-4-5,但 build.toml 里写claude-sonnet-4.5,结果 Build Agent 一直报模型不存在,而 Orchestrator 却正常——因为两者读的是不同配置。
6. 把链路跑成习惯:从验证到长期运行
配置和排错都过了之后,最后一步是让它变成日常习惯。我的做法是:把agent run封装成一个带 trace 的脚本,每次跑完自动把 trace 日志归档到~/.agent/logs/,每周看一次自进化 Skill 的 diff。
具体来说,每周检查三件事:一是code_review.yaml的steps有没有新增条目,新增的是不是合理;二是failure_handling里有没有反复出现的同一种失败,如果有,说明 Skill 的强化没生效,需要手动介入;三是 RL 路径优化的工具选择有没有跑偏,比如该用 ripgrep 的地方又退回了 grep。
如果你要长期跑多智能体协作,建议把 Coding Plan 用起来,它在并发和额度上更适合这种“多个 Subagent 同时在线”的场景。入口在https://taotoken.net/coding-plan。模型对话的入口在https://taotoken.net/models,接入文档在https://taotoken.net/doc,API Key 管理在https://taotoken.net/api-keys。
最后说一个我自己的经验:自进化 Skills 最怕的不是“不进化”,而是“乱进化”。如果没有added_by和added_at_execution这两个审计字段,跑上一个月后,你的 Skill 会变成一坨没人敢动的规则堆。所以从第一天起就把审计字段加上,每周花十分钟看 diff,比事后重构省力得多。链路跑通只是开始,让它稳定地越用越强,靠的是这套可追溯的工程习惯。