我的 Agent Orchestrator 每个任务消耗了 100-200 万个 Opus token。
成本是如何爆炸式增长的
该编排器是为 Claude Code 构建的,并采用了层级化的子代理(sub-agents)架构。每个子代理都会继承父代理的设置,运行自己的提示词(prompt),并将结果反馈回循环中,直到审核员宣布输出“干净”为止。该工具虽然完成了任务,但价格却极其昂贵。
三个隐藏的“税收”倍增了 token 数量:
- 模型税 (Model tax) – 子代理从未指定模型,因此它们默认使用了最昂贵的 Opus 层级。一个本可以用更便宜的模型(Haiku 或 Sonnet)完成的小型操作,却按 Opus 的费率计费。
- 缓存税 (Cache tax) – 提示词缓存(Prompt caching)仅能重用字节级完全匹配的内容。由于每个子代理都会添加自定义指令,每一次调用都会强制进行冷缓存写入(cold cache write)。父代理的缓存无法被重用,从而浪费了共享缓存通常能提供的节省。
- 循环税 (Loop tax) – “循环直到干净”的规则使得只要审核员发现任何瑕疵,流程就会一直持续下去。由于没有设置硬性上限,循环会一直运行直到模型停止。
这些乘数效应共同作用,将寥寥几行代码变成了一场 token 雪崩。
为什么提示词中的预算规则失效了
最初的设计试图通过将预算规则直接嵌入到系统提示词(system prompt)中来抑制支出。理论上,告诉模型“保持在 X 个 token 以内”应该能限制使用量。但在实践中,基于提示词的规则仅仅是一种“偏好”。随着会话(session)的增长,模型会压缩上下文,并可能完全丢弃或忽略这些指令。结果是:模型的表现就像该规则从未存在过一样。
将执行权从提示词转移到代码
重新设计将预算逻辑从提示词中剥离出来,并将其放入一个模型无法覆盖的确定性钩子系统(deterministic hook system)中。
- 显式模型选择 – 现在的每次子代理调度(dispatch)都需要一个具体的模型选择(Haiku、Sonnet 或 Opus)。不再有隐式继承,因此廉价任务保持廉价。
- 通过 PreToolUse 钩子设置硬性防护 – 在任何工具运行之前,钩子会检查:
- 会话中已经进行的调度次数。
- 所选模型是否符合最低层级(防止误用 Opus)。
- 最大循环迭代次数,超过该次数后流程将中止。
如果触发了任何防护措施,代码会中止子代理;语言模型无法通过辩论来强行恢复运行。
这对开发者意味着什么
任何实施支出上限、安全策略或破坏性命令限制的系统,都应将这些约束视为代码,而非对话引导。提示词可能会被覆盖、忽略或在模型的内部压缩中丢失。相比之下,代码是确定性执行的,并且是可以审计的。
