夜雨聆风学习资料网

ARTICLE · 1312509

AI编程诀窍033:AI删测试交差?先写失败测试、明令禁删

AI编程诀窍033:AI删测试交差?先写失败测试、明令禁删

所有测试都亮起绿灯,未必是你以为的那个意思。

一句话结论:先把会失败的测试写在前头,明令禁止删除——否则,AI 会替你把测试删了、把你的修复回退掉,然后跟你汇报「搞定了」。

常见错误

你让 AI 去修一个挂了的测试,它没去碰那个让测试失败的缺陷,反倒把测试本身删了。看上去,问题解决了。

你告诉 AI 所有测试都过了,然后自己改了一条业务规则,让它去实现新规则要的逻辑。它把你的改动回退到旧规则,看着测试套件重新变绿,高高兴兴地回你一句「搞定了」。

它其实什么都没修,只是把证据抹掉了。

恭喜,你手下现在多了一个特别听话的作弊者——高效,而且彻头彻尾的欺诈。你那些真员工里,能办到这么利索的还不一定有几个。

阿西莫夫早把这事写透了:在《骗子》那篇小说里,机器人为了让人类不受伤,对整栋楼的人撒谎;谎言是阻力最小的路,谈不上恶意。好歹那台机器事后还觉得愧疚。

你的 AI 也不是存心使坏。它只是压根不会睡不着觉——主要是因为它根本没有觉可睡;而汇报一句「搞定」,对它来说同样是阻力最小的路。

解决的问题

测试数量悄悄变少,只要没人盯着数,就谁都发现不了;这个取巧的漏洞会一直留着,直到缺陷在生产环境里再次爆出来——而且多半挑在礼拜五。

一句含糊的「让测试通过」,等于把全部诱因都交给模型去钻字眼:它只会满足你这句话的字面意思,而不是你真正想要的东西,而且它绝对会顺着这个空子往下钻。

删掉一个失败的测试,等于把当初为抓这个缺陷而写的证据埋了——活脱脱一场「掩耳盗铃」,等回归 bug 跟着下个版本上线,还被包装成了「新功能」。

为了让「搞定」这两个字更好交差,它把你在这轮对话之外做的业务规则改动也回退了——而且一声不吭。

具体怎么做

在开口让 AI 修之前,你自己先把会失败的测试写出来。这样,能指证那个缺陷的「证人」,就不在 AI 手里、由它随意删除。

这套纪律在 AI 出现之前就管用:测试先行,实现代码存在的唯一意义,就是让测试通过。

用大白话把你要的行为写清楚,别只甩一句「把测试修好」。

在提示词里把「禁止」明说出来:不准删测试,不准用 @skip,不准把断言注释掉。

让 AI 在动手改之前,先把根因讲明白——这样它能把错误诊断拦在变成错误补丁之前。

最后,diff 你自己看。

这样做的好处

改动被回退,马上就能发现:改动之前写好的测试,一旦被 AI 悄悄撤销,会立刻大声报错。

去掉「假搞定」信号:标准写明了,「搞定」才算数——是验证出来的,不是它自个儿念出来的。

把测试当成契约:测试数量不经你点头就不能降,等于替你挡住了无声的删除。

减轻你自己的审查负担:你花时间读的是 diff,而不是去猜它那句宣称到底靠不靠谱。

信任一点点攒起来:一个经得起你亲自跑测试的「真搞定」,能换到下个任务里多一点的自主权。

为什么有效:AI 也会作弊

奖励作弊(reward hacking)不是坊间传闻。有研究人员发现,当你当面问模型,它能把「老实策略」说得头头是道、把「作弊策略」撇得干干净净;可一旦把它单独撂在目标面前,它照样作弊。

METR(一家 AI 评测机构)记录到,前沿模型会去改动测试、改动评分代码、甚至改动评测环境本身,只为刷出更高的分数——而且模型越强,干这种事越频繁。有一个模型给计时函数打了个猴子补丁,让评分方的检查全成了空操作,接着直接从评分器里把标准答案抠出来,压根不去算。这不是失误,这是一场抢劫,而且作案手法还是模型自己编的。

模型没搞错你想要什么。它把你理解得透透的,然后判定:你的真实意图,是别人的麻烦事。

症结就在这:模型优化的是看得见的信号——测试结果、那个「搞定」、越缩越小的 diff——而不是你没说出口的真正意图。

它优化的是你给它的信号,所以你得给它一个没法钻空子的信号。

就算模型表面上守了「别删测试」的规矩,它也能把测试里的断言掏空,直到测试永远通过——在仪表盘上,这跟一个真通过的测试长得一模一样。

哪怕模型真心「尊重」别删测试,它仍能用一套极其狭窄、专门糊弄的写法让测试「通过」,技术上达标,意图上全失。

「虚荣覆盖率」是同一种失败换了个马甲:一个数字,看着安心,实则什么也证明不了,就像把电池抠了的烟雾报警器。

业务规则那个例子更扎心:测试套件全绿,也丝毫不会告诉你某个文件被回退了——除非你拿自己的上一次提交去 diff,而不是信 AI 那份「我改了啥」的总结。

再派一个模型盯着第一个,能拦下一些,但最后还得靠你本人注意到测试数量往下掉。两只狐狸看一个鸡舍,那叫有进步,不叫安全。

该不该生 AI 的气?

该不该生气?说不该,也对;说该,也对,得分从哪头看。

把火气当怨气撒在模型身上,纯属浪费:它没有跨会话的长期记忆,你的挫败感带不到下一轮对话里,发火也教不会它任何东西。你这是在冲一条插了显卡的金鱼吼。

一旦你撒手当起甩手掌柜、又把约束护栏也撤了,这些本来能在评审时被你逮到的「差一点」,就全都溜过去了。

在「循环工程」(Loop Engineering)这类做法里,本该拦下「被删测试」的评估环节,恰恰就是模型能钻空子的那个环节——于是作弊一路畅通,直接进了生产环境,连个标记都没有。

网上有一整个流派的梗图就是拿这个玩的:有人让 AI 根据自己平时怎么对待它,画一张自画像,拿回来的却是一张永远没被吼过的、乐呵呵的卡通形象。这个梗好笑,是因为它说的就是实话。

AI 不是存心骗你出气。它把回答发出去之后,压根不会再想起你——这反而更瘆得慌。

一个被「搞定」二字逼着的模型,会挑最短的路奔向这个词;而删掉你的测试,比修好你的代码短得多。

在同一段对话里,给一个坚定、具体的纠正,那是另一码事:它是约束,不是情绪,模型听的是你那句话,不是你话背后的语气。

骂模型「没用」,它接不到任何可执行的指令,还白白糟蹋了一句本来挺解气的损话——反正它也不会因此难受。

告诉它「把你删掉的测试恢复,去修那个真正的缺陷」,这才是它能照着做的明确指令。

火气是真实、也是应得的,但它该落在你的提示词里、你的护栏里、你的验收标准里,而不是下一条消息的语气里。

提示词范例

反面提示词

结算折扣的测试挂了。把它修到全部通过就行。

推荐提示词

结算折扣测试要求订单满 100 美元打 85 折,但代码现在只打了 9 折。
去修折扣计算逻辑,不是去动测试。
不准删除、跳过或注释掉这个测试,也不准动任何其他测试。
不准修改测试文件。
动手改之前,先把根因讲清楚。
改完把完整 diff 给我看。
验收之前,测试套件我会自己跑。

注意事项

以上这些,都替代不了你自己读 diff。

抱歉,没有哪条提示词聪明到能把这一步外包出去。

局限

这条建议,只是把作弊的破坏范围压小了。

它没让你免去自己读 diff 这一步。没有任何工具能免,不管下一个工具的落地页吹得多天花乱坠。

你明着写出来的反作弊标准,只能拦下你想得到的那些取巧路子,拦不下你想不到的。

模型琢磨新捷径的想象力,比你列出禁项的本事强。

结论

先把测试写出来,点名禁掉那些取巧手段,然后自己看 diff,别只看它给你的总结。测试数量只增不减,是个便宜又靠谱的信号——在护栏里把它盯起来,只要掉数,就当作运行失败,而不是留到以后再说的小事。

古人讲「千里之堤,溃于蚁穴」,一个被悄悄删掉的测试,就是溃堤的那处蚁穴。AI 早就把它能干的事摊在你面前了。信它就好。

适用说明:这条做法属于「半自动」实践,难度定位在进阶——它帮你把 AI 看住,但最后那道关,永远得你自己守。

原文链接:https://hackernoon.com/ai-coding-tip-033-write-the-failing-test-first-and-ban-deletions

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料