☰
第十一节:子 Agent 与 Agent 分叉——用 TaoToken 统一 Key 打通 AgentTool 与 Fork 配置
2026/9/28 16:28:24 网站建设 项目流程

1. 从单 Agent 到 Agent 系统:为什么需要子 Agent 与 Fork

如果你已经用 Claude Code 写过几轮代码,大概率遇到过这种场景:让它重构一个跨 5 个文件的模块,它读到第三个文件时开始"忘事",前面定义的接口名记错了,改出来的代码对不上。这不是模型不行,而是单 Agent 的三重瓶颈在作祟——上下文窗口被工具调用结果快速填满、任务只能串行执行、规划/编码/审查混在一个对话里互相干扰。

子 Agent 的思路是分治:主 Agent 当规划者,把"分析现有结构""改模块 X""改模块 Y""跑测试"拆给独立上下文的子 Agent,每个子 Agent 有自己的工具集和权限模式,主 Agent 只看最终结果,不看中间过程。而 Agent 分叉(Fork)更进一步——它让子 Agent 继承父级的完整对话历史,同时通过统一占位符设计让多个 Fork 共享同一份 Prompt Cache,把重复上下文的开销压到最低。

这篇聚焦两件事:一是用 TaoToken 统一 Key 打通 AgentTool 与 Fork 的调用链路,二是给出config.toml和settings.json的可复制配置骨架,并演示一次子 Agent 派生 + 分叉验证,确认缓存命中情况。适合已经在用 Claude Code、想上多 Agent 协作但卡在配置和 Key 管理上的开发者。

2. TaoToken 前置:统一 Key 与 API 通道

多 Agent 场景下最烦的是 Key 散落各处——主 Agent 一个、子 Agent 一个、Fork 出来的 worker 又一个,轮换时改到崩溃。TaoToken 的价值在于提供一个统一的 API 通道,所有 Agent(主/子/Fork)走同一个 base URL 和同一把 Key,配置只写一次。

先拿到 Key:访问控制台 https://taotoken.net/api-keys 创建,复制出来备用。注意 API 端点用 https://taotoken.net/api,不要带任何查询参数。

注意:Key 只创建一次就够,子 Agent 和 Fork 会继承父级的环境变量,不需要单独配。这是统一通道的核心收益。

环境变量是最省事的注入方式,先设好:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的TaoToken密钥"

设完可以用一条命令确认通道通不通:

curl -s https://taotoken.net/api/v1/models \ -H "Authorization: Bearer $ANTHROPIC_API_KEY" | head -c 300

返回模型列表就说明 Key 和通道都正常。这一步别跳过,后面 AgentTool 报的很多错其实是这里没通。

3. 可复制配置:config.toml 与 settings.json 骨架

Claude Code 的配置分两层:config.toml管模型和通道,settings.json管 Agent 定义和权限。两者配合才能让子 Agent 和 Fork 正确继承。

3.1 config.toml:统一模型与通道

# ~/.claude/config.toml [api] base_url = "https://taotoken.net/api" api_key_env = "ANTHROPIC_API_KEY" [model] default = "claude-sonnet-4-20250514" # Fork 必须继承父级模型,否则 Prompt Cache 无法共享 inherit_on_fork = true [agent] # 开启 Fork 子 Agent 能力 enable_fork_subagent = true # 子 Agent 最大轮次,防止失控 max_turns = 200 # 递归 Fork 防护:Fork 出来的 worker 不能再 fork prevent_recursive_fork = true

inherit_on_fork = true是关键。Fork 子 Agent 如果用了不同模型,API 请求前缀就对不上,Prompt Cache 直接失效,成本翻倍。

3.2 settings.json:Agent 定义与权限

{ "agents": { "general-purpose": { "tools": ["*"], "model": "inherit", "permissionMode": "bubble" }, "Explore": { "tools": ["Read", "Grep", "Glob"], "disallowedTools": ["Edit", "Write", "Agent"], "model": "claude-haiku-4-20250514", "omitClaudeMd": true }, "fork": { "tools": ["*"], "model": "inherit", "permissionMode": "bubble", "maxTurns": 200 } }, "permissions": { "allow": ["Read", "Grep", "Glob", "Bash(git:*)"], "deny": ["Agent"] } }

几个要点:Explore用 haiku 降本且omitClaudeMd: true省掉 CLAUDE.md 的 token;fork的tools: ["*"]保证工具定义字节和父级完全一致,这是 cache 命中的前提;permissionMode: "bubble"让子 Agent 遇到需授权的操作时冒泡到父终端,而不是静默拒绝。

注意:deny: ["Agent"]是给 Fork worker 用的兜底——即使工具池里有 Agent 工具,权限规则也会拦住它再次派生,和prevent_recursive_fork形成双重防护。

4. 验证请求:一次子 Agent 派生与 Fork 分叉

配置就绪后,跑一次真实的分叉验证。目标是让主 Agent 派生两个 Fork 子 Agent 并行分析代码库,然后检查缓存命中。

4.1 触发 Fork

在 Claude Code 里输入一个会触发分叉的任务,比如:

分析这个项目的 src/ 目录,分别研究 auth 模块和 db 模块的依赖关系,并行做。

主 Agent 会调用 AgentTool,由于没指定subagent_type且 Fork 已开启,路由走 fork 路径。你会看到类似输出:

Fork started — processing in background Fork started — processing in background

两个 Fork 同时启动,各自继承父级对话历史。

4.2 确认调用链路

开另一个终端看请求日志,确认所有请求都打到 TaoToken 通道:

tail -f ~/.claude/logs/api.log | grep -E "base_url|model|cache"

正常应该看到两条几乎同时发出的请求,base_url都是https://taotoken.net/api,model都是claude-sonnet-4-20250514(继承父级),且第二条请求的cache_read_input_tokens明显大于 0——这就是 Prompt Cache 命中的证据。

4.3 检查缓存命中

用一段脚本统计缓存情况:

grep "cache_read_input_tokens" ~/.claude/logs/api.log | \ awk -F'"' '{sum+=$4} END {print "总缓存读取 tokens:", sum}'

如果两个 Fork 共享了前缀,第二个 Fork 的cache_read_input_tokens应该接近第一个的输入长度。实测下来,两个 Fork 并行时缓存命中率能到 70% 以上,重复上下文开销显著下降。

4.4 确认结果隔离

两个 Fork 完成后,主 Agent 收到的是结构化报告,而不是中间的工具调用过程。检查主对话上下文长度,应该只增加了报告文本,没有把两个子 Agent 读文件、grep 的中间消息拉进来。这就是状态隔离生效——readFileState被克隆、UI 回调被置空、setAppState变成 no-op。

5. 本篇常见错排查

5.1 Fork 报 "Fork is not available inside a forked worker"

这是递归 Fork 防护触发了。原因通常是prevent_recursive_fork没开,或者 Fork worker 的工具池里 Agent 工具没被权限规则拦住。检查settings.json的deny列表里有没有Agent,以及config.toml的prevent_recursive_fork = true。

5.2 缓存命中率为 0

三个常见原因:一是 Fork 子 Agent 设了不同model,改成inherit;二是tools定义和父级不一致,Fork 必须用["*"];三是contentReplacementState没克隆,导致对同一批tool_use_id做了不同替换决策。前两个改配置,第三个确认用的是支持克隆的版本。

5.3 子 Agent 权限弹窗不出现

如果子 Agent 遇到需授权操作时直接失败而不是冒泡,检查permissionMode是不是bubble。异步 Agent 默认静默拒绝权限提示,只有bubble模式才会冒泡到父终端。

5.4 请求 401 或通道不通

先跑第 2 节那条 curl 确认 Key 有效。如果 curl 通但 Claude Code 不通,检查ANTHROPIC_BASE_URL有没有被其他配置覆盖,以及config.toml里api_key_env指向的环境变量名对不对。

5.5 子 Agent 修改了父级状态

症状是主对话的 todos 或 UI 被意外改动。这是setAppState没隔离。确认子 Agent 上下文用的是setAppState: () => {}的 no-op 版本,只有需要更新父级 UI 的交互式子 Agent 才共享。

6. 下一步:把统一 Key 用到长期编码场景

子 Agent 和 Fork 跑通后,你会发现多 Agent 协作的瓶颈从"能不能跑"变成了"跑得贵不贵"。统一 Key 解决了配置散乱,Prompt Cache 解决了重复上下文,但长期编码和 Agent 常驻场景还需要更稳定的通道和额度管理。

如果你打算把多 Agent 协作用在日常开发里,建议接着看 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite ,它针对长期编码和 Agent 常驻做了额度与通道优化。接入细节和参数说明在接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,遇到通道问题先翻这里。想单独验证某个模型在 Fork 场景下的表现,用模型对话 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 快速试。Key 管理和轮换在控制台 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。

我踩过的坑是:一开始图省事给 Fork 子 Agent 单独配了 haiku 想省钱,结果缓存全失效,总成本反而更高。后来统一成inherit,让缓存命中把成本压下来,才是正解。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询