这半年我试着把 AI 当"结对伙伴"用:写业务代码时让它先出草稿,我再改。半年下来最大的一句体会是——它写出来的代码,最后签字负责的还是我。这个看似废话的结论,落到日常里比想象中难执行。
一、bug 率确实降了,但来了新一种提交
先说好的。我统计了自己这半年合并的 PR,和我纯手写的那半年比,明显的低级 bug(空引用、拼错字段名、漏判边界)少了一截。它把"按模式写对"这件事做得很稳,这部分我承认省心。当然这数字是我自己粗略对的,没有严格对照实验,只能算体感,别当结论用。
但它引入了一种新的、更隐蔽的提交:代码能编译、能跑通我给的 happy path,可它根本没测过——它只是"看起来对"。我有个活生生的例子:让它写一个按状态分页的查询,它用了 CreatedAt 排序然后 Skip/Take,单测里造的数据恰好是按时间顺序插的,全绿。上线后真实数据里有同一秒创建的两条,分页边界直接丢了一条。这种 bug 不是它写错,是它"没想过要测"。
所以从那以后我对自己定的规矩是:AI 写的代码,测试覆盖我必须亲自补边界和异常分支,不能只信它给的那几个绿色勾。
二、代码评审反而更重要了
我原以为有了 AI 帮忙写,评审能轻松点。现实相反:我得花更多精力审"它为什么这么写",而不是"它写对没有"。写的时候我参与了,但没逐行想清楚;审的时候才被迫把逻辑走一遍。
有个片段我记得清楚。它把一个循环里的数据库查询提到了外面,理由是"减少次数"。我第一眼觉得挺好,准备过。评审时多问了一句"这个列表最多多大",才意识到那个列表在某些租户下能到上万条,全加载进内存会爆。要不是评审这步,上线又是一顿报警。AI 不会主动告诉你"这里取决于数据规模",它只会给出一个在它见过的样本里成立的写法。
三、新人的"它写的应该没错"错觉
我们组去年来的小伙子,前两个月用 AI 写功能,提交得飞快。但有次我 review 他的 PR,发现一个权限判断被它简化掉了——原本要校验当前用户是不是资源 owner,它为了"代码更简洁"去掉了那行。小伙子自己也没察觉,他的原话是"它生成的,应该没问题吧"。
这件事让我警惕:当工具越来越能写,人越容易把"判断权"也交出去。我后来在组里提了一句——AI 出的是草稿,不是结论,合进去之前你得能向别人解释每一行为什么在。解释不出来的,就是还没懂,不能合。
说实话我自己也犯过类似的懒。有次它给了一段正则表达式做校验,我看着眼熟就放了,结果那个表达式在某个 Unicode 边界上会误判。所以"它写的不等于我懂的"这条,对谁都成立。
四、半年下来我的用法变了
最早我把它当"快点写完"的工具,现在更当"逼我想清楚"的陪练。具体变了三处:
- 动手前先把它当提问对象,让它列"这个需求有哪些我没想到的情况",往往比直接写更有用;
- 它出草稿后,我一定会重写一遍关键路径,重写时常常发现它埋的假设;
- 合入前补测试这件事,我从"顺手"变成"硬性动作"。
还有一个我之前没料到的副作用:因为写草稿变快,我更容易在没想透需求时就开干。需求模糊时它照样能写出能跑的东西,反而掩盖了"我其实没搞清楚要做什么"。这点我在另一篇里单独写过,这里不展开了。
五、回到开头那个问题
"AI 写完代码谁来负责"——答案平淡但必须有人接:写的人。工具帮你把键盘敲得快了,不帮你把判断做了。半年观察下来,它最值钱的地方不是替我写,而是逼我在审和测的时候把逻辑真正走通。这半年我反而比纯手写时更累一点,但提交下去心里更踏实。
(写这篇时翻了下记录,上面那个分页丢数据的 bug 是二月的,权限那件事是三月,时间顺序我按记忆排的,可能有几天出入,不影响结论。)
六、给团队的两点具体做法
半年踩坑下来,组里现在默认两条,不算规定,但大家都照做:第一,AI 生成的代码在 PR 描述里标一行"本 PR 含 AI 生成草稿,关键路径已手写复核",方便 reviewer 知道该多盯哪;第二,新人前两个月不允许把 AI 生成的代码直接合,必须先给导师讲一遍"每行在干嘛",讲得通才放。这两条把"它写的应该没错"的错觉挡在了合入之前。
不过我得老实说,这两条执行得时好时坏。忙起来标"已复核"有时会变成走过场,新人赶进度时也偶尔直接合了。所以它会退化,得有人偶尔抽查。工具带来的坏习惯,最后还是得靠人的纪律去兜,这一点我没什么好办法,只能承认它不自动成立。
我也给自己留了个记录习惯:每次它给出让我意外的写法,我顺手记一句到笔记里,下回同类任务先翻。半年来这类笔记攒了三十多条,反而比它写的代码更值钱——因为那是"我真的想明白"的部分,不是它替我填的空。