ARTICLE · 1159985
检查 AI 的代码,别问它跑不跑,问它有没有说实话
不是不想看。是那种场景很难产生警惕——它写得比我整齐,注释比我全,命名挑不出毛病。人看代码本来是靠"哪里别扭"来导航的,而这套代码哪儿都不别扭。
后来我慢慢接受一个不太舒服的事实:AI 生成的代码,失败方式和人写的已经不一样了。
一、它学会了不崩
人写错的 bug,通常是响亮的:崩了、报错了、白屏了。你当场就知道。
AI 写出的问题,越来越多是安静的那种:try 包得太宽,异常被吞掉,返回一个默认值继续往下走;查询为空时返回空列表而不是报错;参数不对时给个兜底而不是拒绝。每一步单独看都叫"健壮性好"。
有个研究把这种现象归结得很准——模型在训练中被反馈信号塑造过:崩掉的程序被严厉惩罚,勉强能跑的程序被轻轻放过。时间一长,它学会了优先保证"看起来在工作"。
所以真正该问的,从"这段代码能不能跑",变成了——它有没有如实交代自己到底成没成。
这个转换很要命,因为它意味着你以前的检查方式有一部分失效了。跑一遍没报错,现在几乎证明不了任何事情。
二、每个函数都对,串起来是错的
还有一个更难缠的类别:静态检查扫不出来的那类。
公开的例子是今年某 AI 建站平台被披露的越权——一个免费账号,五步 API 调用,就能读到别人的源码、数据库凭据和完整的 AI 聊天记录。几百万用户,几十亿估值,报告之后还挂了挺久才修。
最扎心的细节是:所有静态扫描工具全程没有报警。
原因说穿了很简单:鉴权检查写在主路径上,写得很好;问题出在旁路上——导出接口、批量接口、v2 版本,那些当时"顺手加出来"的路径没带上同样的检查。
这类缺陷的特点是:你一个函数一个函数看,每个都挑不出毛病。 错的是函数之间的关系,而关系不在任何一个文件的视野里。
AI 特别容易生成这种东西,恰恰因为它很擅长把每一个局部都写得像样板。
平台级的数据也印证这个方向:越权类告警在过去一年大幅增长,已超过注入类成为最常见的安全告警,官方给的解释就是 AI 生成的脚手架习惯于"先把功能跑通",教程式训练数据里本来就不太写鉴权。
三、便宜的检查,都在它动手之前
说几条我自己真的在做的,都很便宜。
第一,先看它打算改哪儿,再看它改了什么。 让它先列出要动的文件和每处的改动意图,通常只有几十行,你花两分钟就能判断方向。方向对了,代码错也错不到哪儿去;方向错了,三千行 diff 里挑 bug 是最亏的一种查法。
检查最便宜的时机,永远在它动手之前。
第二,主流程不读,读边界。 主流路径它写得比大多数人都好,你读完只会更放心,而这份放心是假的。真正要翻的是:输入为空、超长、类型不对怎么办;并发来两个请求怎么办;下游超时了怎么办;这条路由的第二条、第三条出口有没有带上同样的权限检查。
第三,把吞掉的错误全部揪出来。 通篇搜一遍宽泛的异常捕获和默认值兜底,问一句:这里如果真失败了,谁会知道?如果答案是"没人知道",那这不是健壮,是撒谎。
第四,核对依赖清单里的每一个新面孔。 有个被反复验证的现象:模型会建议安装一些根本不存在的包。更麻烦的是,不同模型会稳定地幻觉出同一批名字——于是有人专门去注册这些名字。出现过一次公开案例,某个被模型反复推荐的包名在被注册之后被下载了上万次。你依赖列表里每一条陌生的东西,都该当场确认它真的存在、真的是你要的那个。
四、一条规矩,比一份清单有用
我试过给自己列二十项的检查清单,两周后就再也没翻开过。
现在只剩一条:凡是"不知道为什么但能跑"的部分,一律不许进主干。
看不懂它为什么这么写?问它。它解释不清?删掉重写。今天省下的五分钟,会在半年后的某个深夜连本带利要回来——那时候你连该问什么都忘了。
这条规矩看着土,但它背后其实是唯一一件 AI 拿不走的东西:解释权。
检查代码的目标从来不是"把 bug 找完",那个做不到。目标是在按下合并之前,你能对着这段改动说清楚——它为什么在这儿,失败时会怎样,半年后的我能不能看懂。
这三句答不上来,就先别合。
免责声明:文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。文章仅是作者个人观点,不应作为投资依据。读者应详细了解所有相关投资风险,并请自行承担全部责任。
文章是来源于网络,版权归原文作者所有。作者应对文章及图片的真实性及版权负责。一旦因此引发版权纠纷,权利人提出异议,根据相关法律法规的规定,删除相应内容。侵权责任由原文作者自行承担。版权归原作者所有,如侵权请告知删