用AI改bug时,我强制自己先写一句“复现命令”,命中率翻倍
先说背景。上周我维护的一个采集脚本,跑一批任务时总在第37条左右崩,报错是KeyError: 'url'。以前的我拿到这种错,第一反应是把报错贴给模型,让它猜哪里可能有问题。
这么做的问题不是模型不行,是我给的信息太穷。模型看不到数据长什么样,只能按“最常见情况”猜,于是它给了一串“加try/except”“用get兜底”的补丁。我照着改了,当天不崩了,第三天换个数据源又崩。
这次我换了个做法,给整个过程加了一道约束:在让AI动手之前,我必须先产出一条能稳定复现的命令。
什么叫“能稳定复现”:不是"我这里会崩",而是一行可以复制到终端、跑十次崩十次的命令。为了写出这行命令,我被迫做了三件事:
第一,把触发条件缩小。我从“跑整批任务”缩到“只跑第37条”,这就逼我去看第37条的原始数据,而不是整批日志。
第二,把输入固定下来。我把那条数据dump成文件,命令里写死这个文件路径。这一步很关键,因为它把“环境问题”和“数据问题”分开了。我很快发现不是网络、不是超时,是那一条记录的字段结构跟别的不一样。
第三,把预期和实际写清楚。命令跑完应该输出什么,现在实际输出什么,两行对照。
做完这三步我再看错误,其实已经很清楚了:那个数据源在缺字段时返回的是null而不是空字符串,脚本里判空用的是if not item.get('url')没拦住null进入了后续拼接。
真正让我改观的是接下来发生的事。我把这条复现命令连同两段原始数据一起发给模型,它一次就给了根因判断,还指出了同一个文件里另外两处有相同的判空逻辑没被我注意到。我grep了一下,属实。
对比一下两轮对话的成本:第一次我描述了半小时的“现象”,来回改了四轮;第二次我只发了一条命令加两个数据片段,一轮结束。差别不在模型,在于我给的信息能不能被验证。
现在我给自己定了条死规矩,写进我的日常流程:
遇到偶发bug,先把“偶发”这个词消灭掉,用固定输入把它变成必现。
复现命令必须能独立跑,不依赖我本地的隐式状态。
拿不出复现命令就不问AI,先自己花时间造一个。造不出来的,说明我还没理解问题。
这条规矩还有一个附带好处:复现命令本身变成了回归测试的种子。修完之后我把它存进项目里,下次同一个地方再出问题,一条命令直接判定。
踩过的坑也记一下:一开始我图省事,用“跑整批然后看日志”当复现方式,结果一条命令跑三分钟,来回试五次就是十五分钟,效率反而更低。复现要的是“最小”,不是“最真实”。最小且稳定,才有迭代价值。
结论很简单:AI不会因为你的报错截图变聪明,但会因为你的复现命令变得准确。把“描述现象”换成“给出可执行的最小复现”,是我今年在AI辅助改bug上性价比最高的一个改动。