☰
并行Agent费用翻4倍?给子Agent指定小模型省一半成本
2026/9/28 16:04:08 网站建设 项目流程

上周我把一个大模块的重构拆成四个独立任务,开了四个 Agent 并行跑,本想着能省一晚上的时间。结果第二天看到账单,API 消耗直接翻了 4 倍,数字大到让人肉疼。问题不在我用的模型本身变贵了,而是这 4 个 Agent 全在用又大又全的配置,做那些本来只需要小模型就能完成的活。

准确说,是 Claude Code 在并行调度子任务时,把主会话的模型设置一路传递了下去。最后真正把账单压回来的,不是少开 Agent,也不是把主模型换便宜,而是只动了一个配置:给只读、检索、总结这类子 Agent 单独指定小模型。就这么一个字段,省下来的钱比我想象中还夸张。

这篇把整个排查链路、费用结构和这个配置的用法一起捋一遍,给同样在玩 Agent 并行开发的人做个参考。

1. 事情是怎么失控的

1.1 我当时的并行方式

我当时的场景挺典型:手上有四个改动方向,分别是接口重构、日志链路调整、测试用例修补、文档同步更新。这几个方向虽然都落在同一个仓库里,但涉及的文件基本不重叠,逻辑上也相对独立,按道理很适合并行处理。

于是我在终端里开了四个 Claude Code 会话,用了类似 tmux 多窗口那种方式,四个会话同时跑。另外主会话里我还挂了几个子任务,用来做代码搜索、文件阅读和变更摘要。从编排角度看,这已经是一个典型的 Agent 框架用法了:一个主 Agent 负责任务拆解和决策,多个子 Agent 分别执行窄任务。

概念上没问题,账单一出来问题就大了。我翻了下费用明细,四个会话并行跑了大约一个多小时,输入 token 消耗几乎是原来单用户会话的六倍,总费用则到了原来的四倍多。第一反应是模型是不是被切成更贵的档位了,结果查了一圈,模型没变,变的是每一笔请求都在重复付“读资料”的钱。

1.2 账单结构长什么样

我去控制台把按模型拆分的用量拉出来,看到了一个很典型的现象:output token 其实没有暴涨很多,真正暴涨的是 input token。如果把一次完整请求拆开看,里面大头不是模型生成回复的那段,而是每次都要带上的 system prompt、工具定义、代码索引、历史消息,这一大坨都按 input 计费。

以我当时的基线做参照,大概是这样一组数据:

场景输入 token 消耗输出 token 消耗缓存命中率账单变化
单会话、单轮小任务基线 1x基线 1x较高基线
单会话长任务2-3x1.5x中等1.5-2x
4 个会话全并行6-8x2x很低4x+
4 个并行 + 子 Agent 继承主模型10x+3x极低6-8x

我属于最后一行那种情况,既开了多会话,又在会话里继续派生子 Agent。两个因素叠在一起,账单自然就压不住了。

1.3 什么任务适合并行,什么不适合

这里要先说一句公道话,并行 Agent 不是原罪。它最适合的场景是任务之间文件不重叠、状态不共享,比如我刚才说的接口重构和文档更新,各改各的文件,互不影响。

真正不适合的,是多个 Agent 同时写同一个文件,或者多个 Agent 共享同一份可变状态。我见过有人让两个 Agent 同时改一个配置文件,A 改完 B 又覆盖回来,两边反复“救火”,来回折腾了七八轮才结束。每一轮都是一次完整的 API 请求,成本直接线性叠加。这种不是提效,是花钱买冲突。

所以并行之前,先判断依赖关系。依赖关系清楚的,并行是效率放大器;依赖关系乱成一团的,并行只会让 Agent 框架替你承担“沟通成本”,最终的代价还是会落在账单上。

2. 账单为什么翻 4 倍:三个问题叠加

2.1 基础上下文被多份重复计费

这是最核心的机制问题。每次调用 API,模型并不知道上一个请求发生了什么,它看到的只有当前请求里携带的上下文。Claude Code 为了让对话连续,会把之前的消息、工具结果、文件内容一并塞进下一次请求。这个设计在单会话时没问题,一旦并行,问题就来了。

四个会话各自维护独立的上下文,等于同一份代码库摘要、同一份 system prompt、同一批工具定义被复制了四份。每一份都按 input token 计费。这不是四倍的小开销,而是好几倍的重复开销。

我当时请了四个“专家”来改代码,每请一位专家,都要把整摞资料从头念一遍。四个专家同时进场,就是四份资料的重复阅读费。更关键的是,这些资料里大量内容是重复的,系统提示词一样、项目说明一样、最近一次 git 变更一样,但它们分散在四个不同的上下文里,谁也共享不了谁。

这里就牵出 Anthropic 的 prompt caching 机制。它本意是好的:请求里命中缓存的部分,按很低的折扣计费。但缓存命中有前提,它依赖请求前缀的一致性。四个并行会话如果从不同的工作目录启动,废话不多说继续把错误分摊到四份独立账单里,缓存几乎全部落空。缓存命中率一旦跌到谷底,成本就不是线性涨,而是几何级涨。

2.2 模型继承导致“高射炮打蚊子”

第二个问题出在模型选择上。Claude Code 的自定义 Agent 允许你给每个 Agent 单独指定模型,但如果你不写这个字段,很多情况下它会沿用主会话的模型设置。

我最初图省事,直接在 settings 里把主模型设成了很强的档位,想着这样能保证质量。结果所有子 Agent 也全部走了这个模型计费。检索一段代码、总结一个文件、跑一遍测试结果,这些都算在贵模型头上。打个比方,让全科主任医师去给每个病人量体温,体温是量得准,可这个人力成本完全不合理。

更隐蔽的是,子 Agent 有时候还会被用于一些后台辅助任务,比如自动生成任务标题、整理变更摘要。这些任务的输入输出都不长,但请求次数频繁。如果它们也继承贵模型,那每一笔小额支出都会变成一个小额放大镜,次数一多,总额就非常可观。

真正合理的用法是分级:需要推理、规划、改代码的任务,用强模型;只做检索、过滤、摘要、格式整理的任务,用便宜模型。就像团队里既有架构师也有实习生,架构师定方案,实习生收集资料,这样才能把人力成本压到最低。

2.3 失败重试与工具膨胀的隐形消耗

这一块是最容易被忽视的。并行 Agent 跑起来之后,非常容易触发 API 的速率限制,报错信息会直接出现在终端里,类似 agent execution terminated due to error。Claude Code 遇到这类错误,通常会做自动重试。一次重试不是重新算一遍这么简单,而是把整个请求重新发送一遍,等于同样的成本再付一次。

我排查日志的时候发现,最严重的那个会话在十分钟内重试了六次,其中有三次是限流导致的,有两次是上下文超长被截断后重推。这些重试请求基本没有产出有效结果,却全部按正常 token 计费。这就解释了为什么我的 output token 没有暴涨,但总费用还是冲了上去。

另一个大坑是工具定义膨胀。Claude Code 里挂的 MCP 服务器、插件、自定义工具,每个请求都要带上工具描述。工具越多,每次请求的 input token 越大。单个会话可能感觉不出来,四个会话并行之后,工具定义被重复加载四遍,哪怕没实际调用,描述文本也已经计入费用了。如果某个 MCP 服务器的描述写得特别啰嗦,那它几乎是在偷偷烧钱。

3. 一个配置解决:给子 Agent 指定专用模型

3.1 配置入口和具体写法

先说结论,这个配置写在项目的.claude/agents/目录里。Claude Code 允许你用 Markdown 文件定义自定义 Agent,每个文件代表一个 Agent,文件头部有一段 YAML frontmatter,里面可以声明 name、description、tools 和 model。

我的做法是,给使用频率最高的几个子 Agent 分别建了文件,并且统一加上了 model 字段,全部指向便宜的小模型。

举个例子,我建了一个代码检索 Agent:

--- name: code-searcher description: 在仓库中检索代码、查找定义和引用关系,输出结构化结果 tools: Read, Grep, Glob model: claude-haiku ---

再比如变更摘要 Agent:

--- name: change-summarizer description: 读取 git diff 和相关文件,生成简洁的变更说明 tools: Read, Grep model: claude-haiku ---

关键就是那个 model 字段。没有这个字段时,子 Agent 走的是主会话的模型配置,费用高;填上之后,它就按照你指定的模型去跑,单价立刻降下来。这就是标题里说的那一个配置。

可能有读者会问,所有子 Agent 都写 model 字段会不会很麻烦。我的经验是值得的,你只需要给那些高频、窄任务、只读类型的 Agent 写上小模型,真正负责写代码的主力 Agent 保留强模型就行。一个仓库里这种文件的个数通常不超过十个,一次配置,长期生效。

3.2 配置之后账单发生了什么变化

我改完配置之后,重新跑了一轮同样的任务,效果非常直接。子 Agent 承担了大量检索、阅读、摘要工作,这些工作以前按强模型计费,现在按小模型计费,成本单价大概下降了一个数量级。整体账单回到开并行之前的水准,某些重复性任务甚至比单会话全量跑还低。

成本变低不等于质量下降。关键是我把任务边界也理清了:子 Agent 只做范围明确的窄任务,最终方案和代码改动还是由主 Agent 拍板。窄任务对模型能力的要求本来就不高,用便宜模型完全够用。反而是以前那种让强模型去反复检索文件的做法,既浪费钱,速度还慢。

这里给一个直观的换算思路。假设一次子任务消耗的 input token 相同,模型 A 的输入单价约为模型 B 的十分之一,那么同样的任务,单位成本就是原来的十分之一。如果整个工作流里有六成 token 消耗发生在子 Agent 身上,那总成本能省掉差不多一半以上。这是最简单的算术,但前提是这个配置得真的写对。

3.3 如果你还是想开多个终端会话

如果你和我一样,确实需要同时开多个终端会话跑不同任务,那除了子 Agent 配置,还有几个配套做法需要跟上。

第一,尽量用 continue 模式延续会话,不要每次都从全新的空会话开始。延续会话至少能保住一部分 prompt 前缀,让缓存命中率不至于跌到零。我从多个会话平行切到续跑模式之后,缓存命中率上来了,input token 的浪费少了不少。

第二,不同任务不要各自为战地开在不同目录。Claude Code 的上下文很吃工作目录,目录不同、加载的 MCP 配置不同,缓存前缀就对不上。要么统一在同一个项目根目录启动,要么干脆就用子 Agent 来区分任务,而不是再开一整份会话上下文。

第三,控制并发上限。一个简单的 Bash 脚本就能做到串行队列:

for task in task-a task-b task-c task-d; do echo "running $task" claude -p "执行 $task 目录下的重构任务,只输出最终变更" done

这个脚本把四个任务排成队,每个跑完再跑下一个。虽然总耗时变长了,但成本比四个全并行低很多。如果你想微调,也可以用类似 GNU parallel 的工具控制最大并行数设为 2,效果介于全并行和全串行之间。

4. 排查方法和避坑清单

4.1 快速定位账单增长点

遇到账单异常,第一件事不是去改配置,而是先搞清楚钱花在哪。我建议去 Anthropic 控制台的用量页面,按模型维度看 token 消耗分布。如果发现某个贵模型的 input token 数量远超你预期,那大概率就是模型继承问题。

第二个办法是看缓存命中率。控制台通常能体现缓存相关数据,缓存命中率的趋势一旦明显下行,就可以怀疑是并行会话导致的重复上下文。这时候把多个会话改成续跑模式,或者统一从同一目录启动,命中率会很快回暖。

第三个办法是开调试模式观察请求细节。Claude Code 支持查看请求日志,你可以确认每个请求实际使用的模型名称,看看是不是有子 Agent 在偷偷用贵模型。这个日志在排查阶段特别有用,比对着账单猜要快得多。

4.2 避坑速查表

场景现象处理方法
子 Agent 未指定模型用量记录里贵模型 input 暴涨在.claude/agents/里给子 Agent 写 model 字段
多个会话并行缓存命中率极低,input 重复上涨用 continue 延续会话,或改用子 Agent 而非重量级会话
MCP 服务器挂太多每次请求 tools 描述很大精简子 Agent 的 tools,不往子 Agent 堆一堆 MCP 服务器
频繁报错重试成功次数少但费用高降低并发数,检查是否触发速率限制,必要时做任务排队
上下文被截断后重推输出 token 不高但 input 异常高调小单次任务范围,不要让一个会话揽全仓库的活

这张表基本覆盖了我这次踩坑的所有场景。对照着排查,半小时内就能定位到问题根因。

4.3 几个容易被忽略的细节

再分享几个细节层面的坑。

第一,子 Agent 里的 tools 越少越好。tools 字段不只是权限声明,它还会直接影响每次请求携带的工具描述。子 Agent 能干活的前提是它有足够的工具,但给它塞一堆不需要的 MCP 工具,只会让 input token 白白膨胀。

第二,注意配置文件的覆盖顺序。Claude Code 的配置有全局、项目、本地之分,.claude/settings.local.json会覆盖项目配置。如果你改了项目配置但没生效,先检查本地配置里是不是有同名项。

第三,给 Agent 命名的时候,description 要写得具体一点。Claude Code 调度子 Agent 时,会根据 description 判断该调哪个 Agent。描述含糊会导致主 Agent 选错子 Agent,选错了就得重新跑,来回折腾的每一轮都是钱。把 description 写清楚,比如“只负责检索,不负责修改代码”,调度准确率会高很多。

5. 成本优化不是不开 Agent,而是分级

5.1 让每一层 Agent 干它该干的活

经过这一轮折腾,我对 Agent 编排的理解变了不少。以前总觉得 Agent 多开就是提效,现在更倾向于把 Agent 分成不同层级,每层用不同模型、不同工具、不同权限。

主 Agent 承担规划、决策、代码修改,它需要强模型和完整工具链;子 Agent 承担检索、验证、摘要、翻译,它需要小模型和窄工具集。这种分级方式,和 Agent 框架里的 harness 与 agent 的关系很类似,harness 提供运行环境和调度骨架,agent 在骨架里执行具体任务。框架解决了“怎么跑起来”的问题,但没帮你解决“谁该用什么模型”的问题,后者得自己配置。

Skill 和 Agent 的区别也值得拎出来说一下。Skill 更像是一组能力包,比如“代码审查技能包”“测试生成技能包”,它不绑定模型,可以被不同 Agent 调用。Agent 则是带模型、带工具、带权限的执行单元。成本优化的重点不在 Skill,而在 Agent 的模型和工具组合。模型贵不贵、工具多不多,直接决定了每一轮任务的单价。

5.2 警惕 Agent 记忆带来的上下文重复

热词里有 Agent 记忆相关的讨论,我也踩到了边。并行 Agent 各自有各自的上下文,彼此不知道对方已经读过哪些文件。如果每个 Agent 为了完成任务,都把仓库的核心文件重新读一遍,那多 Agent 的记忆优势就变成了成本灾难。

解决方式也很简单:任务描述里给出足够上下文,但不要给整段对话粘贴。比如子 Agent 需要知道某个函数的位置,直接把函数签名和文件路径给它,而不是让它自己从头读一遍整个项目。更不要在主上下文里塞入子 Agent 已经读过的东西,能不重复就不重复。

我这里要特别提醒,多个 Agent 并行改代码时,最好的状态是“各看各的文件”,最怕的状态是“每个人都把项目目录扫一遍”。想判断是不是犯了这个错,可以看每次请求的 token 数,如果单个请求动不动就几万 input token,且其中大部分是和任务无关的全局文件,那就要做上下文收敛。

5.3 把配置沉淀进仓库,团队一起受益

这个改善不能只停留在个人配置里。我最后把.claude/agents/目录提交到了仓库,里面每个 Agent 文件都写清楚了模型和工具,团队其他人拉下来就能直接用。这样大家都不会掉进模型继承的坑,新人也省得自己从头摸索。

另外,我还在项目 settings 里做了预算相关的提醒,隔一段时间看一眼用量,不用等账单炸了才反应。成本优化的本质不是不开 Agent,而是用最合适的配置,让每个 Agent 干最擅长的事,付最匹配的价钱。

我这几天把配置改成上面的样子,并行还是照开,只是每个子代理的工具和模型都做了收敛。实测账单回到开并行之前的水准,某些重复性任务甚至更低。最后再提醒一句,别只看模型单价,子代理的工具数量、缓存命中率、自动重试次数才是隐藏账单。先把模型分级这个配置补上,再谈多 Agent 提效。

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

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

立即咨询