
并行编码代理优化:每行代码token消耗降低3.3倍
来源标题:The same work on a third of the tokens: tuning a fleet of coding agents
通过十周内六项调整,并行编码代理每改动一行代码消耗的token减少了3.3倍,同时每周合并的PR数量提升4.4倍,总token用量还下降19%。作者利用Claude Code本地保存的对话记录进行测量,并将节省的token用于完成更多任务而非延长预算。单个PR的平均改动行数从约1400行降至850行,使每个合并PR的token消耗降幅达约5.5倍。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
摘要:Coding agent 会消耗大量 token。当我开始在一个项目上并行运行四个 agent 时,原本一周的 token 预算大约一天就用完了。十周、六项改动之后,每改动一行代码所消耗的 token 降到了原来的三分之一(3.3 倍)。我把省下来的额度用在多做事情上,而不是让预算撑得更久:现在这些 agent 每周合并的 PR 数量是原来的 4.4 倍,而每周消耗的 token 反而少了 19%。
本文说明 token 都花在了哪里、我如何从 Claude Code 已经保存在磁盘上的对话记录中测量出这些数字,以及哪些改动有效、哪些无效。一篇配套文章介绍项目本身,以及它的代码是如何保持可控的。
基于十周对话记录的测量结果:
同样的代码现在消耗不到三分之一的 token。每改动一行代码的 token 数下降了 3.3 倍,若按各类 token 的价格加权计算则约为 2.5 倍。这是最核心的数字,因为它不取决于工作如何拆分到各个 PR。PR 也变小了,所以每个 PR 的 token 数降得更多。平均每个 PR 从约 1,400 行改动降到 850 行(缩小 1.65 倍),因为现在每个 agent 只做一项任务。结合每行 3.3 倍的降幅,每个已合并 PR 的 token 数约降低 5.5 倍(3.3 × 1.65)。每周合并的 PR 数上升了 4.4 倍,而每周 token 消耗减少了 19%。回滚依然很少(占合并数的 0.2% 到 0.7%),但每个 PR 的返工略有上升,从每个已合并 PR 0.8 轮修复增加到约 1 轮。大部分 token 不是 agent 写的代码,而是它们发送的上下文。模型在两次调用之间不保留任何东西,所以每次调用都要重新发送整个对话,而一个 agent 每项任务会发起很多次调用。总量与调用次数乘以每次调用的平均上下文成正比。所有改进都来自减少调用次数,或减少每次调用发送的上下文。下面的列表列出我做了哪些改动,以及每项改动的影响(相关术语在后续章节中解释):
从对话记录中测量,按已合并 PR 计,而不是按小时计。它帮我找到了那些杠杆,包括最大的那个——我自己的调优在数周内都没发现它:agent 等待期间的缓存过期,占 agent 用量的 31%。每个 agent 完成一项任务后就结束,并附上一份书面交接和由 hook 强制执行的上下文上限。与第 3 项改动一起,这是最大的一步。在上限生效的第一天,所有类型 agent 的每次请求上下文中位数从 218k token 降到 101k token。保持 prompt cache 处于热态,并减少每个 agent 加载的内容。缓存过期占 agent 用量的比例从 31% 降到 0.7%。把规则变成代码,这样模型就不必记住它们。没有单独的数字。让程序替 AI 分担运行集群的日常工作中繁重的部分。协调器每个已合并 PR 的 token 降到了基线的 7%。让代码库对新开发者友好,因为每个 agent 都是新开发者。没有单独的数字。这六项背后的共同原则:不要依赖模型记忆,要让系统来记忆。
这是一个项目,由一个人运行,多项改动同时生效。在无法区分各自影响的地方,我会说明。
先做什么 无论是一个会话还是一打 agent,算术是一样的。即使没有集群,以下五步也能覆盖大部分收益:
测量。附录中的脚本从 Claude Code 保存在 ~/.claude/projects/ 下的对话记录中汇总每个会话的 token,每个请求只计一次。一个会话只做一项任务。下一项任务重新开一个会话,并附上简短说明你进行到哪了;长对话会在每次调用时重新读取所有内容。不要让会话空闲超过其缓存生命周期(sub-agent 即会话启动的后台 agent 为五分钟,主会话最长可达一小时),并把任何慢操作放到后台运行。减少每个会话加载的内容:只放适用于所有地方的规则,其余用指针引用。让代码库易于浏览:简短的模块摘要、小文件、指向细节的注释。我用来运行集群的那个会话(即接下来要介绍的协调器)已经存在了几天,脚本显示约 3,600 次调用,每产生一个输出 token 对应超过 200 个缓存读取 token。这个比例正是本文的主题。下面的门禁和调度程序只有在大量 agent 运行于一个庞大、规则繁多的仓库上时才能收回成本。
配置 一个协调会话(协调器)负责监督工作。在一台云 VM 上,最多十几个后台 agent 各自领取一个 GitHub issue,在自己的克隆中编写改动和测试,然后打开一个 pull request。一个独立的审查 agent 被要求找出不应合并的理由,它必须在每个 PR 的当前 head commit 上批准,然后该 PR 通过带绿色 CI 的合并队列合入。
主仓库是一个多服务搜索解决方案,主要使用 Python 和 TypeScript,约有 1,400 个解决方案代码文件、约 600 个脚本和工具文件,以及 136 个 CI 任务。agent 还在三个较小的仓库中工作:一个数据生成器、一个配置与数据仓库,以及 agent 控制仓库。现在这个集群每周在四个仓库中合并 590 到 870 个 PR。
结果 这些数字来自一个脚本,它覆盖了自九月以来的所有对话记录。每个 token 只计一次:新输入、缓存写入、缓存读取和输出(缓存相关术语在“为什么 agent 使用这么多 token”中解释)。该脚本与我开始时做的独立计数(9 月 15 日至 10 月 3 日)进行了核对,误差在 2.3% 以内。周为 ISO 周,周一到周日:W36 从 8 月 31 日开始,W41 从 10 月 5 日开始,W45 不完整,截至 11 月 7 日。
改动行数为四个仓库的新增行数加删除行数。每周有少数 PR 会重新生成数据文件、改动数万行,因此计算每行 token 时,一个 PR 最多按 5,000 行计。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。