一个开发人员最近开始让Codex连续处理一个Spring Boot项目的开发任务。

上午先让它增加订单日期筛选,完成后继续增加订单导出,接着开发数据统计接口,最后再补充缓存功能。

整个过程看起来很顺利。

Codex每次都会告诉他修改完成,相关测试也能通过。开发人员只需要不断提出下一个需求,不用每次重新解释整个项目。

但到了下午,问题开始出现。

订单列表的日期筛选有些数据查不到,导出的记录和页面显示不一致,统计接口的结果也出现偏差。

开发人员检查代码后发现,后面几个功能虽然各自能够运行,但它们都依赖了前面修改过的订单查询逻辑。

而最开始的日期边界处理其实就存在问题。

更麻烦的是,Codex后续修改时并没有重新检查这个基础逻辑,而是继续沿用之前的实现。

原本一个很小的问题,最后影响了三个功能。

这次开发人员才意识到:连续使用Agent开发,真正需要关注的可能不是某一次代码生成是否正确,而是前面的修改会不会成为后面任务的错误基础。

单个任务通过测试,不代表连续多个任务执行仍然可靠。Agent最容易被忽略的风险,是一个没有及时发现的小错误,会随着后续开发不断扩大。

一、为什么第一个任务完成了,后面的任务反而越来越难?

先还原一下这个订单系统的开发过程。

第一个需求:增加订单日期筛选。

开发人员要求Codex支持开始日期和结束日期查询。

Agent修改了Controller、Service和Mapper,也补充了单元测试。

第二个需求:增加订单导出。

由于已经存在订单查询功能,Agent直接复用了之前的查询Service。

第三个需求:增加订单统计。

Agent继续使用相同的查询条件,按照日期汇总订单金额。

第四个需求:增加缓存。

为了提高查询速度,Agent又把之前的筛选参数作为缓存Key的一部分。

表面上看,每个需求都很独立。

但实际上,后面三个需求已经建立在第一个需求的实现之上。

假设第一个任务对结束日期的处理存在错误,后面的导出、统计和缓存就可能全部继承这个错误。

例如,业务要求结束日期包含当天,但最初实现只查询到当天零点。

开发环境的测试数据恰好没有覆盖当天后续时间的订单,因此测试通过。

后面的功能复用这个查询方法,也就继续使用了错误的日期范围。

这时候,即使每个新功能都增加了自己的测试,也不一定能够发现问题。

连续开发任务之间存在依赖关系,前一个任务的实现结果就是后一个任务的输入。

因此,Agent完成第一个任务,并不意味着后面的任务可以直接建立在这个结果上。

二、真正的问题:Agent会把之前的实现当成新的事实

这是连续任务出现错误传播的核心机制。

Agent处理新需求时,通常会读取当前代码、接口定义、项目文档和之前留下的开发结果。

这些信息共同构成了它理解项目的依据。

假设第一个任务错误地处理了日期边界。

第二个任务开始时,Agent看到订单查询Service已经存在,而且单元测试通过。

它很可能直接认为:

这个查询方法已经具备正确的日期筛选能力,可以在此基础上增加导出功能。

第三个任务又读取第二个任务修改后的代码,继续增加统计功能。

于是,最初的错误不再只是一个日期判断问题,而是变成了多个功能共同依赖的基础逻辑。

这里存在一个容易被忽略的区别:

代码已经存在,不代表代码已经经过正确验证。

Agent能够读取当前项目状态,却不能仅凭代码存在和测试通过,就确认之前的业务假设一定正确。

如果前面的实现没有经过独立验证,后续任务就可能把错误继续当成正确的项目规范。

这也是为什么连续开发不能只看每次修改的完成状态。

三、为什么后续任务有时会把问题越修越复杂?

第一个错误出现后,后续任务不一定会立即失败。

有时候,Agent为了让新功能通过测试,会在原有实现上增加额外处理。

例如:

订单列表日期不完整,于是增加一套日期转换逻辑。

订单导出结果不一致,于是导出功能又单独处理结束时间。

统计接口结果不对,于是统计Service增加另一套时间范围判断。

最终,项目中可能出现三套不同的日期处理方式。

每个功能单独运行似乎都正常,但业务规则已经不统一。

这种情况比单纯的编译失败更难处理。

因为编译失败会直接暴露问题,而错误的业务假设可能让系统一直运行,只是在特定数据条件下产生错误结果。

还有一种情况是,Agent为了修复当前问题,开始修改公共方法。

这可能进一步影响之前已经完成的功能。

如果没有完整的回归测试,原本的错误还没修好,又可能引入新的问题。

连续任务中的错误传播,不只是重复使用错误代码,还可能让后续修改不断增加补丁,最终形成多套相互冲突的业务逻辑。

四、为什么单元测试通过,也不能证明整个任务链正确?

很多开发人员认为,只要Agent每次修改之后都运行测试,就能保证连续开发的可靠性。

但这里有一个明显的盲区。

单元测试通常验证的是当前代码是否符合已有测试条件。

如果测试本身没有覆盖真正的业务规则,即使代码存在错误,测试仍然可能通过。

例如,订单日期筛选要求结束日期包含当天。

但测试只准备了当天零点的一条数据。

Agent采用了错误的日期边界处理方式,测试仍然通过。

后续开发继续复用这个方法,问题就被带到了其他功能。

还有一种更隐蔽的情况:

Agent修改代码的同时,也负责生成测试。

如果它对业务需求的理解本身就有偏差,那么测试也可能按照同样的错误假设编写。

代码和测试都正确地执行了错误规则。

这就是为什么不能只依赖Agent自己生成的测试来证明任务正确。

更可靠的验证需要从业务需求出发,检查实际结果是否符合预期。

例如,日期筛选至少需要覆盖:

  • 开始日期当天的数据。

  • 结束日期当天的数据。

  • 跨天的数据。

  • 空日期和非法日期。

  • 不同时间区域下的边界情况。

测试通过,只能说明当前测试覆盖的条件通过了,不能证明所有业务规则都正确。

五、上下文越长,为什么越需要管理任务状态?

连续使用Codex时,还有一个问题容易被忽略:上下文会不断增加。

一个任务可能涉及几十个文件、多个工具调用、测试日志和修改记录。

当开发过程持续很长时间,Agent需要不断处理之前的对话、当前代码和新的需求。

但并不是所有历史信息都同样重要。

例如:

最初确定的业务约束可能非常重要。

某次临时调试产生的日志可能只在当时有用。

某个没有验证的实现假设,更不应该被当成已经确定的事实。

如果任务状态没有明确记录,后续Agent就可能根据当前代码和已有说明重新推断。

一旦原始业务要求没有被持续保留,错误实现就可能逐渐取代最初的需求。

因此,长任务不能只依靠聊天记录维持上下文。

更可靠的方式是把关键状态保存在项目中,例如:

  • 当前任务已经完成什么。

  • 修改了哪些核心文件。

  • 哪些业务规则不能改变。

  • 哪些假设已经验证。

  • 哪些问题还没有解决。

  • 下一步任务依赖哪些结果。

这里要注意,状态文件不能只是简单写一句任务完成。

它应该区分已经验证的事实和Agent尚未确认的判断。

上下文管理的重点不是让Agent记住所有历史,而是确保后续任务能够获得正确、可验证的项目状态。

六、真正有效的方法:每完成一个阶段,就建立验证检查点

如果项目需要让Codex连续完成多个需求,我更建议使用阶段性检查点。

例如,一个订单系统准备连续完成四个功能:

第一阶段:订单日期筛选。

第二阶段:订单数据导出。

第三阶段:订单统计。

第四阶段:查询缓存。

不建议四个任务全部交给Agent连续执行,最后再统一测试。

更稳妥的方式是:

第一阶段完成后,先验证基础查询逻辑。

检查日期边界、SQL执行结果和不同条件组合。

通过后再进入下一阶段。

第二阶段完成后,验证导出结果与订单查询结果是否一致。

不能只检查CSV文件能不能生成,还要检查记录数量、日期范围和关键字段。

第三阶段完成后,验证统计结果与实际订单数据是否一致。

特别是金额、订单数量和状态分类。

第四阶段完成后,验证缓存是否正确区分不同查询条件。

避免一个条件的查询结果被错误地用于另一个条件。

这样做的核心不是增加测试数量,而是阻止错误进入下一个开发阶段。

如果某个阶段没有通过验证,就应该先修复当前问题,而不是让Agent继续叠加新功能。

七、如何让Codex真正执行检查点,而不是只口头报告完成?

可以把连续开发任务改成明确的阶段执行规则。

例如,给Codex这样的要求:

你需要连续完成订单系统的多个开发需求。

执行规则:

1. 每次只处理当前阶段的需求。
2. 修改前检查相关业务逻辑和已有测试。
3. 完成后运行对应单元测试和集成测试。
4. 检查是否影响之前已经完成的功能。
5. 记录修改文件、测试结果和未验证假设。
6. 当前阶段未通过验证,不得继续下一阶段。
7. 每个阶段完成后保留Git检查点。

最终输出:
- 当前阶段完成情况
- 修改内容
- 测试结果
- 已发现的问题
- 尚未验证的风险
- 下一阶段依赖条件

这类约束比简单地要求Agent连续完成四个需求更有价值。

因为它明确规定了任务之间的交接条件。

还可以要求Codex在修改公共Service、DTO和数据库结构时,单独检查对后续任务的影响。

但不能认为提示词本身就能解决所有问题。

如果没有真实测试、Git记录和外部验证,Agent仍然可能把错误结果报告为完成。

八、为什么Git检查点和回滚机制很重要?

连续任务最大的风险之一,是错误已经传播到后面多个功能,开发人员却不知道应该从哪里恢复。

例如,第四个任务出现异常。

如果没有保留阶段性提交,就需要重新比较大量代码,判断问题是来自第一个任务、第二个任务,还是最近的缓存修改。

如果每个阶段都保留独立提交,排查范围就会清晰很多。

例如:

git add .
git commit -m "feat: add order date filter"

git add .
git commit -m "feat: add order export"

git add .
git commit -m "feat: add order statistics"

这些提交并不是简单地保存代码。

它们实际上为连续任务建立了可追踪的状态节点。

如果第三阶段验证失败,可以比较第二阶段和第三阶段之间的差异。

如果发现第一阶段已经存在错误,也可以回到相应检查点重新修复。

对于复杂任务,还可以使用独立Git分支或Worktree,让不同阶段的实验修改不会直接污染稳定代码。

但需要注意,Git回滚只能恢复代码状态,不能自动恢复已经发生的数据库变更、外部接口调用和真实业务数据。

这些操作仍然需要独立的恢复方案。

没有检查点,Agent连续开发就很难定位错误从哪里开始;有了检查点,至少可以把问题限制在明确的修改范围内。

九、让Agent自己开发,再让另一个过程独立验证

还有一种比较实用的做法,是把开发和验证分开。

例如:

第一个Agent负责实现需求。

第二个独立验证过程负责检查业务规则、代码差异和测试结果。

验证时不要只问:

“代码有没有问题?”

而应该根据需求明确检查:

  • 日期筛选是否包含结束日期。

  • 导出结果是否与列表一致。

  • 统计结果是否与数据库实际数据一致。

  • 缓存Key是否包含全部必要参数。

  • 是否影响已有接口。

如果验证发现问题,就先返回修改阶段。

如果验证通过,再允许进入下一个任务。

这种方式并不意味着两个Agent一定比一个Agent可靠。

如果两个Agent使用相同的错误需求理解,仍然可能得出相同的错误结论。

因此,独立验证最好有明确的验收标准和可执行测试,而不是只依靠另一个模型阅读代码后给出主观评价。

对于关键业务,还可以使用真实数据样本、数据库查询结果和人工确认的业务规则作为外部依据。

十、用一个指标判断连续开发是否可靠

这篇只突出一个核心指标:

连续任务最终通过率。

它不是统计Agent单独完成了多少个需求,而是统计一整条连续任务链,最终有多少条能够全部通过验收。

例如,一个项目安排10组连续开发任务,每组包含5个相互依赖的需求。

如果其中6组最终所有需求都通过独立验证,那么连续任务最终通过率就是60%。

这个指标能够反映一个重要区别:

Agent单独完成一个需求的能力,与持续维护同一套代码并不断扩展功能的能力,并不是一回事。

如果单个任务通过率很高,但连续任务最终通过率明显下降,就说明开发流程可能存在错误传播、回归不足或者阶段交接不清晰的问题。

优化前后,可以使用相同类型的任务链进行对比,观察检查点和独立验证是否真正提高了最终完成质量。

真正值得关注的不是Agent完成了多少个任务,而是连续完成的任务最终有多少经得起完整验收。

十一、Plus和Pro怎么判断?

如果主要使用ChatGPT、Codex完成单个项目的连续功能开发、代码修改、单元测试和阶段性验证,Plus通常够用。

如果需要持续处理大型代码库、多阶段任务、跨模块修改和长时间Agent工作流,并且频繁进行多轮测试、修复和回归验证,Pro更适合高频、长任务的工程工作流。

但套餐升级不会自动解决任务之间的依赖关系,也不能替代检查点、版本控制和独立验收。

最后

Agent连续完成多个需求,为什么第一个小错误会让后面任务全部跑偏?

因为后续任务会不断使用前面任务留下的代码、接口和业务假设。

如果第一个任务没有经过真正验证,后续任务就可能把错误当成正确基础,继续增加功能、修改接口和扩展业务逻辑。

最终,一个很小的实现偏差就可能演变成多个功能之间的连锁问题。

真正可靠的连续开发流程应该是:

拆分任务 → 明确验收标准 → 分阶段实现 → 独立验证 → 保存Git检查点 → 确认通过后继续 → 最后进行完整回归测试。

ChatGPT、Codex可以提高连续开发的执行效率,但不能把每次任务报告完成当成最终质量保证。

AI编程真正需要提高的,不只是单次任务完成率,而是让每一次修改都建立在已经验证的正确结果之上。

持续分享 Codex、大模型开发与 AI 编程实战内容

也整理了稳定的 Plus/Pro 会员订阅渠道,有需要下方可自取。

Logo

更多推荐