大家好,我是 Naco。
最近我用 Codex 跑长任务,反复遇到三个问题:
- 一个窗口从需求聊到实现,后面已经分不清哪一版结论有效;
- 方案还没落地,就让 Agent 一轮轮评审,流程越来越复杂;
- 一上来就开多个 Agent 同时改代码,最后省下的时间全花在协调和合并上。
这些动作看起来都在提效:更长的上下文、更多的循环、更多的 Agent。
但我越来越明确一件事:
AI Engineering 不是让 AI 无限多写代码,而是为上下文、验证和协作建立控制系统。
我现在主要用三种方式控制 Codex 长任务:
- 用 Snapshot + Handoff 管上下文;
- 用 Evidence-driven Loop 管生成和验证;
- 用 多个读、一个写 管多 Agent 协作。
△ 快照、Loop 和单线写入,分别解决上下文、验证和协作问题
这篇文章记录的是我在实际使用 Codex 时,如何把这三套控制方式串成一条可执行的工作流。
一、问题背景:为什么 Agent 跑得越久,任务反而越容易乱
很多 AI 编程问题,并不是模型不会写,而是任务运行一段时间后开始失控。
常见表现有三个:
- 上下文失控:旧假设、失败方案、临时日志和新约束混在一个窗口里;
- 验证失控:没有测试、日志或 Diff,Agent 仍然不断"再优化一轮";
- 协作失控:多个 Agent 同时修改共享文件、接口和测试夹具。
模型能力再强,也不能自动消除这些工程问题。
如果没有明确的状态、停止条件和写入负责人,Agent 越多、窗口越长,协调成本通常也越高。
所以我的目标不是让 Codex 一口气跑到底,而是让任务在每个阶段都满足三件事:
有人能接手、有证据能判断、有人对最终写入负责。
二、整体方案:三套控制系统分别管什么
我的做法可以先压缩成一张表:
| 失控点 | 控制方式 | 要解决的问题 |
|---|---|---|
| 上下文越来越长 | Snapshot + Handoff | 下一阶段应该以什么为准 |
| Loop 不断重复 | Generator--Evaluator + 停止条件 | 这一轮是否真的更接近完成 |
| 多 Agent 互相覆盖 | 多个读、一个写 | 谁收敛决策,谁负责修改 |
三个控制系统并不复杂,关键是放在正确的阶段。
三、上下文控制:阶段结束先做 Snapshot,再 Handoff
我现在很少让一个 Codex 对话从任务开始一直跑到最后。
窗口变长以后,容量反而不是最麻烦的。真正麻烦的是:模型可能记得前面说过什么,却未必知道现在应该听哪一版。
比如一个长任务里经常同时存在:
- 最初提出、后来已经被推翻的方案;
- 为排查问题临时收集的日志;
- 已经完成的待办;
- 中途新增的业务约束;
- 修改后的接口和仍停留在旧接口上的讨论。
Compaction 可以压缩旧对话、释放上下文空间,但它主要解决"装不装得下"。
Handoff 解决的是另一个问题:
下一阶段应该拿着什么状态继续工作。
我的 Snapshot 模板
在方案确认、实现完成或准备转入 Review 时,我会先让 Codex 生成一份快照:
shell
## 当前目标
这一阶段最终要交付什么。
## 已确认事实
哪些结论已经从代码、文档、日志或用户输入中得到确认。
## 已做决策
选择了什么方案,为什么放弃其他方案。
## 当前状态
修改了哪些文件,测试、构建和审查结果是什么。
## 未完成事项
还缺什么,哪些判断仍然待验证。
## 下一步与验收标准
新窗口接下来只做什么,做到什么程度算完成。
然后开一个新窗口,让它先读快照,再继续执行。
这里最重要的一句提示是:
整理任务状态,不要复述聊天流水。
好的快照应该让一个没参与前面讨论的新窗口,直接看懂哪些已经确认、哪些已经决定、还有什么没有完成。
△ Compaction 解决容量,Handoff 保证任务连续性
什么时候值得切窗口
我不会每做一个小步骤就 Handoff。
只有出现明显的阶段边界时才切,例如:
- 调研结束,准备进入方案设计;
- 方案已经确认,准备开始实现;
- 实现完成,准备进入 Review 或验证;
- 当前窗口的目标或角色发生变化。
判断标准只有一条:
现在有没有一份代码、文档、测试结果或决策记录,能让新窗口接着干?
没有可交接的成果,换窗口只是把上下文切碎;有了明确状态再切,才是在降低噪声。
四、验证控制:方案阶段少 Loop,代码阶段多 Loop
Ralph Loop 这类模式很适合让 Agent 持续执行"实现---检查---修复"。
但我不会在所有阶段都使用同样数量的循环。
1️⃣ 方案设计阶段:少循环
方案阶段通常还没有代码、测试、日志和 Diff。
如果反复让不同 Agent 评审方案,很多时候得到的不是新证据,而是:
- 换一种方式重新描述原方案;
- 在几种都能成立的选择之间来回摆动;
- 继续增加角色、流程和抽象层;
- 任务越拆越细,代码一行还没开始写。
所以方案阶段我只确认四件事:
- 最终要交付什么;
- 哪些边界不能碰;
- 用什么证据验证结果;
- 任务是否已经拆到可以实现。
四件事说清楚,我就开始做,不再让 Agent 轮流给方案加意见。
2️⃣ 实现阶段:让证据驱动 Loop
代码出现以后,Loop 的价值完全不同。
每执行一轮,都可能产生新的证据:
- 编译结果;
- 失败测试;
- 运行日志;
- 代码 Diff;
- 静态检查结果;
- Reviewer 指出的具体文件和行号。
这时我会使用 Generator--Evaluator Pattern:
javascript
Generator 实现代码
↓
Evaluator 按验收标准检查
↓
不合格:返回具体问题和证据
↓
Generator 根据反馈修订
↓
达到标准或触发停止条件:结束
△ 有了代码、测试和 Diff,Loop 才更容易收敛
3️⃣ 给 Loop 设置停止条件
我通常会提前写清楚三个停止条件:
- 验收标准已经通过;
- 连续两轮没有实质改进;
- 达到预先设定的轮数或资源上限。
平时判断是否继续,我只问一句:
这一轮有没有比上一轮多出新的证据?
没有测试变化、没有新日志、没有新的 Diff,也没有定位到更具体的问题,就应该停。
继续运行通常只是在消耗上下文,并不代表任务正在收敛。
五、协作控制:多个 Agent 并行读,主线只保留一个写
当 Agent 的单次执行成本降下来以后,很容易自然地同时开五个甚至更多 Agent。
对于日常开发任务,我更常用的配置是:
多个 Agent 并行读,主线只保留一个 Agent 写。
读操作为什么适合并行
不同 Agent 可以同时完成这些工作:
- 查代码入口和调用链;
- 读官方文档和依赖说明;
- 分析日志、复现路径和已有测试;
- 分别从正确性、安全、性能几个角度检查 Diff。
这些任务主要是在收集证据,不会互相覆盖文件,结果也容易由主线程统一汇总。
多个 Agent 同时写,会增加什么成本
写代码的风险不同。多个 Agent 同时修改时,经常出现:
- 最初拆任务时信息最少,实际读完代码后边界发生变化;
- 两个子任务同时修改公共接口、配置、测试夹具或数据结构;
- 一个 Agent 更新了约定,另一个仍在旧上下文中继续实现;
- 并行完成后还要解决冲突、同步上下文并重新执行集成验证。
Agent 数量增加以后,协调成本不会自动消失。
△ 多个读负责找证据,一个写负责改系统
我的默认执行方式
日常任务里,我一般按这个顺序工作:
- 多个只读 Agent 并行查入口、约束和风险;
- 主线程汇总证据、解决冲突并确定方案;
- 由主线程或一个实现 Agent 修改代码;
- 修改完成后,再让只读 Reviewer 检查 Diff 和测试结果;
- 主线程执行最终验证并决定是否收口。
这相当于把"调查""决策""写入""审查"分开,避免多个 Agent 同时改变系统状态。
什么时候才使用 Worktree 并行写
并行写不是不能用,但我会先检查四个前提:
- 子任务确实位于不同模块,几乎不修改共享文件;
- 模块之间的接口已经稳定,不需要边写边改契约;
- 每个子任务都有独立的完成标准和验证方式;
- 主线程能够统一合并,并对最终结果重新验证。
四个条件都满足,再把独立的大任务放进不同 Worktree 并行实现,收益才比较明确。
如果几个 Agent 还需要频繁同步决策、修改同一个接口,最后又要靠一个人理解所有冲突,那么并行写只是把开发时间换成了协调时间。
六、把三套控制系统串起来:我现在的五步工作流
真正执行时,我会把上面的做法组合成五步:
- 明确目标和验收标准:先说清交付物、边界和验证方式;
- 并行读取和收集证据:查入口、读文档、分析日志、寻找测试;
- 由主线程收敛方案:处理证据冲突,确定最终修改范围;
- 保留一个写入口并循环验证:实现后用测试、日志、Diff 和 Reviewer 驱动修订;
- 阶段结束生成快照:记录事实、决策、修改状态和下一步,再 Handoff。
markdown
目标与验收标准
↓
多个 Agent 并行读
↓
主线程汇总并决策
↓
一个 Agent 写 + 证据驱动 Loop
↓
Snapshot + Handoff
这套流程没有"十个 Agent 同时开工"那么热闹,但它更容易知道任务现在处于什么状态、为什么继续,以及最终谁对修改负责。
七、实际效果:最大的变化不是写得更多,而是返工更少
这套方法没有让 Codex 突然拥有新的模型能力,但我的实际使用感受很明显:
- 长任务不再需要从几十轮对话里翻找最新结论;
- 方案阶段很少因为反复评审而越做越复杂;
- 实现阶段的每一轮修订都有测试、日志或 Diff 支撑;
- 多 Agent 仍然可以并行收集信息,但不会随意覆盖主线修改;
- 进入 Review 时,Reviewer 能直接看到验收标准和验证结果。
以前我更关注"还能不能再开一个 Agent"。
现在我更关注三个问题:
- 新窗口能不能根据快照直接接手?
- 下一轮 Loop 会不会产生新的证据?
- 当前到底由谁负责写文件?
这三个问题能够回答,长任务才值得继续跑。
八、为什么我认为这套方案在工程上是"对的"
它不是工具堆砌,而是几条比较朴素的设计原则:
- 状态显式化:不要求新窗口从聊天历史里猜当前状态;
- 验证证据化:不把"Agent 又思考了一轮"当成进展;
- 写入单一化:明确谁负责修改,减少并发写带来的冲突;
- 阶段可交接:调研、实现、审查之间都有可复用的交付物;
- 并行有边界:读可以大胆并行,写要根据模块和接口独立性决定。
最终目标不是限制 Agent,而是让它在明确的边界里稳定执行。
人负责目标、边界和取舍;Agent 负责执行、收集证据和重复验证。
九、不足与适用边界
这套方法也不是所有任务都需要。
- 小改动如果十几分钟就能完成,专门做 Snapshot 和 Handoff 反而增加成本;
- "一个写"会牺牲部分并行速度,不适合边界已经稳定的大型独立模块;
- Snapshot 记录错误,新窗口会稳定地继承错误,因此关键事实仍要有代码、文档或测试支撑;
- Loop 只能帮助修正可验证的问题,无法替代业务判断和架构取舍;
- Reviewer 和测试也可能遗漏问题,最终验证仍然要由主线程收口。
所以我不会把它做成固定仪式,而是按任务规模和风险选择。
十、最后总结
我现在用 Codex 跑长任务,主要守三个规矩:
- 一个阶段结束,先生成 Snapshot,再 Handoff 到新窗口;
- 方案阶段少 Loop,代码出现后再让测试、日志和 Diff 驱动循环;
- 调研和审查可以并行,写入口默认只保留一个,真正独立的大任务才使用 Worktree。
准备让 Agent 长时间运行之前,我会再检查一次:
这份快照能不能让新窗口接手?这一轮有没有新证据?现在到底是谁在写?
如果三个问题答不上来,我不会继续增加窗口或 Agent。
先控制上下文、验证和协作,再让 AI 跑得更久、写得更多。
参考资料
1 AI Engineer,Anthropic Workshop: Build Agents That Run for Hours --- Ash Prabaker & Andrew Wilson
www.youtube.com/watch?v=mR-...
2 AI Engineer,The Multi-Agent Architecture That Actually Ships --- Luke Alvoeiro, Factory
www.youtube.com/watch?v=ow1...
说明:本文结合公开分享与个人使用 Codex 的实践判断整理。具体执行方式仍需根据任务规模、代码库结构和协作成本调整。