我最近在处理团队代码评审的复盘数据时,发现一个特别扎心的现象:提交量比去年同期涨了不少,但真正有价值的评审意见反而变少了。和几个同行交换完意见,发现这根本不是个案。“AI 写代码太多,评审跟不上”这句话已经在无数团队里成为日常。AI 代码助手能一口气生成函数、补测试、改调用链,但评审人还是那几个人,评审规则还是那几条,节奏还是那套“回头再看”。这篇文章是我自己调整评审流程时的完整复盘,包含现象拆解、为什么 AI 代码不能绕开人工评审,以及团队层面怎么把节奏拉回正轨。适合正在被合并请求积压折磨的开发者,也适合刚接手团队、想重建评审制度的负责人。
1. 现象拆解:AI 写代码之后,评审到底哪里崩了
1.1 伪代码量与有效代码量严重偏移
很多朋友喜欢用“AI 让我日更千行”来形容这件事,但这个数字其实有误导性。我翻过自己维护的几个代码仓库,把明显由 AI 辅助生成的提交单独统计出来,行数确实涨得猛,但新增代码里有不少是样板代码、重复的类型定义、AI 自作主张加的“防御性”分支,以及为了通过静态检查而补的空注释和占位返回。
这类代码我习惯叫“伪代码量”。听起来很多,实际没有给系统增加多少能力和复杂度,却实打实膨胀了 diff。问题在于,评审人读 diff 时并不会自动区分哪些是真实逻辑,哪些是凑数代码。于是每个人都被迫把大量时间花在没营养的重复内容上,真正需要集中精力的核心逻辑反而一带而过。这种偏差带来的直接后果是评审的“信噪比”快速下降。以前一个两百行的合并请求可能承载三个有效变更点,现在一个四百行的合并请求可能有六处变更,但夹杂着几十行 AI 生成的边角料,评审人来回扫了三遍才敢说看明白了。时间一长,大家都觉得读代码成本高,于是更不愿意深读,形成恶性循环。
更麻烦的是,AI 生成代码的“伪正确感”比真人写的更强的现象越来越普遍。真人写代码时会犹豫、会留 TODO、会写出风格不一致的片段,这些恰恰是评审线索;AI 生成的代码通常语法干净、风格统一、注释规整,看起来就“不太需要质疑”。这种光滑感非常骗人,也是评审质量掉得最隐蔽的原因。
1.2 评审队列积压,等待时间完全失控
评审阻塞最典型的表现不是意见少,而是排队。我见过一个十二人左右的后端团队,合并请求日均新增量从四到六个直接涨到十五个左右,但评审人其实还是那两三个核心开发。剩下的人在赶功能,顺手看一眼顺手回一句。结果平均评审等待时间从四小时的中位数一路跳到四十小时以上。
等待时间一旦超过半天,提交者的心态马上会变。很多人会直接切去开新分支写别的,等回到评审时上下文已经凉透,于是“改一行漏三行”。这边评审人也很委屈:刚看到一个很有价值的 PR 想认真审,结果提交者已经不在线了,等了两天才有回复,整个讨论的节奏被拖得稀碎。更麻烦的是,团队为了按期发版,往往会把积压太久的东西直接设置成可合并,评审从“质量关口”变成“事后补签”,只有出了问题才回头看那些被忽略的批注。
这个过程根本不是某个人懒或者态度差,而是队列长度超过人类耐心阈值之后,系统自动做出的妥协。你别以为只有大团队才这样,五六个开发的小团队如果同时开着四个需求分支,谁也不可能保持一整天的评审专注力。
1.3 评审从找问题变成走过场
等排队时间长了,你就会知道最终结果是什么样。有人开始用一句“Looks good”代替完整意见,有人只回复“请解决冲突”而完全不看逻辑,有人在群里问“这个 PR 有人看过吗”。我在团队里做过一次抽样统计,把 AI 参与比例较高的提交和人工手写为主的提交分开看,结果是 AI 参与的合并请求收到“提出质疑或追问”的比例明显更低。
这个现象最值得警惕。不是说 AI 的代码更正确,而是评审人面对一大片生成代码时,会下意识放松警惕。“读不懂生成过程”带来一种“不好质疑”的错觉,好像代码是从一个无所不知的模型里吐出来的,天然带着权威感。团队如果默认接受这种心态,评审工具上就会挂满“已读”状态,却没有一条真正问过“你这边的边界条件是什么”。
2. 为什么 AI 写出来的代码更需要人工评审
2.1 评审的四层价值,自动化一条都顶不掉
先说一个基本问题:既然 AI 能写代码、测试能自动跑、静态检查也能扫,为什么还必须留人肉 review?我的理解是,代码评审承载四层价值,自动化工具只能部分辅助。
第一层是正确性,代码是否符合需求预期,边界和异常有没有埋雷。第二层是可维护性,别人以后能不能读懂,扩展时会不会想骂人。第三层是一致性,改动是否遵从团队已有的约定,模块边界和依赖方向是不是合理。第四层是风险意识,是否悄悄引入了安全、性能或者长期演进上的隐患。
单元测试和静态扫描主要顶在最前面的正确性层,而且只能证明“覆盖到的用例符合预期”。可维护性和一致性天然依赖人对项目演进历史的理解,工具很难凭空判断“这里明明有现成能力为什么不复用”。AI 生成代码尤其容易在这两层出问题,因为它只基于一段提示词和当前文件来作答,并不会真的读懂整个系统的技术债和迁移背景。
2.2 AI 生成代码的两个典型盲区
第一个盲区是上下文缺失。生成式模型读过大量公开仓库,表现很像一个“熟悉所有标准写法但刚入职的新同事”:它能打出工整的代码,却不清楚你们项目里某个老接口为什么不能动、配置为什么要走统一入口、数据库字段为什么要保留冗余。从代码局部看,这些都是完全正常的写法,放到系统整体场景里就是隐患。
第二个盲区是“自信式错误”。模型只要没有强烈的不确定性信号,就会用非常肯定的语气输出看起来完全合理但实际不成立的实现。我亲眼见过一个后端接口生成代码直接把异常吞掉,配套的单测也同步补上了,测试用例恰好没有覆盖到异常路径。评审时明明能看出蹊跷,但如果大家都默认“AI 生成的东西是经过验证的”,这些坑就会被带进生产环境。
2.3 测试通过不能代替评审通过
有些开发同学觉得,既然 CI 跑不过就不允许合并,测试全绿了还 review 干什么。这个思路在 AI 时代尤其危险。AI 不但能写业务代码,还能反向生成大量配套测试,而这些测试往往是根据生成代码本身去补的,不是根据业务需求去设计的。如果生成代码有语义偏差,测试反而会把这个偏差固化成一个“正确行为”。
我自己的经验里有一个非常典型的例子:某功能模块需要一个分页稳定排序,AI 生成的排序实现功能测试全绿,但用的算法并不稳定,分页一多就会出现重复和丢失。这种需求语义差异,测试完全不会提示,只有真正理解业务的评审人能从上下文里嗅出问题。所以我团队有一条很明确的规矩:测试是质量底线,评审是质量天花板,缺一个都不行。
3. 团队层面:把评审节奏拉回正轨
3.1 从源头控制:限制单次提交规模
对抗评审阻塞最直接的办法不是劝大家“看快一点”,而是让每次需要看的东西少一点。普通功能分支,我建议把合并请求控制在三百到四百行以内,超过就必须拆成独立提交,每个提交对应一条明确的任务拆解。
拆开之后,很多细节问题会自动浮出水面。原来一个“实现用户管理页”的需求可能直接开出一个六百行的大 PR,现在要拆成接口定义、数据层改动、页面骨架、交互逻辑、异常处理五个小 PR。每个小 PR 都没有多少背景噪声,评审人可以很快进入状态,给意见也更具体。实现过程中我还会配合平台的自动提醒功能,超过阈值的 PR 直接打上“规模超标”标签,不会进入快速评审通道。这个限制本身也是在逼团队重新思考任务粒度,而不是永远被 AI 的生成速度推着走。
3.2 分层评审:快速通道与深度评审分开
不是所有改动都值得投入同样的评审深度。我习惯把变更分成三个风险层级,先分类再决定评审流程。
L1 低风险变更:比如注释、文档、配置格式调整、格式化、没有业务逻辑的重命名,这类可以走单人快速通道,提交者自查后找任意一位同事点个赞就能合并,但 CI 必须全量跑完。L2 普通功能变更:覆盖大多数需求改动,至少需要两个评审人,其中一个是模块负责人。L3 高风险变更:涉及数据库迁移、支付账务、权限体系、对外 API 协议、大规模重构,这类必须组织异步评审,至少三个人参与,并且要附一份影响面说明。
分层不是为了降低要求,而是把有限的评审精力集中到真正需要人的地方。AI 生成的代码更需要分级:如果只是工具自动补的样板或者迁移代码,可以直接走低风险通道;如果是核心业务逻辑,不管提交者是谁、写得是不是很干净,都必须按高风险处理,这一条没有商量余地。
3.3 给评审安排被保护的时间碎片
评审最被人吐槽的点就是“挤占写代码的时间”。我试过很多办法,最后真正见效的是把评审当成正式工作项排进时间盒。周一至周四下午固定留出三十分钟到四十五分钟作为评审窗口,在团队日历上直接占住。当天的新增请求必须在窗口开始前完成提交,窗口内唯一优先级就是评审。
一开始阻力很大,因为几乎所有人都觉得“写代码才是产出”。但跑了一个月之后,普遍反馈是零星被打断的时间少了,等待时间掉了三分之一,合并节奏反而更稳。这里的关键因素是管理者要先给出保护,否则窗口很快会被各种临时会议吃掉。评审窗口不是“有时间就看”,而是“到点就放下手头事情去处理”,这两者的体验差别非常大。
4. 实操细节:把评审动作变得具体可落地
4.1 给评审人一张可以勾选的检查清单
很多评审意见写得模糊,不是因为人笨,而是因为没有基线。我整理了一份适用大部分后端和前端团队的评审清单,内部复盘反复用,效果还可以,这里贴出来供参考。
表格化描述如下:
| 检查维度 | 问题示例 |
|---|---|
| 需求匹配 | 这个改动解决的是 PR 描述里的哪一条? |
| 边界与异常 | 输入为空、超限、异常返回是否都处理了? |
| 兼容性 | 会不会影响旧调用方?是否需要版本迁移? |
| 依赖方向 | 是否引入反向依赖或循环依赖? |
| 可测试性 | 核心逻辑有没有独立测试,测试是否和实现强耦合? |
| 性能隐患 | 有没有明显循环嵌套、重复查询、无意义扫描? |
| 命名一致性 | 是否符合团队规约?有没有重复造轮子的地方? |
| 安全问题 | 外部输入是否校验,权限模型是否完整? |
清单不是评审的全部,它的作用只是保证评审人不会在疲劳时漏掉基础项。真正有价值的意见往往来自清单之外,比如“这个东西放在这里,背后动机是什么”这类设计问题,但这些需要建立在基础项已经确认过得基础上。
4.2 让 AI 帮你做第一轮预筛,但保留人类判断
我现在允许团队成员用 AI 工具做辅助评审,但有一条铁规矩:AI 的建议只能作为“预筛意见”进入评论区,不能直接评审闭合。也就是说,AI 说“这里可能越界”,提交者必须自己判断这句话成不成立,并在回复里给出处理结论。为了让历史记录都可回溯,评论里还要打上明显的“机器人预审”标签。
这么做的收益很明显,评审人可以跳过大量低水平问题,集中讨论设计和取舍。但必须克制,不要将所有 lint 告警一股脑挂回评审工具。我踩过一个大坑:某个维护中的项目临时全量开启规则,一个二百行的小改动弹出了七十多条告警,评论区彻底变成噪音场,真正的设计讨论完全被淹没。更合理的节奏是先接五到十条高置信规则,比如未处理错误、密钥硬编码、明显越界访问,再逐步扩展。
4.3 给评审人提供足够的上下文
只写一句“优化了某某接口”的 PR 描述,是评审最大的敌人。我强制要求团队每个 PR 至少包含三段式说明:背景、影响面、验证方式。背景要交代为什么需要这次改动,对应哪个业务预期或技术债;影响面要写清楚改了哪些模块、调用方是否有变化、需要同步哪些文档;验证方式要说明本地怎么复验、依赖哪些测试用例。
如果 AI 参与生成代码,还要额外补一句“哪些代码由 AI 生成、哪些是手写”,这不是为了给人戴帽子,而是告诉评审人哪里需要特别警惕。AI 生成的代码缺少上下文意识,评审人知道来源之后,会自然把审查重点放到接口边界、异常处理和业务匹配上,效率会高很多。这个习惯花不了几分钟,但对后面读代码的人非常重要。
4.4 把挑毛病变成提问题
评审里最容易引发争端的表达方式是“这里写错了,改成 X”。AI 生成的代码尤其容易引起这种冲突,因为提交者自己都未必理解 AI 为什么要那么写。你直接给结论,等于剥夺了对方理解的空间,讨论就会变成拉锯战。
我更习惯用提问式表达:“这个分支为什么需要提前返回?调用方传空值时走到哪条路径?”提问不会立刻定义谁对谁错,而是把双方拉回到上下文里一起把问题弄清楚。一个经验是:如果评审意见能被一条“你说得对,但我这里特意处理过了”直接终结,说明问题问得还不够深。好问题应该让提交者重新审视自己的决策,而不是只做文字修改。
5. 常见问题与排查技巧实录
5.1 评审积压越来越严重,先从数据找入口
如果合并请求列表常年居高不下,第一件事不是发全员消息催大家 review,而是先拉数据。重点看四组:平均等待时间、有效评审意见数、单请求平均行数、评审人分布。按周拆开看,瓶颈很快就会浮出水面,要么是请求行数偏大,要么是评审人全部集中在同一两个人身上。
人手集中问题可以靠轮值制度解决。每周指定两名非提交者作为默认评审人,其他人员自由补充,平台支持的话直接把轮转配成自动分配表。我见过很多团队试过这个办法后,原来“热门模块挤满评论、冷门模块无人问津”的局面很快就改善了,评审责任也变得更均匀。
5.2 意见全是 Looks good,怎么打破
“Looks good”连发并不是团队氛围变好了,而是评审走过场的信号。我设置过一条很轻的规则:每个普通级别以上的 PR,至少要有 1 条有效评审意见。所谓有效,指的是可以被验证的问题,比如“这里没有超时处理,建议补充”这种可以落地的小项。
很多同事一开始觉得这条规则很形式化,但跑了几周后发现,它的价值不是凑评论数,而是强制评审人真正读完代码。因为你要是敢对没看过的代码随意提意见,提交者回一句“我明明已经在这里处理了”,你的公信力就没了。这个机制一旦稳定,团队会慢慢形成基于事实的讨论习惯,而不是靠客套话维护表面的“代码关系”。
5.3 提交者不愿意改,怎么继续推进
AI 生成的代码还有个尴尬情况:评审人提了六条意见,提交者回一句“这是 AI 写的,我也不太会调”。我的处理方式是把评审意见在结构上区分清楚:阻塞性意见和非阻塞性意见。阻塞性只限定在影响正确性、安全、数据一致性、依赖方向这些场景;其他优化项统一算作非阻塞性,可以直接记录为后续技术债。
这样既不会让请求被无限拖住,也不会放弃质量改进。提交者只需要对阻塞性意见负责,非阻塞性意见进入项目问题清单,由后续迭代继续偿还。分类这个动作本身也在训练团队对风险的判断,有些事情确实不完美,但不值得为此阻塞一次发布,那就果断放行、登记、后面处理。
5.4 AI 大规模重构带来的合并冲突风暴
AI 改代码最头疼的是“整文件重写”,哪怕逻辑只动一小块,diff 里全是换行、注释和类型声明的变化,评审人根本没法定位真实改动点。我给出的建议永远是在过程上控制,而不是事后抱怨。AI 辅助重构时,一个请求里只做一件事;真需要大范围替换,先合并纯格式化或者纯重命名,再合并真正的逻辑变更。
这里有几个平台技巧值得记下来:开启忽略空格功能,拍摄不跟踪纯空白变更的粒度,善用“忽略移动代码块”这类 diff 配置。如果变更实在太大,就让 AI 在提交说明里明确写一句“核心变化是 X,其余为机械迁移”。这句话经常能帮评审人省下半小时。
5.5 自动化规则太多,评审噪音全场淹没
把仓库的安全规则、复杂度检查、代码风格、lint 全部塞进评审工具,是我见过的另一条走偏路线。某次我为了“全面”一次性开满全部规则,结果一个二百行的小 PR 弹出了七十多条告警,大家在评论区讨论了半天规则而不是代码逻辑,心态直接崩了。
合理的方案是渐进式引入:先关闭所有非阻塞规则,只保留阻塞性告警;低优先级问题按告警级别汇总到外部,或者用脚本统计后统一踢进技术债。我给自己定过一个原则:评审工具里的每一条告警都必须有可执行的修法。没有修法或者修法成本过高的告警,只会让评审变成打字游戏。
6. 长期调整的经验:别把评审做成流程惩罚
6.1 评审最大的价值是知识传递,不是合并许可
代码评审的核心产出,绝不只是“合并前的净化”,而是团队认知的共同更新。AI 参与的代码越多,这种知识传递就越重要,因为提交者本人也经常读不懂自己提交的东西。每次评审都是一次把“AI 的黑盒决策”翻译成“人类可理解逻辑”的机会,翻译完之后,团队里至少多一个人能讲清楚这段代码为什么这样写。
所以我不建议把 review 完全自动化。工具能帮你扫雷,但不能帮你建立团队语境。只要团队还要做架构演进、还要维护公共模块,就必须有真人承担“这个改动放在整个系统里会怎样”的判断。这些判断没法写死在规则里,必须在一次次对话中积累。
6.2 用一个月的周期验证流程调整是否有效
调整评审流程不能靠拍脑袋,至少要给团队一个月的观察期。我每周都会看三组指标:请求平均等待时间、有效评审意见数、合并后回滚或者补丁率。这三条能同时反映“评审是否及时”和“评审是否有效”。
如果等待时间降了但回滚率没变,说明流程只是变快了,质量判断可能还没跟上;如果意见数少了但回滚率也降了,说明评审目标更聚焦了。这些指标不能只看单一维度,否则很容易被“数字好看”骗过去。尤其是 AI 代码占比越来越高的时候,回滚率比评论数更能反映评审的真实效果。
最后说一点我的个人体会。前几年我也觉得代码评审是流程包袱,但 AI 参与写代码之后,我反而更确信评审不可替代。AI 把“写代码”这个动作变得很便宜,却把“为什么这样写”“这套逻辑放进真实系统会不会出问题”这些判断推到了更重要的位置。把评审做好的关键不是增加审批层级,不是延长等待时间,而是缩小评审单元、给评审人安排被保护的时间、提供足够的上下文,再用工具去扛掉重复劳动。这四点只要做到,AI 提效的红利才能真正落进团队手里,而不是变成一堆越积越多的合并请求和浮于表面的 Looks good。