两个 Agent,一个夜晚,1.58 亿 Token:读了两百本《战争与和平》,只为写出不到一本

📄 本文综合改写自 Aashish Bhandari(Max)发布在 DEV Community 的实测报告《Two agents, one night, 158 million tokens: what it cost and what we are fixing》,原始数据来自 Codex 会话的运行时分析,原文链接见文末。
9 月 15 日晚上,一份针对某个 Web 服务的设计评审报告摆到桌面上,里面列了 12 条问题:缺一个事务保护、重试和密钥轮换有缺口、交接路径很脆、诊断信息太薄、可移植性有问题。
有人把这份清单丢给一个 AI 编程 agent,要求它把这 12 条全部修掉、写好测试、把改动整合起来、打出一个可交付的发布包。它做到了。
第二天早上,另一个厂商的 AI agent 从零开始重建了同一份结果,做独立复核。两个 agent 用的规则文件不同,厂商不同,会话不同。复核结果:100 个测试全部复现,73 项浏览器检查全部复现,发布包逐字节一致,没有发现严重问题。
整个夜晚,没有人敲一行代码。
一张凌晨的成绩单#
先把实测数字摆出来,因为这篇复盘最有价值的部分就在这张表里。
| 指标 | 实测值 |
|---|---|
| 墙钟时间,第一条提示到最后一条 | 13 小时 4 分 |
| 其中模型真正在工作的时间,约 | 5.5 小时 |
| 改动文件数 / 新增行数 | 118 / 16369 |
| 第二个 agent 复现的测试 | 100 / 100 |
| 复现的浏览器检查 | 73 / 73 |
| 交付包比对 | 逐字节一致 |
| 所有模型处理的 token 总量 | 158137319 |
| 其中重复读取已缓存上下文 | 95.4% |
| 其中模型真正新写出的文字 | 0.42% |
负责构建的是一套父子结构:一个最强的模型当父 agent 负责统筹,16 个跑在更便宜模型上的 worker 负责干具体活。按文章作者的说法,模型读掉的内容大约相当于两百本《战争与和平》,而它真正写出来的东西加起来还不到一本。
这就是整篇复盘要抓的那个杠杆:阅读量根本不是问题,重复的阅读量才是。
作者还先加了一句提醒:读一次这样的遥测数据本身也是一件模型任务,他们第一次尝试做分析,花掉了被分析那次运行 60% 的成本。这一次压到了 4.7%。他们给这件事定了目标:分析开销必须低于被评估运行的 2%,否则分析停止,先申请预算。
第一步不是省钱,是让测量不花钱#
这篇文章的很多结论能站住脚,靠的是一个很朴素的设计:Stop 和 SessionEnd 生命周期钩子。
会话暂停或结束时,钩子用一个普通脚本读取会话记录,把计数器写进 JSON,再重新生成 CSV 和摘要。全程没有模型参与,成本是零 token,而且不可能被「忘记」。这次运行能报出 55 个组件、1505 次激活、1299 次工具调用,靠的就是它。
这个设计对比过去做法的差别值得说清楚。以前他们让模型在任务结束时自己汇报用量,代价是整整一次满上下文激活,而且模型看不到自己最后那句回答,报出来的数天然缺一块。
更关键的是它给出了一个可以拿来推演的模型:
一次运行的成本约等于「激活次数 × 上下文大小」。
拿到这个公式,后面所有优化都不是玄学。要么减少激活次数,要么缩小每次激活要重发的上下文。文章里出现的每一个机制,最后都落在这两项上。
杠杆一:按活儿的形状挑模型#
父 agent 用最强的模型,这一点没变。变化在于 worker 的分配规则:机械、量大的活交给最小的模型,大范围阅读交给中档模型,只有真正需要推理的部分才上最贵的档。
按冻结的价目表算,这次运行里的具名模型用量折合 99.80 美元。如果每一个 token 都跑在父 agent 的模型上,同样的用量是 218.81 美元。降幅 54%,他们上一次规模更小的构建测出来是 43%。
这里必须提一个容易被误读的细节:这 54% 是纯粹的价格替换,不是工作量减少。worker 一共处理了 1.1 亿 token,活一点没少干,只是换了一批更便宜的模型去干。
对多 agent 编排有兴趣的人应该把这句话记住:先确认你省下的是单价,而不是任务量。把单价当成绩效,很容易在下一次模型调价时全部归零。
杠杆二:把 worker 当一次性用品#
第二个机制是「派单下限」加「一次性 worker 包」。
规则写得很具体:只有当一段工作可以划出清晰边界时,才允许派 worker;派单时把一个简短的数据包一次给全,包括目标、涉及的文件路径、权限范围、输出格式和预算;然后要求它做完一次就返回。
效果是这次运行 70% 的 token 离开了昂贵的父 agent。
但同一个机制也暴露了一半的失败:父 agent 没有守住「一次性」,它复用了 4 个 worker,前后追加了 28 次后续指派。这 4 个长寿 worker 最终承担了整次运行 49% 的 token。
原因并不神秘。一个被复用的 worker 每一步都要把自己累积的历史重新发一遍,于是它从「一次性工人」变成了「背着全部上下文的重型节点」。省下来的单价,被上下文增长吃回去了。
这条经验可以直接抄:一个 worker 只负责一个阶段,下一阶段开一个全新的、上下文最小的 worker。 复用看起来省事,实际是在给自己造一个越来越贵的黑洞。
最贵的一句话是「还没好」#
如果只读这篇文章的一段,建议读这一段,因为它可能是最普遍存在、也最容易被忽略的浪费。
规则写得很清楚:派完单之后,父 agent 要么去做自己手上的独立工作,要么就等一次;绝不允许按时钟反复去问「你做完了吗」。
在有活干的时候,这条规则守住了。父 agent 一空闲,规则当场失效。
实测数据是:父 agent 一共发起 89 次等待,其中 88 次是 60 秒的定时等待,66 次等到超时。每一次这种「检查」,都要把整段对话重新发一遍。加起来是 1030 万 token,占整次运行的 6.5%,占其价目表成本的 12.7%,买回来的信息只有三个字:还没好。
Codex 上那个叫不醒的父 agent#
更值得 Codex 用户注意的是对失败原因的解释。
在 Claude Code 上,worker 完成时,harness 会主动唤醒父 agent,所以这个陷阱不会打开。而在 Codex 上,目前一个已经完成的 worker 无法唤醒空闲的父 agent。
这意味着什么?意味着「不要轮询」这条规则,写在 AGENTS.md 里是不够的。规则是声明式的,它约束的是模型的行为倾向;而这里缺的是一个事件信号,属于 harness 的能力缺口。声明式规则补不上结构性的信号缺失。
能补上的是外部结构。文章给出的方向是「零 token 看门狗」:一个普通脚本每分钟读一次 worker 的计数器,只在三种情况下唤醒父 agent,分别是任务完成、预算越界、以及出现卡死的特征信号。唤醒本身不消耗模型 token,等待期间也不再重发上下文。
顺便说一句,这个坑和公众号里常见的「Codex 空转」是同一类问题的两个面:模型没坏,是编排层少了那根线。区别只在于,有的 harness 已经接上了线,Codex 目前还没有。
压缩是泄压阀,不是控制器#
父 agent 的上下文在整次运行里被压缩了 5 次,其中 3 次是手工触发。每一次压缩都把下一步的输入砍掉 36% 到 84%。
数字很好看,但作者对这个机制的评价相当克制:它是泄压阀,不是控制器。
因为上下文会重新长回来。整次运行里最长的一个回合出现在压缩之后,那一个回合就烧掉 2000 万 token,并发起了 62 次等待。
把这句判断放到自己的项目里对照,得到的操作建议是:别指望自动压缩替你管住成本。压缩解决的是「会话还能不能继续」,不是「这次运行划不划算」。
两个不花 token 但值钱的工程习惯#
除了模型路由和派单纪律,还有两个纯管理动作。
第一,分析纪律。 性能分析放在独立工作区里做,先读已经派生好的遥测数据,缺字段就用确定性工具去抽取,绝不派一个模型去读原始日志。效果是从 60% 的开销降到 4.7%。
第二,共享的决策记录和验收标准。 他们维护了 10 条决策和 10 条胜负标准,每条一个文件,两个 agent 都能读。一条标准只有在某个 agent 连续 3 次合格会话之后才算「拿下」,而且判定只允许依据遥测数据。
第二条尤其值得学。它解决的是所有 AI 工程团队都会遇到的尴尬:改完之后大家都说「感觉快多了」。把判定权从对话里挪到遥测里,讨论才能结束。
六个排好队的修法#
这次运行的成绩单是「前」的一栏,接下来有 6 个修法等验证,每一条都配了一个用遥测来判卷的标准。
- 等待从 60 秒改成 5 分钟,等待之前先打一行进度,让父 agent 有事可看。
- 零 token 看门狗,只在完成、预算越界、卡死特征三种情况下唤醒父 agent。
- 一个 worker 只干一个阶段,每个 worker 带跟进次数和激活次数的闸门,下一阶段开新的最小上下文 worker。
- 扩展遥测,让等待次数、跟进次数、压缩消耗的 token 和终止错误都由钩子直接计数,不再靠人工重建。
- 机械活固定给最便宜的模型,把解析失败当成停止条件,审计开始前先检查分析预算。
- 自动审批审查员,这部分占本次运行 7.5%,价格未知,需要先弄清楚它到底是一个设置项,还是一个真实的设计决策。
同样的任务形状会在这些修法落地后重跑一次,用同一个钩子来计数。数字动了,标准会说话;数字没动,这篇文章就继续当基准,然后换下一批六个。
我的看法#
这篇复盘最难得的地方,是它把「交付」和「编排」当成两个独立变量来看。
一个夜晚修完 12 个问题、测试全绿、独立复核逐字节一致,这个交付质量放在今天的行业里已经算优秀。作者自己也承认:以这个节奏交付,对他们来说已经是常规操作。但同时他们明确写出「成本还不可接受」,然后把整篇文章用来解释为什么。
两件事可以同时成立,这恰恰是很多团队搞混的地方。交付变好,不代表编排变好。而编排的问题只会在账单上暴露,不会在任何质量指标上暴露。
对 Codex 用户来说,有三条可以今天就用的结论:
- 先装零 token 的测量钩子。 如果你不知道自己的成本等于「激活次数 × 上下文大小」,那你所有的优化都是猜的。测量本身一旦要花 token,就会扭曲被测量的对象。
- 不要把 worker 当员工养。 复用 worker 看起来省派单成本,实际在每一步重发历史,是最隐蔽的成本黑洞。一个阶段一个 worker,做完就退休。
- 别用提示词去修 harness 的缺陷。 在 Codex 上,靠
AGENTS.md写「不要轮询」管不住等待,因为缺的是唤醒信号而不是意愿。这种缺口要用外部脚本兜住,而不是写更严厉的规则。
长任务时代真正稀缺的能力,不是让 agent 多干活,而是让它在等待的时候不要继续花钱。
参考来源
- Aashish Bhandari (Max), Two agents, one night, 158 million tokens: what it cost and what we are fixing, DEV Community (2026-09-17): https://dev.to/maxstravion/two-agents-one-night-158-million-tokens-what-it-cost-and-what-we-are-fixing-b3k
- 本文数据均出自该报告的 Base case fact sheet 与 Codex 运行时分析,未经二次运行验证,引用的价格为冻结价目表下的折算值
- Codex 生命周期钩子(
Stop/SessionEnd)与AGENTS.md行为约定,参见 OpenAI Codex CLI 官方文档