推行AI写代码一年后,Code Review变成了新的加班理由
一、AI写代码快,但review起来慢
今年年初,团队的核心项目交到了手上。组里几位同事都在用Cursor和Copilot,代码产出量确实可观。可一旦轮到自己来review这些提交,总感觉哪里不太对劲。

举个具体的例子。有位同事提交了一个功能模块,运行起来一切正常。但逐行细看时发现,一个组件里竟然塞了三个useEffect,其中两个的功能还是重叠的。问起来,同事也无奈,说是AI自动补全的,自己没太留意。这类情况后来几乎成了常态:AI生成的代码往往能跑通,但结构混乱、逻辑重复、边界判断缺失,这些“暗病”比比皆是。
对比起来,以前人工写的代码,你能隐约摸到作者的思路脉络。而AI产出的代码,更像是一锅精心调配却又略显怪异的大杂烩,该有的似乎都有,可读起来就是不对劲。到了review环节,任务就变了质——你不仅要判断逻辑对不对,还得额外花力气帮作者删冗余、补缺失、理结构。这一套流程走下来,耗费的时间不知不觉就翻了个倍。
二、几种AI代码的“通病”
看得多了,几种高频出现的“AI痕迹”也就浮现出来。
1. 逻辑正确,边界全无
AI很擅长把主流程跑通,但对于空指针、超时、并发这类边界情况,它往往缺乏主动处理的意识。比如生成一个查询接口,AI会流畅地写出data.list.map(...),却很少会前置判断data本身是否为空。review时,你就得手动帮它补上data?.list?.map,或者加上一句if (!data) return null。
2. 过度设计,简单问题复杂化
有时候,AI会把一件很简单的事情搞得特别“隆重”。就拿加个防抖功能来说,它可能会兴致勃勃地生成一个完整的自定义Hook,里面useRef、useCallback、useEffect一应俱全,洋洋洒洒四五十行。可实际上,可能只需要一个现成的debounce工具函数就足够了。review这种代码,你得先费劲理解它复杂的实现,然后再判断是否真的有必要。
3. 注释和命名像“机器翻译”
AI生成的变量名,常常是data、items、config这类通用词,具体指代什么,得靠猜。函数注释要么干脆没有,要么就是“获取数据”、“处理信息”这种说了等于没说的描述。review时,不得不额外花时间,把这些命名改成有业务含义的,或者补上关键注释,否则后续接手的同事根本无从下手。
三、怎么让review不那么痛苦
经过大半年的磨合,倒也摸索出几条还算管用的应对策略,能让review的体验稍微好一些:
- :在提交PR之前,可以要求作者把代码丢给另一个AI模型(比如换个引擎)再审核一遍,并根据其建议预先修改一轮。
让AI先审AI
- :工具类函数、单元测试、文档注释这些部分,可以放心交给AI去生成;但对于核心的业务逻辑,建议还是亲手写,或者对AI的产出进行深度重构。
差异化对待
- :在团队内部约定一些简单的代码规范,比如“
建立小规范
useEffect必须包含清理函数”、“API调用必须显式处理loading和error状态”。AI虽然不一定能自觉遵守,但review时有了这些对照项,检查起来会快很多。
这些办法谈不上根治问题,但至少能把review的时间成本拉回到一个可以接受的范围。
四、反思
如今对AI编程的态度,多少有些矛盾。一方面,它确实接管了大量重复、枯燥的编码劳动,效率提升是实实在在的。但另一方面,它似乎把负担巧妙地转移到了代码审查这个下游环节。以前是“一人写码,众人审阅”,现在则更像是“一人指挥AI写码,另一人替他审查AI留下的漏洞”。
这当然不是AI的错,也不是工具的错。问题的核心在于,我们还没有完全学会如何与这位强大的“协作者”高效共事。或许未来会出现更智能的review流程,或者AI能进化到自我审查的地步。但就眼下而言,一个略显无奈的现实是:
AI并没有让我少加班,它只是让我加班的内容,从“写代码”变成了“审代码”
五、最后
如果你所在的团队也正经历着类似的转变,或许会有共鸣。也欢迎在评论区聊聊:你们团队的Code Review,有没有因为AI的加入而变得更慢、更费力了?