ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Agent与SubAgent全链路拆解:从创建、上下文传递到调度机制,TaoToken统一Key通道实测

Agent与SubAgent全链路拆解:从创建、上下文传递到调度机制,TaoToken统一Key通道实测

1. 多 Agent 协作的真实痛点:为什么你的 SubAgent 总是“各干各的”

很多人第一次接触 Agent 编排,脑子里想的都是“主 Agent 派活、子 Agent 干活、最后汇总”这么一条顺滑流水线。真跑起来才发现,SubAgent 要么收不到足够上下文,要么拿到的 prompt 里塞了一堆无关历史,要么几个子任务互相踩文件,最后主 Agent 汇总时发现结果对不上。问题不在模型能力,而在创建方式、上下文传递边界和调度策略这三件事没拆清楚。

我先把概念对齐一下,避免后面看代码时混淆。Tool 是扳手,被调用一次做一件事;SKILL 是工具箱,里面装着若干工具和使用说明,被动响应;Agent 是工匠,拿到目标后自己规划路径、选工具、验证结果、决定什么时候停。SubAgent 就是主 Agent 临时请来的另一个工匠,它有自己独立的 Agent Loop,但只拿到主 Agent 精选过的那部分信息。

这套机制能解决什么?举个最典型的场景:你让主 Agent“全面审查这个项目”,它会把任务拆成结构分析、安全审查、性能审查、规范检查四条线,分别 spawn 四个 Explore 类型 SubAgent 并行跑,谁先完成谁先回传,主 Agent 边等边整合,甚至根据某个子结果动态再开一个新 SubAgent 去深挖。整个过程不需要你手动编排,但前提是底层模型通道得稳、得能同时扛住多个并发请求。

适合谁看?已经会用 Claude Code 或类似 Agent 框架、想搞明白 SubAgent 背后到底怎么调度的人;以及正在搭多模型协作链路、被“上下文丢失”和“并发限流”折腾过的开发者。下面我会从创建、上下文传递、调度三个层面拆开讲,并且用 TaoToken 的统一 Key 通道把多模型接入这一段跑通,让你有一条能直接复制的链路。

2. TaoToken 统一 Key 通道:多模型接入的前置准备

多 Agent 系统里最容易被忽略的坑,是每个 SubAgent 可能要用不同模型。Explore 类型做只读搜索,用便宜快的模型就够;Plan 类型做方案设计,得用推理强的;安全审查可能想换个模型交叉验证。如果每个模型都单独配一套 Key、单独改一遍 Base URL,配置管理会迅速失控。TaoToken 的价值就在这里:一个 Key、一个 Base URL,通过 Model ID 切换背后调用的模型,Agent 和 SubAgent 共用同一条通道。

先明确三个必须对齐的参数,后面所有配置都围绕它们:

参数值说明
Base URLhttps://taotoken.net/api所有请求的统一入口,不要加 UTM
API Key在控制台创建一个 Key 通吃多模型
Model ID按需填写决定这次请求实际走哪个模型

获取 Key 的路径很直接:打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,进控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,API Key 管理页在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。创建完先别急着往 Agent 里塞,用模型对话页 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 发一条消息验证 Key 是活的,这一步能省掉后面大量“到底是 Key 错还是配置错”的排查时间。

为什么强调“统一通道”对多 Agent 特别重要?因为 SubAgent 是动态创建的,数量不确定、类型不确定。如果每个 SubAgent 都要独立鉴权、独立配 endpoint,主 Agent 在 spawn 的时候就得把鉴权信息也一起传下去,这既增加了 prompt 的复杂度,也把密钥暴露在了上下文里。统一通道之后,SubAgent 只需要知道自己该用哪个 Model ID,鉴权由运行环境统一处理。

这里有个设计上的取舍值得说清楚:TaoToken 是合规的 API 聚合通道,不是让你绕过什么限制,它的定位是帮你把多模型调用收敛到一个入口,方便计费、方便切换、方便在 Agent 编排里做模型路由。你把它理解成“模型调用的统一网关”就行。

配置层面,我建议把 Base URL 和 Key 放在环境变量里,不要硬编码进 Agent 配置。原因后面排障章节会讲——当 SubAgent 在隔离环境(比如 git worktree)里运行时,环境变量是最可靠的传递方式。先执行:

export TAOTOKEN_BASE_URL="https://taotoken.net/api" export TAOTOKEN_API_KEY="sk-你的Key"

验证环境变量生效:

echo $TAOTOKEN_BASE_URL echo $TAOTOKEN_API_KEY | head -c 8

第二条只打印前 8 位,避免 Key 完整出现在终端历史里。这一步做完,前置准备就算齐了,接下来进入真正可复制的配置环节。

3. 可复制配置:Agent 与 SubAgent 的创建模板

这一节给三份能直接用的配置片段:一份是 Agent 运行时的 settings 配置,一份是 SubAgent 的创建调用 JSON,一份是 Claude Code 场景下的 settings.json。三份都对齐同一个 Base URL、Key、Model ID 三件套。

先看运行时的 settings 配置,我用 TOML 写,方便你放进项目根目录:

# agent-settings.toml [provider] base_url = "https://taotoken.net/api" api_key_env = "TAOTOKEN_API_KEY" [models] # 主 Agent 用推理强的模型 main = "claude-sonnet-4-20250514" # Explore 类型 SubAgent 用快而省的模型 explore = "claude-haiku-4-20250514" # Plan 类型 SubAgent 用推理强的模型 plan = "claude-sonnet-4-20250514" [subagent] default_type = "general-purpose" default_isolation = "shared" max_parallel = 4 timeout_seconds = 300

注意api_key_env指向的是环境变量名,不是 Key 本身。这样配置可以进版本库,Key 留在本地环境。max_parallel = 4是并发上限,后面调度章节会解释为什么这个值不能拍脑袋定。

再看 SubAgent 的创建调用,这是主 Agent 实际发出的结构,字段含义我在注释里标清楚:

{ "tool": "Agent", "parameters": { "description": "审查认证模块安全漏洞", "prompt": "分析 src/auth/ 目录下的认证逻辑,重点检查:1) token 刷新时机是否存在竞态;2) 权限校验是否可绕过;3) 密钥是否硬编码。输出 Markdown,包含文件路径、函数签名、风险等级。只搜索 src/auth/,忽略 test/。", "subagent_type": "Explore", "run_in_background": true, "isolation": "worktree", "model": "claude-haiku-4-20250514" } }

这里model字段就是统一通道的落点——同一个 Base URL、同一个 Key,靠这个字段切换实际模型。prompt是上下文传递的唯一载体,这一点下一节展开。isolation: "worktree"让 SubAgent 在 git worktree 副本上跑,改文件不影响主工作区。

最后是 Claude Code 场景下的 settings.json,路径放在~/.claude/settings.json:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的Key", "ANTHROPIC_MODEL": "claude-sonnet-4-20250514" }, "permissions": { "allow": ["Read", "Grep", "Glob"] } }

三件套在这里的对应关系是:Base URL 填ANTHROPIC_BASE_URL,Key 填ANTHROPIC_API_KEY,Model ID 填ANTHROPIC_MODEL。如果你用的是 Cline 或带 MCP 的客户端,配置逻辑一样,只是字段名不同——Base URL、Key、Model ID 这三个位置必须都填对,缺一个就会在请求阶段报错。

配置写完先别急着跑多 Agent,用单次请求验证通道。这一步很关键,因为多 Agent 出问题时,你很难判断是通道问题还是编排问题。验证命令:

curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $TAOTOKEN_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-haiku-4-20250514", "max_tokens": 64, "messages": [{"role": "user", "content": "回复 OK 两个字母"}] }'

返回里能看到content字段带正常文本,说明 Base URL、Key、Model ID 三件套全部对齐。这一步过了,再往上叠 Agent 编排,出问题就能快速定位到是编排层而不是通道层。

4. 上下文传递与调度验证:从创建到结果回传

上下文传递是 SubAgent 机制里最容易被误解的地方。很多人以为 SubAgent 会自动继承主 Agent 的完整对话历史,实际上不会。SubAgent 收到的只有prompt参数里的内容,主 Agent 的对话历史、之前的 tool_call 结果、用户的原始输入、主 Agent 的思考过程,SubAgent 一概看不到。这个设计是有意的:控制上下文窗口、减少干扰、做安全隔离、省 token。

所以主 Agent 构造 prompt 的策略直接决定 SubAgent 能不能干对活。我实测下来,有效的 prompt 遵循四条原则:说目标不说步骤(让 SubAgent 自己规划)、给关键上下文不给全部历史、指定输出格式、设置边界。对比一下:

差:先搜索文件 A,再读文件 B,然后分析第 42 行…… 好:分析认证系统的架构,找出所有安全漏洞 差:粘贴整个之前的对话记录 好:我们在重构 auth 模块,已知问题有 token 竞态和权限绕过 差:随便输出点东西 好:输出 Markdown,包含文件列表、函数签名、调用关系 差:搜索整个项目 好:只搜索 src/auth/,忽略 test/

验证上下文传递是否按预期工作,最直接的办法是在 SubAgent 的 prompt 里埋一个只有主 Agent 知道的标记,然后看 SubAgent 的输出里有没有用到它。比如主 Agent 在 prompt 里写“本次审查基于 commit a1b2c3d”,如果 SubAgent 输出里引用了这个 commit,说明上下文透传成功;如果 SubAgent 说“我不知道基于哪个版本”,说明 prompt 构造漏了信息。

调度层面,同步和异步的选择决定了整个链路的形态。同步模式(run_in_background: false)下主 Agent 阻塞等待,适合结果直接影响下一步决策的场景,比如先搜索代码再决定怎么改。异步模式(run_in_background: true)下主 Agent 立即拿到 task_id 继续干活,适合多个独立任务并行,比如同时搜前端、后端、配置。

并行调度的实际时间轴是这样的:

SubAgent A ████████████████████░░░░░░░░ 已完成 SubAgent B ██████████████████████████████ 已完成 SubAgent C ██████████░░░░░░░░░░░░░░░░░░ 已完成 主 Agent: t0: 同时创建 A、B、C(全部 run_in_background: true) t0: 收到三个 task_id,记录到任务列表 t0: 主 Agent 继续执行自己的任务(不阻塞) t1: 收到通知 → C 完成,取回结果并入上下文 t2: 收到通知 → A 完成,发现新问题 → 创建 SubAgent D t3: 收到通知 → B 完成,所有结果收集完毕 → 整合输出

关键点是主 Agent 不等待所有 SubAgent 完成才行动,它边等边做,收到一个处理一个,甚至根据某个子结果动态再开新 SubAgent。这就是 Agent Loop 五步循环(Plan → Execute → Observe → Decide → 循环)在调度层的体现。

依赖管理有三种典型模式。完全并行无依赖,三个 SubAgent 同时启动各自完成;串行依赖链,A 的结果作为 B 的输入,B 的结果作为 C 的输入,必须逐个等待;混合依赖最复杂也最常见,A 和 C 并行,B 等 A,D 等 C,E 等 B 和 D 都完成。混合依赖下主 Agent 的调度逻辑要显式写清楚“等谁完成再启动谁”,不能靠默认行为。

验证调度是否按预期并行,可以在每个 SubAgent 的 prompt 里让它输出开始和结束时间戳,然后对比时间轴。如果三个本该并行的 SubAgent 时间戳是串行的,说明run_in_background没设成 true,或者并发上限被卡住了。

5. 常见报错排查:401、local proxy failed、reading choices、OAuth

多 Agent 链路出问题时,报错信息往往指向底层通道而不是编排逻辑。这一节把四类高频报错和对应处理列清楚,你按顺序排查基本能定位。

401 Unauthorized。最常见的原因是 Key 没传对或环境变量没生效。先确认环境变量在当前 shell 里可见:

echo $TAOTOKEN_API_KEY | head -c 8

如果为空,说明 export 没执行或在新终端里丢了。如果 Key 有值但仍 401,检查请求头字段名是否正确——Anthropic 风格用x-api-key,OpenAI 风格用Authorization: Bearer,两者不能混。还要确认 Base URL 没有多余斜杠,https://taotoken.net/api后面不要再拼/v1之外的路径。

local proxy failed。这个报错通常出现在客户端配置了本地代理但代理没起来,或者 Base URL 指向了本地地址。检查你的 settings.json 里ANTHROPIC_BASE_URL是不是被改成了http://localhost:xxxx之类的本地地址。统一通道场景下,Base URL 应该直接是https://taotoken.net/api,不需要经过任何本地转发。如果确实需要本地代理做日志,确保代理进程在跑且端口对得上。

reading choices 相关报错。这类报错一般出现在 OpenAI 兼容格式的响应解析阶段,说明返回结构里没有choices字段。原因通常是 Model ID 填错了,请求打到了不支持该格式的模型上,或者 Base URL 路径不对导致返回了错误页而不是 JSON。排查方法:用第 3 节的 curl 命令直接打一次,看返回体是 JSON 还是 HTML。如果是 HTML,说明路径错了;如果是 JSON 但没有 choices,说明 Model ID 和接口格式不匹配。

OAuth 相关报错。如果你用的是 Claude Code 或 Codex 这类带 OAuth 登录的客户端,报错可能来自它尝试走 OAuth 流程而不是 API Key。这时候要确认配置里用的是 API Key 模式,而不是登录态模式。Claude Code 场景下,ANTHROPIC_API_KEY和 OAuth 登录态是互斥的,配了 Key 就走 Key,不要再触发登录流程。Codex 的auth.json里如果同时有 OAuth token 和 API Key,优先走哪个取决于客户端版本,建议清掉 OAuth 部分只留 Key。

排查顺序建议固定成:先 curl 验证通道 → 再验证单 Agent 请求 → 最后验证多 Agent 编排。这样每层都能独立确认,不会出现“改了五处配置不知道哪处生效”的情况。另外,SubAgent 在 worktree 隔离环境里跑时,环境变量可能不继承,如果隔离环境下报 401,检查是不是 Key 没通过环境变量传进去。

6. 把链路跑稳:从单 Agent 到多 Agent 的落地建议

多 Agent 协作链路能不能稳定跑,取决于几个容易被忽略的细节。第一是 prompt 粒度,太粗 SubAgent 理解困难,太细又失去自主决策优势。“分析 src/auth/ 下的认证逻辑”是好粒度,“审查整个项目”太粗,“读 login.ts 第 42 行”太细。第二是并行上限,max_parallel不要拍脑袋设成 10,要看你用的模型通道的并发承载能力,设成 4 左右先跑,观察有没有限流再调。第三是结果验证,SubAgent 也会出错,主 Agent 收到结果后要检查完整性、交叉验证重叠范围、关键发现自己复查。

如果你打算长期跑多 Agent 编码或 Agent 类任务,Coding Plan 比按次调用更划算,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有各客户端的完整配置示例。Claude Code 专项接入参考 https://taotoken.net/claudecode?utm_source=taotoken_aicg_blog_end&utm_content=claudecode&utm_campaign=rewrite 。

最后给一个实用技巧:在项目根目录放一个.agent/config.toml,把 Base URL、Model ID 映射、并发上限写进去,主 Agent 和 SubAgent 都从这里读。这样切换模型或调整并发时只改一处,不用满项目找配置。跑通之后你会发现,SubAgent 机制真正的价值不是“多开几个进程”,而是让主 Agent 能根据任务形态动态决定拆不拆、拆几个、用哪个模型——这套决策能力,才是 Agent 和普通脚本的本质区别。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进