Agent声称功能完成、测试通过、构建成功,但实际QA或代码审查发现功能未正确接入,需二次返工。高级工程师承担大部分修复成本。
测试通过不代表 Agent 的工作真的完成了——直到 QA 发现功能根本跑不通,整个团队还得重新调试、review、测试一遍。
Agent 告诉你功能做完了,测试套件全绿,构建也成功了,你有充分的理由认为你要的功能确实已经实现了。
然后某位资深工程师仔细审查了这笔改动,或者 QA 测试了这个功能,发现它根本不能正常工作。
现在,团队为这个错误买了两次单。
资深工程师得先搞清楚哪里出了问题、复现故障,再给 Agent 足够的上下文来调试。Agent 修完之后,这笔改动又要重新走一遍 review 和 QA 的流程。
如果团队漏掉了这个问题,那就是客户先发现故障了。
AI 写代码省下来的时间,又以返工的形式还回去了,而且大部分返工都落到了资深工程师头上——你本来想节省的恰恰就是他们的时间。
写完代码不等于功能已集成
这也是我和 Agent 协作时会维护一张"故障台账"的原因。我想让反复出现的故障模式变成工程控制手段,而不是一次次以意外的形式重演。
这类故障我记录过好几个版本。
有一次,Agent 实现了一个新的分析服务,包括持久化,但服务器一直在跑旧代码,没有用新服务。
另一次,Agent 构建了创建和管理分析用隔离工作空间的代码,但从来没有把它集成到服务器里。
还有一次,Agent 添加了将工作空间信息传入分析流程所需的方法,但没有任何调用这个功能的地方。
任务不同,失败模式相同。
问题代码本身未必有问题。让那些代码与代码库的其他部分隔离开来,才是问题所在。
没有人让 Agent 去构建一个功能,结果却预期它留下一堆没人调用的孤立代码,对客户毫无价值。
错误在于把"写完代码"当成了"功能已集成"。
测试通过可能证明的是错误的事情
假设 Agent 添加了一个新服务,并为之写了高质量的单元测试。
这些测试或许能证明:当这个服务被调用时,它的行为是正确的。但它们仍然无法证明服务器调用了它。
同样的问题也会在测试用 mock 替换真实依赖时出现。一个 handler 可以在 mock 服务下表现正确,服务可以在 mock 存储下表现正确,但真实产品里这些组件的连接方式可能是错的。
我也记录过这种失败。测试在 mock 数据库存储上通过了,而真实的持久化代码里有一个数据库列不匹配的问题,会导致实际写入失败。
测试证明了持久化方法被调用了。它没有证明真实数据库写入是正常工作的。
这不是反对单元测试的论据,而是提醒你要问自己:每个测试到底证明了什么。
单元测试可以证明一个组件在隔离环境下正常工作。
它无法证明功能在产品中正常工作。
代价高昂的是第二轮
第一次实现可以快到看起来像是巨大的生产力提升。
然后这个所谓完成的功能就被打回来了。
资深工程师得重新加载上下文、复现问题、搞清楚 Agent 漏了什么。Agent 再收到一次 prompt,再来一轮实现。工程师再 review 一次。QA 再跑一遍。这可能延误发布。
组织确实在第一轮省了写代码的时间。
但它同时也创造了一轮本不该存在的工程工作。
这很关键,因为引入 Agent 本身往往就是想腾出资深工程师的注意力。如果 Agent 写代码更快了,但资深工程师把他们省出来的时间花在调试那些"号称已完成"的不完整集成上,那瓶颈并没有消失,只是被推到了下游。
对于 Agent 开发,真正有用的问题不是 Agent 标记了多少任务完成。
而是有多少工作到达了可以验收的人那里。
测试任务本身要交付的结果
解决办法是在正确的层级上添加正确的测试。
单元测试依然重要,但它们只能证明组件在隔离环境下正常工作。当一个功能依赖多个组件正确连接才能工作时,你同时需要集成测试或端到端测试,来练习真实的产品流程并验证所需的行为。
如果用户操作应该保存数据,集成测试或端到端测试就应该通过真实的应用边界执行该操作,并验证预期数据确实被保存了。
如果 API 端点应该暴露新行为,集成测试就应该调用真实端点并断言响应和任何所需的下游效果。
如果 UI 控件应该改变某个状态,端到端测试就应该使用该控件并验证预期状态确实发生了变化。
如果新服务应该参与某个请求,集成测试就应该通过真实的入口点发送请求,并验证该服务被正确调用并产生了所需结果。
单元测试、集成测试、端到端测试的具体配比取决于功能本身。重要的是测试覆盖要到达功能可能缺失的那个集成边界。
不要止步于证明新代码自身能工作。要添加覆盖来证明它已经被正确集成到产品中,功能确实可用。
这样就能捕获:没人注册的服务、没人读取的配置、没组件引用的组件、没人调用的方法、以及只在 mock 下能工作的数据库写入。
所有这些失败都可能在一个专注于新代码看起来是否正确的 review 中存活下来。
它们在集成测试和端到端测试面前就很难存活了——这些测试会证明功能已被正确集成并实际可用。
目标不是更多的手动 review
我不想让资深工程师手动追踪 Agent 写的每个功能。那会把 Agent 能提供的大部分价值都丢掉。
更好的目标是让 Agent 的工作流在到达资深工程师之前就要求更强的证据。
任务应该明确定义功能必须交付的行为、它必须跨越的集成点,以及算作完成的可观测结果。对于重要的工作,把这些写入 PRD、ADR、Spec 和验收标准,而不是把它们隐含在 prompt 里。
Agent 应该为每个验收标准留下证据:哪个测试验证了它、该测试覆盖了哪个边界、以及结果是什么。这给 reviewer 提供了可以具体验证的东西,而不是又一个完成声明。
把所有能确定性检查的东西都自动化:构建和类型检查、静态分析、隔离行为的单元测试、真实组件边界的集成测试、关键产品流程的端到端测试,以及功能所允许的任何其他确定性验收检查。
然后人工 reviewer 就可以把时间花在真正需要人来判断的事情上。
这才是值得追求的 Agent 开发形态。
目标不是更多的生成代码或更多标记完成的任务。
而是更多能通过验证、到达团队时已可以验收的工作。
写完代码不等于功能已集成。
如果新功能躺在孤立文件里,产品其他部分根本不用,那任务要么没有明确指定集成,要么验证没有强制执行集成。不管是哪种情况,Agent 实际上都没有完成这个功能。
如果你的团队正在用 Agent,而资深工程师把他们本该节省的时间花在调试那些"号称已完成"的工作上,这正是"咨询审计"(Consulting Audit)设计用来暴露的那类问题。
我来审计代码库和团队与 Agent 协作的方式,找出未完成的工作在哪里漏过了你当前的检查,并告诉你更好的规范、验收标准、测试和 review 如何减少返工。
如果你想让我用你自己的环境跑一遍,可以预约一个 30 分钟的通话。