从一次并行任务复盘 Codex 的 token 消耗

一个 3 分钟完成开发、却耗尽 5 小时额度的任务意外

这件事最初是从一次并行任务开始的。我要给一个 iOS 客户端接入新功能,改动牵涉 iOS、API 两端,还需要读取 Obsidian 里的 TaskSpec 文档。为了试试多个子 Agent 并行工作的效果,我把任务拆开推进。开发阶段确实很快,3 分多钟就完成了代码编写,进入验证阶段。

真正意外发生在后面。验证过程中,任务多次申请使用 Docker、Xcode 等工具;我逐一批准,但验证还没有跑完,5 小时限额已经耗尽,还额外用了 2 刀的 credit。代码产出只有几个文件,消耗却像一次大型任务。

这让我开始重新审视「并行」的代价。于是有了这样的思考:输出代码并没有想象中那么多,token 到底花在哪里?

另外 Codex 更新后,感觉 token 消耗变快,而且很明显了。对 Plus 订阅用户而言,5 小时额度有时只能支撑半小时左右的实际工作,随后只能等待下一个窗口。

所以必须要弄清楚怎么省,要想了解如何省token,先弄明白token花在什么地方了?

先还原消耗路径:token 花在了代码之外

通过ChatGPT了解到,这次任务的过程很典型。它包含理解任务、定位项目、分发子任务、实现、验证和排查验证结果这一整条链路。每一步都合理,叠在一起却很贵。

任务开始时,Agent 要读取指令、项目规则、Skill 和 TaskSpec,建立对 iOS、API 与文档的共同理解。多个子 Agent 并行后,每个 Agent 又各自加载一遍相关上下文、浏览目录、搜索文件和推理实现路径。并行缩短了开发时间,也把这些固定成本压缩到了同一段时间里。

真正容易失控的是验证。构建指定 Scheme、拉起 Docker、运行测试、读取日志、根据失败重试,每一个动作都会继续产生上下文和工具输出。如果验证目标没有提前收窄,Agent 很容易从「确认这几个文件能工作」滑到「把环境里所有不确定性都查一遍」。代码已经完成,消耗却仍在增长。

把账拆开看,问题就清楚了。多 Agent 和验证本身都有价值,只是任务的不同阶段需要不同的上下文和预算。该并行的地方发生了重复,该收敛的地方又没有及时止损。

解决问题:把信息和预算放到该出现的地方

让规则按作用域出现

AGENTS.md 不适合做成一个包罗万象的大文件。按我现在的项目结构,分层会更合适:Workspace 层负责工作流和项目路由,Project 层说明项目级约束,Repo 层再放架构、验证和具体的 Skill 路由。

我的项目目前这样分层:

Workspace/
├── AGENTS.md
└── Development/
    ├── AGENTS.md
    ├── ios/
    │   └── AGENTS.md
    ├── backend/
    │   └── AGENTS.md
    └── web/
        └── AGENTS.md

关键不在文件数量,而在边界清楚。每条规则只在它真正生效的范围内出现,不要在多个层级重复描述同一件事。AGENTS.md 负责边界、路由和强制约束;Skill 负责具体做法。相同类型的规则只保留一个事实来源,既能减少上下文,也能避免规则相互打架。

Skill 也不必全部自动加载。高频、与当前开发类型强相关的能力,可以由 AGENTS.md 路由;低频能力则在 Prompt 明确需要时再加载。以 iOS 功能开发为例,swift-architectureswift-concurrencyswiftui-navigation 可以作为高频 Skill,其他能力通过按需路由(Skill routing)进入上下文。知识仍然可用,只是不必每次任务都背着走。

缩小探索空间,别让 Agent 每次重新认识项目

Agent 的探索成本和搜索空间直接相关。面对一个 Workspace,它不该每次都重新认识整个开发目录;面对一个文档库,也不该默认扫描整个 Vault。

Prompt 里最好明确 Target Project、Target Feature、Target Files、Allowed Changes,以及 Do Not Touch。文档任务也一样,从指定项目目录收敛到具体文档,再收敛到需要处理的 Section。以这次任务为例,应该直接指出所需的 TaskSpec、iOS 模块和 API 模块,避免让每个 Agent 都从整个 Workspace 或 Vault 里找入口。

给出这些边界,不是在束缚 Agent,而是在替它省掉无意义的查找和猜测。

给推理和验证单独设预算

高推理预算应该留给真正需要权衡的地方。架构设计可以用 High,复杂调试可以用 Medium 或 High;普通 UI 修改和常规实现通常用 Low 或 Medium 就够了。验证阶段更适合保持低预算,因为它的任务是根据明确标准确认结果,而不是重新做一轮架构思考。

验证范围也应和改动范围对应。一个更实用的默认组合是:构建指定 Scheme,再运行当前任务新增或直接相关的 Unit Test。UI 的视觉确认交给人,UI Test 不作为默认自动步骤。这里不是放弃质量,而是把「机器能稳定、低成本验证的内容」交给机器,避免为了形式完整而引入大段日志、环境噪声和无效重试。

还需要给验证设定停止条件。例如,某个 Docker 或 Xcode 问题若与本次改动没有直接关系,就记录为环境阻塞,不继续无限重试;如果需要扩大验证范围,应先说明原因和预期收益。批准工具权限并不等于批准无边界地排查,二者需要分开管理。

用 Spec 和 Plan 换掉后期返工

最划算的优化,往往发生在 Codex 大规模读取代码之前。Spec 要写清做什么、不做什么、修改边界和验收标准;Plan 再落到修改哪些模块、按什么顺序改、有哪些风险、怎样验证。可定义一些模板,保证输出格式。

这套流程的重点不是增加文档,而是提前消除歧义。需求和验收标准越清楚,Agent 越不需要一边探索、一边实现、一边猜用户到底要什么。前面多花一点时间收敛,后面就少读一遍代码、少改一轮方案,也少跑一轮验证。

三条足够先落地的原则

  1. 收敛 AGENTS.md 和 Skill 上下文。 不要把所有工程规则和能力默认塞进每次任务。AGENTS.md 只保留当前层级的边界、路由和强制约束,Skill 在真正需要时再加载。这样既能减少固定 token 成本,也能降低规则重复和冲突。

  2. 不要所有任务都用 Medium 或 High Reasoning。 架构取舍、复杂 Debug 值得使用更高的推理预算;常规 UI 修改、简单实现和明确的验证任务通常不需要。推理强度应随问题复杂度变化,把昂贵的思考留给确实有不确定性的环节。

  3. Verification 必须按变更范围验证。 改了哪个模块,就构建对应的 Scheme、运行直接相关的测试。不要因为改了几个文件,就默认拉起全量测试、多个 Scheme 和无关的环境排查。验证的目标是为当前改动提供足够证据,不必穷尽整个工程的所有可能问题。

子 Agent 也应该遵循同一套原则。只有子任务可以独立交付、几乎不用共享上下文时,并行才值得;如果每个 Agent 都要读同一份 TaskSpec、扫描同一套仓库、等待同一轮验证,速度虽然更快,token 成本往往也会成倍增加。

总结:优化的对象是 Agent 的信息流

经过这些收敛,可以把 Codex 的 token 优化归纳为四个方向:Context Engineering、Agent Routing、Reasoning Budget 和 Verification Budget。

它们分别处理四个问题:什么信息需要进入上下文,什么能力应在何时加载,哪些决策值得高强度推理,哪些检查值得为结果付出成本。落到日常任务里,目标很朴素:减少无效 Context、重复探索、高成本推理、无意义验证和返工,提高一次任务完成率。

好的 token 优化,不是让 Agent 知道得更少,也不是为了省 token 放弃并行和验证。关键是让它在合适的时间拿到完成当前任务所需的信息,并在已经获得足够证据后停止。token 降下来只是结果,更稳定的 Agent 行为和更清楚的工作流才是这套方法真正留下来的东西。

以上只是我基于一次实际任务和日常使用的个人思考。若有理解不准确或遗漏之处,欢迎指正。