全部笔记
把报错丢给编码 agent,然后让开

2026年6月12日

把报错丢给编码 agent,然后让开

一个编码 agent 是好用还是让人抓狂,最大的区别通常不在模型,而在于你有没有把回路闭合。写完代码就停下的 agent 是在瞎猜;而一个会真的去跑代码、读真实报错、然后反复重试直到测试通过的 agent,完全是另一个量级——几次迭代之内修复率就冲过 90%。agent 只能修它看得见的东西,所以你能做的最高杠杆的事,就是给它一双眼睛。下面讲清楚具体怎么做。

如果你用过编码 agent,就一定体会过那两种截然不同的感受。有时候 agent 像魔法一样; 有时候它一脸自信地丢给你一堆坏掉的代码,你花在修它上的时间比它帮你省下的还多。 大家都以为这个差别在于模型——更聪明的模型会做得更好。但通常根本不在模型, 而在于 agent 有没有机会 看到它写的代码跑起来之后发生了什么

这是 agent 编码里杠杆最高的一个习惯,而且简单得几乎让人不好意思: 让 agent 把代码跑起来,把真实的报错给它看,再让它重试一次。 当你把这个回路闭合, 数字会有很大变化。关于 agent 错误恢复的研究发现,把失败的 stack trace 喂回 agent 的上下文里、让它一直迭代到测试通过, 几次尝试之内修复率就能进入 90% 区间——而有一套自我纠错系统 自己就解决了整整一类运行时错误中的 88%。 agent 并没有变聪明,它只是得以看见失败。

agent 只能修它看得见的东西

整个道理可以用一句话讲清,出自那些搭建这类工作流的人:如果 agent 看不到报错,它就修不了—— 如果它看不到测试输出,它甚至不知道有东西坏了。一个写完代码就停下的 agent, 就好比闭着眼睛写一篇文章,写完从不回头读一遍。它当然有一半时间是错的;它没有任何反馈。

人类开发者不是这么干活的。你写点东西,跑一下,读 traceback,「啊,第 42 行是 null」, 然后修掉。这个「跑—读—修」的回路,才是编程实际上的大部分内容。一个只做第一步——写——的 agent,缺的正是让活儿变正确的那部分。把回路给它,它就开始表现得像个开发者, 而不是一个自动补全。

好反馈 vs. 噪音

有个细节值得做对:不是所有错误反馈都一样。「测试失败了」几乎什么都没告诉 agent。 而具体、可操作的那种版本—— 「Expected 200, got 401」加上行号和 stack trace—— 告诉它该精确地追查什么。模糊的失败产出模糊的猜测;精确的失败产出精确的修复。 所以当你接好这个回路时,要把 真实的 输出传过去:完整的 traceback、行号、 那个具体失败的断言。别替 agent 把错误总结一遍——细节本身就是信号。

具体怎么做

这不是纸上谈兵,你也不需要任何花哨的东西。好用的 agent 工具—— Claude Code、Codex、Cursor 等等——本来就能在一个回路里跑测试、读失败、修代码。 你的活儿,是确保它们真的这么做:

  • 让它执行,而不只是写。 给 agent 一个能自己跑代码或跑测试的途径。一个没法跑任何东西的 agent,永远只能瞎猜。
  • 把测试当成目标,而不是建议。「让它通过」是个 agent 可以拿来验证自己的靶子。 没有测试,回路就没有东西可闭合——这正是为什么 agent 自己说「能用了」毫无价值, 而一个通过的测试不是。
  • 把原始的失败喂给它。 完整的 stack trace、行号、那个失败的断言——而不是你转述的版本。
  • 让它迭代,但要设上限。 跑几轮直到变绿是甜蜜点;无上限的循环只会烧 token。 两三轮就能修掉大部分问题。
  • 让它自己验证自己的活儿。 把「跑测试并确认通过后才算完成」写进你项目的常驻指令里, 这样 agent 就不会再 还没检查就宣布胜利

整套配方就这些:执行、把真实报错给它看、循环到变绿、停下。

结论

当 agent 写出烂代码时,人的本能是去抓一个更大的模型。但通常更便宜、更有效的修法, 是别再让它蒙着眼睛干活。一个没有反馈的编码 agent 是在瞎猜;同一个 agent, 如果能跑自己的代码、读到真实的报错,它就是在调试——而调试,正是正确代码的来源。 这跟 可靠性并非来自原始智力 是同一个教训: 胜出的关键不是更聪明的大脑,而是一个闭合的回路。

所以在你升级任何东西之前,先问那个最简单的问题:我的 agent 能不能看到它的代码跑起来后发生了什么? 如果不能,那才是你的 bug,不是模型的。把报错给它,让它一直循环到测试变绿,然后让开。 这是你会做的最便宜的一次升级,也是那个能把一个让人沮丧的 agent 变成一个好用 agent 的升级。

评论

暂无评论

登录以参与讨论。

做第一个分享想法的人。