1. 多 Agent 架构选型:为什么堆得越多反而越乱
很多人第一次接触多 Agent 架构时,直觉是“多开几个 Agent 就能更强”。我见过一个真实项目,主对话里同时挂了 6 个 Agent:一个查代码、一个跑测试、一个写文档、一个做审查、一个管数据库、一个负责部署。结果呢?主对话的上下文被各种中间日志塞满,模型开始“记不住”最初的目标,一个简单的 bug 修复被拆成了十几轮来回确认,token 消耗翻了三倍,效率反而下降。
问题不在于 Agent 数量,而在于你没有为每种任务选对协作模式。Sub-Agent、Skills、Handoff、Router 这四种模式,解决的是完全不同的问题:
- Sub-Agent(子代理):解决“高噪声执行过程污染主对话”的问题。它拥有独立上下文窗口,执行完即丢弃,只把结论带回主对话。
- Skills(技能):解决“知识复用”的问题。把领域知识、规范、流程预加载到 Agent 上下文中,不需要每次重新发现。
- Handoff(交接):解决“任务在多个角色间流转”的问题。一个 Agent 完成阶段性工作后,把控制权和上下文交给下一个 Agent。
- Router(路由):解决“请求该由谁处理”的问题。根据输入特征,把请求分发给最合适的 Agent 或模型。
选错模式的代价很直接:用 Sub-Agent 做需要频繁来回确认的任务,会拖慢节奏;用 Handoff 做简单查询,会引入不必要的复杂度;用 Router 做单一路径任务,纯属过度设计。
这篇文章会给出config.toml和settings.json的可复制骨架,并演示一次 Router 分流与 Handoff 切换的验证动作。所有请求统一走 TaoToken 的 API 通道,这样你只需要维护一套 Key,就能在四种模式间自由切换做对比验证。
2. TaoToken 前置:统一 Key 与 API 通道
在开始配置之前,你需要先准备好统一的 API 通道。TaoToken 的作用是让你用一个 Key 访问多个模型,这样在做 Router 分流验证时,不需要为每个模型单独申请和管理 Key。
2.1 获取 API Key
访问 TaoToken 控制台创建 API Key:
https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite创建后你会得到一个以sk-开头的 Key。把它保存到环境变量中,避免硬编码到配置文件里:
export TAOTOKEN_API_KEY="sk-your-key-here"2.2 确认 API 端点
TaoToken 的 API 端点为:
https://taotoken.net/api这个端点兼容 OpenAI 风格的请求格式,大多数 Agent 框架和 SDK 都可以直接对接。如果你使用的是 Anthropic 风格的接口,TaoToken 也提供了对应的兼容路径,具体可以参考接入文档:
https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite2.3 验证 Key 是否可用
在正式配置 Agent 之前,先用一条最简单的请求确认通道正常:
curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "reply with ok"}], "max_tokens": 10 }'如果返回中包含"ok"或正常的choices结构,说明 Key 和通道都没问题。这一步很重要——后面四种模式的验证都依赖这个通道,如果这里不通,后面所有配置都是白搭。
3. 可复制配置骨架:config.toml 与 settings.json
下面给出四种模式的配置骨架。你可以根据实际场景选择其中一种或组合使用。所有配置中的 API 地址统一指向 TaoToken。
3.1 config.toml:Sub-Agent 与 Skills 定义
# config.toml - 多 Agent 架构配置骨架 [api] base_url = "https://taotoken.net/api" api_key_env = "TAOTOKEN_API_KEY" default_model = "gpt-4o-mini" # ---------- Sub-Agent 定义 ---------- [agents.code-reviewer] description = "Review code changes for quality, security, and best practices. Use after code is modified." model = "gpt-4o" tools = ["Read", "Grep", "Glob"] permission_mode = "plan" # 强制只读,即使有 Bash 也无法写入 skills = ["security-checklist"] # 预加载安全审查知识 [agents.test-runner] description = "Run test suites and report pass/fail summary. Use when tests need execution." model = "gpt-4o-mini" tools = ["Read", "Bash"] permission_mode = "acceptEdits" [agents.log-analyzer] description = "Analyze log files and extract key errors. Use when logs exceed 100 lines." model = "gpt-4o-mini" tools = ["Read", "Grep"] permission_mode = "plan" # ---------- Skills 定义 ---------- [skills.security-checklist] path = "./skills/security-checklist.md" inject_mode = "full" # 完整注入到 Agent 上下文 [skills.chain-knowledge] path = "./skills/chain-knowledge.md" inject_mode = "full" # ---------- Router 定义 ---------- [router] strategy = "rule-based" # 可选:rule-based / semantic / hybrid [[router.rules]] name = "code-task" match = ["review", "refactor", "bug", "fix"] target = "code-reviewer" [[router.rules]] name = "test-task" match = ["test", "run tests", "coverage"] target = "test-runner" [[router.rules]] name = "log-task" match = ["log", "error", "stack trace"] target = "log-analyzer" [[router.rules]] name = "default" match = ["*"] target = "general-purpose" # ---------- Handoff 定义 ---------- [[handoff.pipelines]] name = "review-fix-verify" steps = ["code-reviewer", "bug-fixer", "test-runner"] carry_context = true # 每一步携带上一步的结论摘要 max_rounds = 33.2 settings.json:运行时参数
{ "api": { "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "timeout_seconds": 60, "max_retries": 2 }, "agent": { "max_sub_agents": 4, "allow_nested_sub_agents": false, "default_permission_mode": "plan", "context_isolation": true }, "router": { "enabled": true, "fallback_agent": "general-purpose", "log_routing_decisions": true }, "handoff": { "enabled": true, "context_summary_max_tokens": 500, "require_explicit_confirm": false }, "skills": { "auto_load": ["security-checklist"], "cache_enabled": true } }3.3 四种模式的配置差异对照
| 模式 | 核心配置项 | 适用场景 | 上下文行为 |
|---|---|---|---|
| Sub-Agent | agents.*.tools+permission_mode | 高噪声执行、权限隔离 | 独立窗口,执行完丢弃 |
| Skills | skills.*.path+inject_mode | 知识复用、规范预加载 | 注入到调用者上下文 |
| Handoff | handoff.pipelines.steps | 多阶段流水线 | 携带摘要,逐步传递 |
| Router | router.rules+strategy | 请求分发、多入口 | 不改变上下文,只做分发 |
这张表是你做选型时的第一判断依据。如果你面对的任务是“跑一次测试,只要结论”,选 Sub-Agent;如果是“每次审查都要遵守同一套安全规范”,选 Skills;如果是“先审查再修复再验证”,选 Handoff;如果是“用户输入不确定,需要自动分发”,选 Router。
4. 验证请求:Router 分流与 Handoff 切换
配置写好了,接下来做一次实际验证。我们分两步:先验证 Router 能否正确分流,再验证 Handoff 能否在 Agent 间正确传递上下文。
4.1 Router 分流验证
启动你的 Agent 框架(这里以通用 CLI 为例),发送三条不同特征的请求,观察 Router 的分流结果:
# 请求 1:应路由到 code-reviewer curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "review this function for security issues"}], "metadata": {"router_debug": true} }' # 请求 2:应路由到 test-runner curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "run the test suite and tell me if it passes"}], "metadata": {"router_debug": true} }' # 请求 3:应路由到 log-analyzer curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "analyze this stack trace and find the root error"}], "metadata": {"router_debug": true} }'如果 Router 配置正确,你会在返回的metadata或日志中看到类似的分流记录:
{ "router_decision": { "matched_rule": "code-task", "target_agent": "code-reviewer", "confidence": 0.92 } }如果三条请求都路由到了general-purpose,说明你的router.rules匹配规则没有生效。检查match数组中的关键词是否与请求文本有交集,以及strategy是否设置为rule-based。
4.2 Handoff 切换验证
Router 验证通过后,再验证 Handoff 流水线。发送一条触发review-fix-verify流水线的请求:
curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "review auth.py, fix any issues found, then run tests"}], "metadata": {"handoff_debug": true} }'预期的执行链路:
[主对话] 接收请求 ↓ [code-reviewer] 审查 auth.py → 输出:发现 2 个问题(SQL 注入风险、缺少输入校验) ↓ (携带摘要) [bug-fixer] 接收摘要 → 修复 2 个问题 → 输出:已修复,变更 3 个文件 ↓ (携带摘要) [test-runner] 接收摘要 → 运行测试 → 输出:12 passed, 0 failed ↓ [主对话] 汇总最终结论验证成功的标志是:主对话最终只收到一条汇总结论,而不是三个 Agent 的完整执行日志。如果你在返回中看到了 500 行测试日志或完整的代码 diff,说明carry_context或context_summary_max_tokens配置有问题。
4.3 成功结果对照
| 验证项 | 成功标志 | 失败标志 |
|---|---|---|
| Router 分流 | 请求命中预期 Agent | 全部落到 fallback |
| Handoff 传递 | 主对话只收到摘要 | 主对话收到完整日志 |
| Sub-Agent 隔离 | 子代理日志不进入主上下文 | 主上下文被日志塞满 |
| Skills 注入 | Agent 直接引用规范内容 | Agent 重新搜索规范 |
5. 本篇常见错排查
5.1 Router 规则不生效
最常见的原因是match关键词大小写不匹配。Router 默认区分大小写,如果你的请求是Review this code,而规则里写的是review,可能匹配不上。解决方法是在 Router 配置中开启case_insensitive: true,或者统一把关键词和请求都转成小写。
另一个原因是规则顺序问题。Router 通常按顺序匹配,第一条命中的规则生效。如果你把default规则放在了最前面,后面所有规则都不会被触发。确保default规则始终在最后。
5.2 Handoff 上下文丢失
如果 Handoff 切换后,下一个 Agent 说“我不知道上一步做了什么”,检查carry_context是否设置为true。另外,context_summary_max_tokens如果设置得太小(比如 100),摘要可能被截断,导致关键信息丢失。建议设置在 300–500 之间。
5.3 Sub-Agent 权限越界
你配置了permission_mode = "plan",但子代理仍然修改了文件。这通常是因为tools列表中包含了Write或Edit。permission_mode是行为约束,tools是能力约束——两者要配合使用。最可靠的做法是:只读型子代理的tools列表中不要出现任何写操作工具。
5.4 Skills 未注入
子代理没有自动继承主对话的 Skills,这是设计如此。如果你希望子代理拥有某个 Skill,必须在子代理的skills字段中显式列出。检查config.toml中对应 Agent 的skills数组是否包含了目标 Skill 名称。
5.5 API 请求超时
如果验证请求频繁超时,先确认base_url是否正确指向https://taotoken.net/api,然后检查timeout_seconds是否设置得太短。对于涉及多个 Agent 的 Handoff 流水线,建议把超时设置为 120 秒以上,因为链路中每一步都需要独立的模型调用。
6. 选型决策与下一步
回到最初的问题:Sub-Agent、Skills、Handoff、Router 到底怎么选?
我的经验是,不要一开始就上全套。先用 Sub-Agent 解决上下文污染问题——这是投入产出比最高的一步。当你发现某些规范需要反复告诉 Agent 时,再引入 Skills。当你发现任务需要多阶段流转时,再引入 Handoff。最后,当你有了多个 Agent 和多个入口,才需要 Router 来做分发。
如果你主要做长期编码和 Agent 开发,建议直接使用 Coding Plan 来获得更稳定的调用配额和更低的延迟:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite如果你想先快速验证模型对话和 Router 分流效果,可以直接在模型对话页面测试:
https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite配置过程中遇到接入问题,优先查阅接入文档中的错误码说明:
https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite最后提醒一点:子代理不能嵌套生成子代理。所有编排必须由主对话完成。理解这条约束,你在设计复杂工作流时就不会走弯路。