内容提要
AI编程代理修复bug时容易陷入循环:模糊重试产生噪音、上下文退化、无法观察真实界面,失败尝试污染后续推理。解决方法:停止盲目重试,回退到已知正常状态,用精确文件路径和可观察事实重新描述问题,每次只改一处,最后亲自验证真实应用。核心是用失败测试替代“还是坏的”,为代理提供可读信号。
延伸解读
修复循环的根源:上下文污染与模糊反馈
文章指出,AI编程代理陷入修复循环并非某个工具的缺陷,而是结构性原因。随着会话增长,上下文逐渐退化,早期错误尝试的diff和解释会污染后续推理。同时,模糊的反馈如“还是坏的”几乎不提供新信息,代理只能微调之前的猜测,导致在两个近似错误的修复间反复。更关键的是,代理无法像人类一样观察真实界面,只能依赖文字描述,这进一步降低了修复精度。
打破循环的关键:回退与精确重述
要打破循环,首先应停止盲目重试,回退到已知正常状态,避免在错误修复上叠加新尝试。然后,用精确的文件路径和可观察事实重新描述问题,并明确“正确”的标准。文章强调,最高杠杆的一步是提供失败测试,将模糊的“还是坏的”转化为代理可读的信号。每次只改一处,最后亲自验证真实应用,而非依赖代理的自信声明。
实战案例:双重扣费与幂等性修复
文章通过一个双重扣费案例展示了循环的典型过程:代理先后尝试检查已有订单、禁用按钮、添加错误处理,均未根治问题。最终,通过编写失败测试(包括并发场景)和提供精确提示,代理用幂等键和Promise缓存实现了修复。这个案例说明,失败测试不仅能证明bug存在,还能捕捉到代理忽略的并发情况,从而引导出正确修复。
可复用的检查清单与长期实践
文章最后提供了一份检查清单,包括:一次模糊重试后停止、回退到已知良好状态、命名确切文件、陈述错误和正确行为、只要求一处更改、亲自验证。这些步骤不依赖特定工具,适用于任何AI编程代理。作者强调,修复循环不是工具使用错误的证明,而是提示需要更多信息的信号。养成这些习惯,初期可能感觉较慢,但能避免陷入更耗时的循环。
Q&A
AI编程代理修复bug时为什么会陷入循环?
循环由四个因素叠加导致:1. 会话变长后上下文退化,代理对应用的模型变得模糊;2. 模糊的重试(如“还是坏的”)只增加噪音,没有提供新信息;3. 代理无法像你一样看到真实界面,只能根据代码和文字描述推理,描述有损;4. 失败的尝试污染后续推理,每次重试都基于包含错误差异和沮丧纠正的上下文,导致问题 compounding。
如何打破AI编程代理的修复循环?
遵循五步序列:1. 停止盲目重试,不要连续发送“再试一次”或“还是坏的”;2. 回退到最后一个已知正常状态(用Git、本地历史或检查点);3. 从头重新描述问题,提供精确文件路径、具体可观察事实和期望的正确行为;4. 每次只改一处,不要捆绑多个问题;5. 亲自在真实应用中验证,而不是相信代理的声称。
给AI编程代理写修复提示时,怎样描述问题才有效?
提示应包含三个要素:确切的文件或组件名(字面路径,而非视觉描述)、具体可观察的错误事实、以及具体可观察的正确行为。例如,弱提示:“还是坏的。修复提交按钮。”强提示:“在CheckoutForm.tsx中,提交按钮调用handleSubmit,但请求失败时加载状态从未重置。失败提交后按钮保持禁用且无错误消息。它应重新启用并在按钮下方显示服务器错误字符串。”
为什么模糊的重试会让AI编程代理的下一次尝试更糟?
模糊重试如“还是坏的”或“再试一次”对代理来说几乎没有新信号,它不知道哪里坏了、涉及哪个文件、正确应该是什么样。代理通常只会稍微改变之前的猜测,导致循环在两个几乎相同的错误修复之间交替,而不是收敛。此外,每次失败尝试都留在对话上下文中,使下一次尝试基于噪音推理,进一步降低精度。
在打破修复循环时,为什么需要回退到已知正常状态?
回退可以防止在已损坏的代码上叠加新尝试,避免一个bug变成三个。使用Git(如git restore)、IDE的本地历史或构建器的检查点/版本历史,将应用恢复到你能识别的状态。只有在应用回到已知正常状态后,才输入新的修复请求。这样代理的上下文更干净,修复更可能成功。
如何验证AI编程代理的修复是否真正有效?
不要相信代理对自己修复的声称,因为它检查的是自己的推理,而不是你运行的产品。验证步骤:重新加载预览或硬刷新页面;点击实际失败的用户流程;如果bug涉及数据或API,检查数据库行、网络标签或日志;确认你在步骤3中写下的成功条件。只有完成这些,才能认为事件已关闭。
在修复循环中,为什么建议每次只改一处?
将“顺便修复头部”等额外问题捆绑到bug修复提示中,会让代理用一个上下文预算处理两个问题。对问题A的干净修复可能悄悄重新引入问题B。应该先发布一个修复,验证它,然后为下一个问题打开单独的请求。这样可以避免问题相互干扰,减少循环风险。