AI 改码通过测试后,还要检查整个差异
一次查询优化虽通过目标测试,却把调试脚本、废弃查询和未完成重构一并带入合并。文章指出,智能体试错产生的临时内容容易残留,交付检查应覆盖整个工作树及变更差异。
AI 深度解读
Agent 说「完成了」,可能只代表它盯着的那个测试通过了。作者让 Agent 优化一条慢查询,合并后才发现:真正的修复只有三行,改动里却混进了注释掉的替代查询、打印堆栈的调试脚本,以及做了一半的重构。
这篇文章提醒我们:验收 AI 编程任务,除了确认功能正确,还要确认交付范围准确。它给出的办法很朴素:检查工作区、核对完整差异、清理调试残留。
为什么测试绿了,工作区却还没收拾好
Agent 的工作过程通常是反复试错:修改代码、运行检查、继续修改。为了比较方案,它可能保留一段旧查询,创建一个备用文件,插入 console.log,或者把实验方案存成同目录下的另一个文件。
这些东西在探索阶段有用途,但测试不会自动判断它们是否应该交付。
作者指出的问题是:目标检查一旦通过,Agent 就停止迭代,没有再从最终工作区的角度检查一次,确认剩下的每一处改动都属于本次任务。
测试通过能证明某项行为符合预期,不能证明所有改动都有交付理由。
作者的案例里,三行修复解决了问题,额外留下的内容却扩大了审查范围。这里的失败不是算法没写对,而是 Agent 对「完成」的声明超出了它实际验证过的内容。
审查为什么容易放过这些残留
审查者通常带着任务目标看 diff:慢查询有没有改对,相关测试有没有通过。
这种阅读方式有个盲区。你容易认真检查预期中的修改,却把旁边的注释块、调试代码当成无关紧要的临时痕迹。diff 越大,多出来的一小段就越容易藏住。
所以,对预期代码块给出「LGTM」,并没有覆盖其他改动。
作者提出了三个成本不高的检查:
- 在审查前查看
git status,并检查相对分支基线的完整 diff。工作区中出现未跟踪文件或被注释掉的替代实现,都需要解释其用途。 - 要求 Agent 单独交付最终 diff,并核对它的变更说明。说明里的每个路径都应该出现在 diff 中,diff 中的每个路径也都应该得到说明。
- 按仓库惯例搜索调试残留,例如无条件日志、
TODO、console.log、调试打印和备份文件后缀。除非这些内容就是本次任务的交付目标,否则应当清理或解释。
这里的「干净」需要结合上下文理解:待审查的工作区可以存在本次任务的修改,关键是每一处变化都能对应到交付意图。
我的判断
我认同作者把验收从「目标测试通过」扩展到「最终状态符合声明」。这能补上单项测试的空白,而且不依赖换一个更强的模型。
不过,文章提供的是一个具体案例和一套经验做法,没有给出发生频率、团队样本或采用前后的对照数据。「比严重 bug 更常见」属于作者判断,不能当成统计结论。
还有两处需要区分。
首先,未跟踪文件不会自动进入提交,普通提交 diff 也不会显示它们。它们属于工作区检查的范围;已提交的调试脚本和废弃代码则属于交付差异检查的范围。作者把这两类问题放在一起讨论,但实际操作时,两项都要看。
其次,搜索 TODO 或 console.log 只能提供线索。已有的任务标记、合理的日志都可能命中,不能看到就删。比起单靠测试或日志扫描,作者这套办法更完整;但它仍然依赖人或 Agent 判断每项变更的用途,不能替代功能审查。
能拿来做什么
- 给日常 AI 编程任务补一条验收要求:完成后检查
git status和相对分支基线的完整 diff,并说明每个变更文件与任务的关系。 - 审查前端或 Node 改动时,把新增的
console.log、注释掉的替代实现、临时调试脚本列为检查项,逐项确认是否需要交付。 - 要求 Agent 的最终说明与文件列表逐一对应。发现没提到的文件,先查清用途,再接受「完成」。
- 把仓库常见的调试写法和备份后缀整理成搜索规则,用扫描缩小人工检查范围,再判断命中内容是否应当保留。