OpenClaw 跑 Sub-agent 编排时,我先把 Key 统一走 TaoToken:打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 创建 API Key,再把它填进 openclaw.json 的 Base URL https://taotoken.net/api。主 Agent 用 sessions_spawn() 拆任务后,每个子 Agent 都是独立会话,每一轮都要独立调模型。如果还按服务商一把一把配 Key,几个子 Agent 并行起来,限流和 401 会轮流来。这篇就按 OpenClaw 5.5.1 的 Sub-agent 编排流程,把主 Agent、子 Agent、fallback 链全部收敛到一把 Key 上。
1. sessions_spawn() 之前,先把子 Agent 的模型通道收敛成一把 Key
1.1 子 Agent 每次都在独立调模型,Key 分散是硬伤
OpenClaw 的 Sub-agent 编排,核心动作就是sessions_spawn()。原文 5.5.4 的研究型工作流是个很好的例子:你让主 Agent 写一份对比报告,它会自动把「查技术资料」「查配置差异」拆成两个子任务,分别 spawn 子 Agent A 和子 Agent B,然后用sessions_yield()等它们跑完再汇总。
问题就出在每个子 Agent 都是独立会话。独立会话意味着它有独立的上下文窗口,也意味着它每一次回复都要单独发起模型请求。一个对比报告任务,主 Agent 自己可能要调三五次模型,两个子 Agent 各自又要调三五次。如果这时刚好有八个子 Agent 并行——原文 5.5.4 明确说过最大并发数是 8——同一秒内会有多个请求打在同一个模型服务上。
老办法是在 openclaw.json 的 models.providers 里给 deepseek、dashscope、qwen 各配一把 Key。按服务商分开配,单个 Agent 用起来没问题,但 Sub-agent 并行时会同时撞上两类错:第一类是同一个 provider 的多个请求同时触发限流,返回 429;第二类是子 Agent 想走 fallback 到另一家模型,结果那家的 Key 没配或者配错了,直接 401。更麻烦的是消耗看不清楚,一次编排下来到底烧了多少 token,得去好几个后台分别查。
这时候把模型调用统一走 TaoToken,其实就是把「多把 Key 分散管理」变成「一把 Key 管所有模型请求」。主 Agent、子 Agent 都从同一个 Base URL 出去,模型 ID 统一挂 taotoken/ 前缀,fallback 链上的备选模型也全在这把 Key 下面。编排逻辑一行都不用改,配置却简单得多。
1.2 和原文配置的对应关系
原文把模型 Key 直接写在 openclaw.json 的 models.providers 下,默认模型写在 agents.defaults.model 下。改成统一 Key 后,对应关系是这样的:
| 原来逐个 provider 做的事 | 现在统一由 TaoToken 完成 |
|---|---|
| 去各服务商后台申请 Key | 打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 创建一把 Key |
| 在 models.providers 里为每家写一段配置 | 只写一个 taotoken provider,Base URL 填 https://taotoken.net/api |
| primary 写 deepseek/deepseek-chat | 改成 taotoken/你在模型广场选到的 ID |
| fallbacks 里写别家模型 | fallbacks 全写 taotoken/ 前缀,Key 只有一把 |
原文 5.3.1 讲模型 fallback 时强调过完整链路:主模型失败、重试、换备选。走 TaoToken 之后,这条链路依然保留,只是所有候选模型都挂在同一个 provider 名下,备选模型不会因为缺 Key 而无法访问。
2. 准备材料:到 TaoToken 拿 Key,并记准 Base URL
2.1 注册、创建 API Key
先去 TaoToken 注册并登录。落地页是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= ,进入后在控制台的 API Keys 页面创建一把新 Key,名字随意,比如 openclaw-subagent。创建完把 Key 复制下来,下文配置里所有 YOUR_API_KEY 都用它替换。这一把 Key 就是 OpenClaw 访问所有模型的唯一凭证,不要写进公开仓库或贴到群里。
2.2 Base URL 和落地页是两个地址,别混
这里有两个地址,职责完全不同:
- 落地页:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= ,用于注册、创建 Key、看模型广场、看后台用量。
- Base URL:https://taotoken.net/api ,填进 OpenClaw 的配置,末尾没有 /v1,也不要带任何 UTM 参数。
如果你在 openclaw.json 里把 baseUrl 写成 https://taotoken.net/api/v1,模型请求会打到一个不存在的路径,报错通常是 404 或连接失败。这不是模型的问题,是地址写错了。
2.3 模型 ID 以模型广场为准
OpenClaw 的模型 ID 格式是 provider 前缀加模型名,原文里的 deepseek/deepseek-chat 就是这个格式。走 TaoToken 后,provider 名固定写 taotoken,后面的模型名以 TaoToken 模型广场当时列表为准。打开模型广场,先选一个做主模型,再选一个做备选模型。例如你在广场看到某个模型的 ID 是 claude-sonnet-4-20250514,配置里就写 taotoken/claude-sonnet-4-20250514;如果看到的是 deepseek-chat,就写 taotoken/deepseek-chat。不要凭印象拼模型名,模型广场没有的 ID,配进去就是 404。
3. 改 openclaw.json:把 Sub-agent 编排的模型调用指到 TaoToken
3.1 先定位原来的 providers 段
打开 ~/.openclaw/openclaw.json,先看 models.providers。老配置通常是每家服务商一段,形如:
{ "models": { "providers": { "deepseek": { "apiKey": "YOUR_API_KEY" }, "dashscope": { "apiKey": "YOUR_API_KEY" } } } }这只是结构示意,真实文件里写的是你原来的 Key。单 Agent 场景下,这样的配置能跑;一旦 sub-agent 并行,限流阈值和 Key 缺失问题会同时暴露出来。改配置前建议先备份一份 openclaw.json,原文明说改大配置前先拉备份,这里同样适用。
3.2 新增 taotoken provider
把 providers 段改成只保留一个 taotoken:
{ "models": { "providers": { "taotoken": { "baseUrl": "https://taotoken.net/api", "apiKey": "YOUR_API_KEY" } } } }提示:baseUrl 必须精确到 https://taotoken.net/api,不要加 /v1,不要加斜杠,不要带查询参数。apiKey 用你在落地页创建的真实 Key 替换,不要保留 YOUR_API_KEY 字样。其他 provider 可以先注释掉,等验证通过再决定要不要留。保留多个 provider 不冲突,但既然目标是统一看消耗,建议默认请求全走 taotoken。
3.3 默认模型和 fallback 链也改成 taotoken 前缀
在 agents.defaults.model 里,原来是 deepseek/deepseek-chat 这类 ID,现在改成:
{ "agents": { "defaults": { "model": { "primary": "taotoken/YOUR_MODEL_ID", "fallbacks": ["taotoken/YOUR_FALLBACK_MODEL_ID"] } } } }YOUR_MODEL_ID 和 YOUR_FALLBACK_MODEL_ID 分别替换成模型广场上看到的主模型和备选模型。主 Agent 和子 Agent 的默认模型都读这里。原文里 demo-agent 有自己的 fallback 链,如果你也在 agents.list 里给某个 agent 单独配了 model 段,同样把 primary 和 fallbacks 都改成 taotoken/ 前缀。
这样改完,一个典型的效果是:子 Agent 在主模型 429 或超时时,OpenClaw 自动切到 fallbacks 里的备选模型,备选也走同一把 Key。不会出现「提示 fallback 到 qwen,但 qwen 的 Key 还没配」这种断链。
3.4 重启 Gateway,让配置生效
OpenClaw 改完配置不会热加载,需要重启 Gateway:
openclaw gateway restart openclaw doctordoctor 没有红色报错,说明 provider 和模型 ID 基本没问题。如果 doctor 提示模型不存在,回模型广场换一个 ID 再重启。这一步别省,配置没生效时,主 Agent 行为跟老配置完全一样,你会误以为改动没起作用。
4. 跑通编排:用两个子 Agent 做一次对比报告
4.1 设计一个安全的任务
先不要急着让子 Agent 去查生产库。把任务限制在当前工作目录:子 Agent A 读取 openclaw.json,整理 models.providers 和 agents.defaults.model 两段的字段清单;子 Agent B 读取 memory 目录下最近的日志,提取出现频率最高的几个报错码。涉及 SQL 的场景,子 Agent 只负责生成排查语句,真正执行由你在本地终端或 SQL*Plus 里做,再把输出贴回对话。这样既验证了 Sub-agent 编排,又不会把生产数据暴露给 Agent 工具。
4.2 主 Agent 拆解任务
在 OpenClaw 会话里给主 Agent 一句话任务,它会自动拆解,大致行为如下:
sessions_spawn({ task: "读取 openclaw.json,把 models.providers 和 agents.defaults.model 两段整理成字段清单", taskName: "config-audit", model: "taotoken/YOUR_MODEL_ID", context: "isolated" }); sessions_spawn({ task: "读取 memory 目录下最近的日志,提取出现频率最高的 5 个报错码", taskName: "error-audit", model: "taotoken/YOUR_MODEL_ID", context: "isolated" }); sessions_yield("两个子 Agent 都在跑,等它们汇总");原文给的参数格式是sessions_spawn(task, taskName, context?),同时核心参数示例又用了对象形式。上面这段用对象形式是为了把 model 字段写清楚。model 参数不写也会走默认模型,但写出来能明确子 Agent 用的也是 taotoken。context 用 isolated,子 Agent 就是干净会话,不继承主会话上下文,这符合原文 5.5.5 的记忆隔离规则,也能省 token。
4.3 等子 Agent 返回,主 Agent 汇总
子 Agent 跑完后,会通过 sessions_yield 唤醒主 Agent。这个过程跟原文 5.5.4 的研究型工作流一致:主 Agent 等待所有子 Agent 完成,再汇总生成报告。日志里应该能看到两个子 Agent 各自独立返回,互不干扰,主 Agent 把两份清单拼成一张 Markdown 表格。
因为 model 参数是 taotoken/ 前缀,两个子 Agent 的模型请求都从同一把 Key 出去,即使其中一个先触发限流,另一个也能顺着 fallback 换到备用模型,不会因为另一家 Key 缺失停在半路。这就是统一通道在编排场景里最直接的价值。
4.4 观察是否真的并行
OpenClaw 默认允许的最大并行数是 8,配置项在 subagent lane 的 maxConcurrentRuns。两个子 Agent 并发跑时,TaoToken 后台应能看到几乎同一时间戳的两笔请求。如果看到的是串行,说明并发配置被调小了,去检查 maxConcurrentRuns。如果子 Agent 每轮都独立调模型,请求时间戳会一条条排开,这是判断编排链路是否真正走通的最直接证据。
5. 验证:到 TaoToken 控制台核对这次调用的记录
5.1 看请求数和 token 消耗
跑完双子 Agent 任务后,打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 登录控制台,查看按时间排序的调用记录。你应该能看到这次编排产生的请求,包括模型、时间、token 消耗。因为所有子 Agent 都走同一把 Key,记录会集中在一个页面,不用再挨个服务商后台翻。
5.2 用消耗数据反推 context 选择
如果两个子 Agent 的输入 token 明显偏大,说明主会话把太多上下文传给了子 Agent,或者你在 sessions_spawn 里用了 context: "fork"。类似任务建议保持 isolated;只有在子 Agent 确实需要看到完整对话时才用 fork。原文的对比很明确:isolated 是干净会话、省 token,fork 会继承主会话上下文、token 消耗会大很多。控制台的记录能验证这个差异是否如预期。
5.3 先用模型对话页确认 Key
如果下一次编排前想先确认 Key 和模型 ID 没问题,可以在模型对话页用同一把 Key 发一条测试消息。模型对话走的是同一套鉴权,能通说明 Key 本身没问题,问题多半在 openclaw.json 的 Base URL 或模型 ID 上。
6. 排障:子 Agent 并行时报错,先查这四类
6.1 401 Unauthorized
最常见原因是 apiKey 没替换干净。检查 openclaw.json 里 YOUR_API_KEY 是否被真实 Key 替换,注意别多复制空格或换行。另外,不要把 Key 塞进 baseUrl,OpenClaw 会从 apiKey 字段单独读取。如果确认 Key 没问题,回控制台重新生成一把再试,偶尔是创建时复制漏了字符。
6.2 404 model not found
模型 ID 写错,或者模型名不在模型广场。OpenClaw 对不存在的模型一般直接报 model not found。回 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 模型广场对照列表重新填,不要自己推断 ID。比如在 deepseek-chat 后面加个日期当模型名,这种 ID 不存在就是 404。
6.3 429 Rate Limit
多个子 Agent 同时调同一个模型,可能触发限流。OpenClaw 有模型 fallback 机制,可以在 agents.defaults.model.fallbacks 里配备用模型,备选也走 taotoken/ 前缀。如果 429 还是频繁,就把 subagent 并发数调小,比如从 8 改成 3,让任务分批跑。并行度太高时,换模型和调并发双管齐下才压得住。
6.4 Base URL 多了 /v1
如果发现请求路径变成 https://taotoken.net/api/v1/xxx 之类的 404,先看配置里 baseUrl 是不是写了 /v1。统一填 https://taotoken.net/api,不要自己补路径。这个错通常在首次配置时出现,排障优先级最高,因为它会让所有模型请求全部失败。
7. 收尾:把编排链路和日常消耗管理接上
7.1 去模型对话确认一遍,再谈 Coding Plan
配置保存后,建议先在 TaoToken 模型对话 里用同一把 Key 发一条测试消息,确认模型 ID 和 Base URL 没填错。日常用 OpenClaw 跑 Sub-agent 编排,token 消耗会比单 Agent 明显增加,可以打开 Coding Plan 看套餐是否够用。需要新 Key 就去 控制台 API Keys 创建。Claude Code 的环境变量对照可以看 接入文档。
7.2 把 Key 管好,编排才跑得久
如果你的 openclaw.json 会提交到 Git,建议把 apiKey 改成环境变量引用,比如 ${TAOTOKEN_API_KEY},而不是明文写死。个人环境临时用明文可以接受,但 Sub-agent 编排链路越长,日志和临时文件里出现 Key 的暴露点越多,生产环境用 SecretRef 更稳妥。原文 5.4.9 也强调过 Secrets 管理,这里正好用上。