工程复利能否复现?Hermes Agent 子代理用 TaoToken Key 做对照
2026/9/18 2:36:15 网站建设 项目流程

1. 把「工程复利」翻译成对照组:先固定供应商层

Elvis Saravia 转评 NousResearch 子代理重构案例时抛出两个反问:换个 harness 还成立吗、子代理少一些会不会更省。我想把这两个问题落到本地可跑的对照实验上,工具链选 TaoToken(官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab )。

外部讨论里最容易被记住的是一串规模和耗时数字,但对一线工程师来说,那些数字既不可验证也不可迁移:换一个客户端、换一套工具调用协议、换一种上下文裁剪策略,结果可能完全反过来。真正值得复现的不是「多少个子代理」,而是边际收益曲线——每增加一档并发,通过验收的补丁数涨了多少,token 花掉了多少,返工了几次。要让这条曲线可信,实验里必须有一个变量被彻底固定住:模型的调用入口。如果供应商层是浮动的,你测出来的差异到底是并发数带来的,还是某个渠道悄悄换了模型版本带来的,就永远说不清。

所以这篇的路径是:先把 Key 与 Base URL 放到一个可计量、可切换、可回滚的位置,再设计对照组。客户端侧统一把 Base URL 写成https://taotoken.net/api,两套常用 harness(Claude Code 与 Codex)分别用原生配置格式接入,不混用前缀,不互相套用环境变量。

对照组的最小设计如下,先看结构,具体参数在后面第 6 节展开:

组别子代理并发任务粒度上下文预算验收口径
A 串行单代理1单文件32k单测 + 类型检查
B 少子代理4模块级48k单测 + lint + diff 抽查
C 多子代理16函数级24k单测 + diff 抽查

三组共用同一批任务切片、同一份验收脚本、同一档模型,唯一变化的是并发与任务粒度。只有 A/B/C 的差异才有解释力,绝对值不重要,重要的是 A→B 与 B→C 这两段的斜率。

2. TaoToken 侧准备:Key、模型清单与 Base URL 的落地顺序

这一步不要跳,顺序错了后面排障会翻倍。

第一步,拿到可用凭证。打开官网入口 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab ,完成账号流程后进入控制台的密钥页面 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab 。这里生成的 Key 就是后文所有配置里的YOUR_API_KEY占位符替代品。建议一次生成两把:一把给 Claude Code,一把给 Codex,方便按 harness 分别统计用量,也方便某一把泄露时单独吊销。

第二步,确认模型标识怎么写。不同客户端的模型字段格式不一样,直接抄别人的字符串很容易踩空。在模型对话页 https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab 里找到你要用于实验的那一档,把它的标识原样复制下来,后面填进settings.jsonconfig.toml。子代理实验里建议同时定好一个「小模型」——用于低风险的文件摘要、目录扫描这类任务,能显著压低 B/C 两组的前期开销。

第三步,记住 Base URL。工具配置里的地址统一为:

https://taotoken.net/api

注意,这个地址是给客户端填的,不要在后面手拼多余的路径段。如果你的客户端在界面上要求「带版本号」的写法,以官方页面上的说明为准,不要凭经验猜。

第四步,评估预算档位。子代理实验的特点是「请求数远超人类手动操作」。一次几十上百个子任务的并发,会把调用量抬得很高。如果只是短期做对照,按量计费就够;如果打算把这类流程固化成日常开发的一部分,先看一眼 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab ,把预算上限锚定下来再开跑,比跑完再看账单理智得多。

完成这四步之后,先做一次最小连通性验证,别急着上并发:

# 只验证地址可达,不校验凭证,看状态码即可 curl -sS -o /dev/null -w "http_code=%{http_code}\n" https://taotoken.net/api # 真正的最小可用性验证交给客户端本体,避免手搓请求带来的路径误判 export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" claude -p "只回复 pong,不要调用任何工具"

只要最后一步能稳定返回,说明 Key、地址、模型三段链路是通的,可以进入配置固化阶段。

3. Claude Code:settings.json 里的 ANTHROPIC_* 与权限白名单

Claude Code 走的是ANTHROPIC_*前缀,配置文件是settings.json。实验场景下我建议直接写进项目级配置,而不是只在终端里 export——因为子代理是并行拉起的,任何一个子进程没继承到环境变量,你看到的失败原因都会指向别处。

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "your-main-model-id", "ANTHROPIC_SMALL_FAST_MODEL": "your-small-model-id" }, "permissions": { "allow": [ "Bash(pytest:*)", "Bash(python -m pytest:*)", "Bash(git diff:*)", "Bash(rg:*)" ], "deny": [ "Bash(git push:*)", "Bash(git reset --hard:*)", "Bash(rm -rf:*)", "Read(./.env)" ] } }

几个必须注意的点:

ANTHROPIC_AUTH_TOKENANTHROPIC_API_KEY是两个不同的变量名,客户端版本不同时识别的那个可能不一样。如果配置后仍然报鉴权失败,先把两个都试一遍,确认哪一个生效,再删掉多余的那个,不要长期双写。

ANTHROPIC_MODELANTHROPIC_SMALL_FAST_MODEL建议都显式指定。多子代理场景下,目录遍历、文件摘要这类任务如果落到主模型上,成本会明显偏离预期,导致 C 组的对照结果被预算而不是被架构影响。

权限白名单要提前收敛。子代理并发跑起来之后,每个进程都会独立申请工具权限;如果白名单太宽,一次误操作会同时被放大到十几个进程里。deny 列表里放git pushrm -rf这类不可逆命令,是保底做法。

如果你更习惯用终端环境变量(例如想快速切档对比),可以这样临时覆盖:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" export ANTHROPIC_MODEL="your-main-model-id" export ANTHROPIC_SMALL_FAST_MODEL="your-small-model-id" # 确认当前 shell 里生效的是哪一套 env | grep -E '^ANTHROPIC_'

关键提醒:ANTHROPIC_*只属于 Claude Code 这一侧,不要把它套到 Codex 上。两套 harness 的配置体系完全不同,混用会得到一堆看不懂的报错。

4. Codex:config.toml 里另起一个 model_provider,别复用 ANTHROPIC_*

Codex 走 TOML 配置,核心是声明一个自定义 provider,然后把 profile 指过去。它不读ANTHROPIC_*,所以第 3 节的变量在 Codex 这里一个都不要写。

# ~/.codex/config.toml model = "your-main-model-id" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat" [profiles.taotoken] model_provider = "taotoken" model = "your-main-model-id"

凭证通过环境变量注入,变量名要和env_key保持一致:

export TAOTOKEN_API_KEY="YOUR_API_KEY" # 校验 Codex 读到的 provider 配置 grep -n -A 6 "model_providers" ~/.codex/config.toml

排障时按这个顺序看:

先看model_provider有没有指到taotoken,默认值不对是最常见的问题;再看base_url是不是被手写成了带额外路径的形式;最后确认env_key指定的变量在当前 shell 里真的存在。wire_api这一项如果和平台提供的接口规格不匹配,表现通常是请求发出去了但响应解析失败,而不是明确的 4xx,容易被误判成网络问题。

Codex 侧不需要为子代理单独建 profile——实验里并发由外层脚本控制,客户端只负责单次调用是否正确。这一点和 Claude Code 不同:Claude Code 自己有子任务派发能力,Codex 这侧的把控点主要在外层调度脚本上。

5. CC Switch 三件套:两套 harness 的 Key 与 Base URL 分帐管理

一旦同时跑 Claude Code 和 Codex,配置就会分散在至少两个文件加两组环境变量里。切换时手工改,出错概率极高。用 CC Switch 这类切换工具时,把关注点收拢成三块,检查完这三块基本不会出问题:

件数内容检查点出错表现
供应商条目base_url必须是https://taotoken.net/api404 或连接被拒
凭证条目API Key与 harness 一一对应,不串用401 / 403
激活项当前生效配置切换后重启终端与 IDE改了配置但行为没变

对应的落地动作:

# 切换前先备份,回滚成本最低 cp ~/.claude/settings.json ~/.claude/settings.json.bak cp ~/.codex/config.toml ~/.codex/config.toml.bak # 切换后强制重启终端与编辑器,再验证实际生效值 env | grep -E 'ANTHROPIC_(BASE_URL|AUTH_TOKEN)' env | grep -E 'TAOTOKEN_API_KEY' grep -n "base_url" ~/.codex/config.toml

最容易踩的坑是「激活项已经切了,但当前终端里的旧变量还在」。子代理并发启动的是一批新进程,它们继承的是父进程的环境,父进程如果还挂着上一套凭证,整批子任务都会打到错误的配置上。切换动作之后,一定要重新开一个终端再验证一次。

第二容易踩的坑是凭证串用:把 Claude Code 的 Key 填进 Codex 的env_key变量。两把 Key 都指向同一个账号时,这个问题不会立刻报错,但会把用量统计搅在一起,后面填成本汇总表时无法按 harness 拆分。给两把 Key 起可区分的名字,是最省事的预防措施。

6. 对照实验参数表与成本汇总表怎么填

实验能不能复现,取决于参数有没有被写死。下面这张表建议直接抄进你的实验记录里,跑之前先填满,跑完只补右边两列。

参数A 串行B 少并发C 多并发
子代理并发上限1416
单任务上下文预算32k48k24k
单任务最大工具调用轮次202012
超时(秒)600600300
失败重试次数110
验收脚本版本v1v1v1
模型标识同一档同一档同一档
小模型标识同一档同一档同一档

三条纪律:

超时和重试次数必须在三组之间保持一致的「单次任务」口径,否则 C 组的失败率会被超时设置掩盖掉。重试设为 0 是有意为之——多并发下自动重试会让成本失控,失败就让外层脚本记录并跳过。

验收脚本必须锁定版本。中途改一次验收标准,前面所有数据作废。

任务切片要提前固定,并且三组使用完全相同的切片集合。切片粒度不同(函数级 vs 文件级)是比较维度之一,不能同时又当变量又当噪声。

跑完之后,成本汇总表这样填:

组别请求数输入 token输出 token单任务平均成本验收通过率返工次数
A 串行待填待填待填待填待填待填
B 少并发待填待填待填待填待填待填
C 多并发待填待填待填待填待填待填

示例格式(数值需替换为你自己的实测结果,不要直接引用):A | 42 | 210000 | 18000 | 0.031 | 76% | 5

汇总不要手工做。让每次调用的 usage 落成 JSONL,一行一条,本地跑脚本聚合:

# aggregate_cost.py # 用法: python aggregate_cost.py usage.jsonl <输入单价/百万token> <输出单价/百万token> import json import sys from collections import defaultdict def iter_records(path): with open(path, "r", encoding="utf-8") as handle: for line in handle: line = line.strip() if line: yield json.loads(line) def main(path, price_in, price_out): agg = defaultdict(lambda: {"in": 0, "out": 0, "calls": 0}) for rec in iter_records(path): group = rec["group"] agg[group]["in"] += rec["usage"]["prompt_tokens"] agg[group]["out"] += rec["usage"]["completion_tokens"] agg[group]["calls"] += 1 for group in sorted(agg): item = agg[group] cost = item["in"] / 1e6 * price_in + item["out"] / 1e6 * price_out avg = cost / item["calls"] if item["calls"] else 0 print( f"{group}\tcalls={item['calls']}\t" f"in={item['in']}\tout={item['out']}\t" f"cost={cost:.4f}\tavg={avg:.4f}" ) if __name__ == "__main__": main(sys.argv[1], float(sys.argv[2]), float(sys.argv[3]))

注意group字段是在外层调度脚本里写进去的,不是客户端返回的。如果你不显式打标,聚合结果就只能按天汇总,无法区分 A/B/C。这个字段是整个成本分析的地基,别省。

7. 子代理并发常见的五类报错与定位顺序

按出现频率从高到低:

401 / 403。先确认 Key 是否和 harness 匹配,再确认是否被环境变量覆盖。执行env | grep -E 'ANTHROPIC_|TAOTOKEN_'看实际生效值,比翻配置文件快。如果只有部分子进程失败,通常是父进程的环境清理逻辑导致的,检查调度脚本里有没有重置环境的语句。

404 或路径类错误。九成是把 Base URL 写成了自定义拼接的形式。回到https://taotoken.net/api这个原始值,删掉所有手工追加的路径段再试。

429 限流。多并发场景几乎必然遇到。正确做法是把并发上限当作变量来调,而不是把重试次数调大——重试会把限流变成雪崩。把 C 组的并发从 16 降到 8 再跑一次,观察通过率是否反而上升,这本身就是有价值的数据点。

上下文超限。表现为请求被拒或响应被截断。子代理天然吃上下文:每个子任务都要带一份文件内容加指令。控制手段是缩小任务切片和减少工具返回体积,而不是单纯提高上限——上限调高会让单位成本涨得更快。

工具调用参数被截断。多步骤任务里比较隐蔽的问题:模型输出的参数不完整,工具调用失败,子代理转而用错误的参数继续执行。定位方法是把每个子任务的完整请求与响应落到本地文件,出现异常时逐个比对,而不是只看最终结果。这一步的日志量会很大,建议按组别分目录存放,跑完即归档。

排障顺序建议固定为:凭证 → 地址 → 限流 → 上下文 → 工具调用。从外到内,绝大多数问题在前两步就能收敛。

8. 什么情况下复利不成立:三条止损线

回到最初那两个反问。子代理数量少一些是否更省,取决于任务本身的可切分程度。如果任务切片之间高度耦合,并行度越高,冲突和返工越多,成本曲线会在某个点之后上翘。三条止损线可以帮助你尽早停手:

第一,当单任务平均成本下降但验收通过率同步下降时,说明省下来的钱是从质量里扣的,实验到此为止。第二,当返工次数超过请求数的两成时,说明任务切片粒度定错了,先修切片再谈并发。第三,当同一批任务在 A 组用串行方式也能在可接受时间内完成时,多并发只是把等待时间换成了协调成本,账面上不划算。

至于换一个 harness 是否成立:从上面的配置可以看出,两套客户端的接入层完全不同,但实验结论依赖的是调用层的行为——模型档位、上下文预算、验收口径。只要这三项在切换前后保持一致,结论大概率是可迁移的;一旦其中一项被迫改动,就要把它当成新实验重新记录参数,而不是沿用旧结论。

如果你准备把这套对照实验真正跑一遍,建议按这个顺序走:先在模型对话页确认要用的模型标识,再评估预算档位,然后创建两把独立的 Key,最后照 Claude Code 的文档把settings.json配好,先串行跑通一个任务,再放开并发。链路:模型对话 https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab → Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab → 创建 Key https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab → Claude Code 文档 https://taotoken.net/doc/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab 。配置入口统一从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=hermes_agent_subagent_ab 进,客户端 Base URL 认准https://taotoken.net/api,实验数据才有可比性。

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

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

立即咨询