为什么 AI Agent 总是陷入死循环?根源可能在那些被你忽略的 Flaky Test 里
这种现象揭示了人类开发者与 AI 在处理不确定性时的本质差异。当 CI(持续集成)流水线出现红条时,人类的脑子里自带一套“噪声过滤网”。比如,一个经验丰富的开发人员看到某个集成测试失败,他能迅速判断出这大概率是因为测试服务器负载过高导致的超时,或者是某个数据库连接没预热,而不是代码逻辑真的写错了。在这种情况下,人类的选择是叹口气,点一下 Rerun,然后心安理得地继续写代码。这种基于经验的“潜规则”过滤,让我们能高效地跳过噪音。
但 AI Agent 并没有这种经验主义的直觉。在它的逻辑世界里,只有 0 和 1,红条就是错误,绿条就是通过。它无法在失败时猜测“是不是网络抖了一下”,也没法在心里嘀咕“这个测试用例一直抽风”。它会极其认真地把每一次随机失败都当成一个必须修复的 Bug。
于是,一个可怕的恶性循环开始了:AI Agent 监测到测试失败 → 分析错误日志 → 尝试通过修改代码来“修复”这个其实不存在的 Bug → 提交代码 → 导致原本正确的逻辑被破坏,引入了真正的 Bug → 再次尝试修复 → 最终导致整个模块崩溃。
我之前在调试一个自动化工作流时就遇到了这种情况。一个依赖于外部 API 的测试用例因为网络波动偶尔报 503 Service Unavailable,AI Agent 竟然尝试通过修改本地的重试机制和超时参数来“解决”这个问题,结果把整个服务的请求链路给改乱了,导致原本正常的 200 响应变成了 404。
这给我最大的启发是:在构建 AI Agent 工作流时,测试套件的“确定性”比测试覆盖率要重要得多。如果把测试套件看作是给 Agent 提供的 API,那么一个返回随机结果的 API 绝对无法支撑起一个可靠的自动化系统。
如果你正准备在团队中部署类似的 AI 自动化流程,我建议不要在 Prompt 里告诉 AI “如果遇到某个报错就忽略它”,因为这种软约束在复杂的上下文环境下极易失效。你应该从工程层面优化测试环境:
首先,必须对不稳定测试进行一次彻底的“大清洗”。那些偶尔失败的测试,要么通过增加资源隔离来彻底修复,要么直接从 Agent 的运行路径中剔除。不要让 AI 在充满噪声的环境中学习。
其次,强化环境的确定性。建议全面采用容器化隔离,确保数据库状态、系统时区、文件路径等外部依赖是完全可控的。避免出现那种“在本地运行通过,但在 CI 环境中偶尔失败”的幽灵 Bug。
最后,建立显式的代码标记机制。如果某个测试确实不稳定且短期内无法修复,最稳妥的做法是在代码层面将其标记为 @pytest.mark.skip 或类似的 flaky 标签。让 Agent 在运行逻辑中直接跳过这些节点,而不是让它在运行过程中去猜测是否需要忽略。
总之,AI Agent 的强大在于它从不厌倦、不跳步,但这把双刃剑在面对噪声信号时会产生严重的反噬。只有当测试结果变成绝对的确定性信号,AI Agent 才能真正从一个“尝试修复的工具”变成一个“可靠的开发者”。