
1. 当AI把代码写完之后评审环节到底卡在了哪里最近半年我身边几乎所有做开发的朋友都在用AI写代码。不管是补全一个函数、生成一套CRUD还是重构一段祖传逻辑AI确实把写这件事的门槛拉到了地板上。但有意思的是我发现一个很普遍的现象代码生成得越快团队反而越不敢合并。这个矛盾不是错觉。我自己带的一个小项目里就出现过这种情况——AI一口气生成了四百多行改动涉及三个模块的接口调整git diff拉出来密密麻麻。我盯着屏幕看了十分钟心里只有一个念头这玩意儿到底能不能合它改的这些地方有没有把我原来某个边界条件给悄悄改掉它引用的那个工具函数真的存在吗问题就出在这里。AI写代码的能力已经足够强但判断这段代码该不该进主干这件事依然压在人身上。而这个判断恰恰是最耗神、最需要上下文、最容易出错的环节。传统的代码评审靠的是人读diff、靠经验嗅味道可当diff的产出速度从一天几百行变成一小时几百行纯靠肉眼和记忆去扛迟早要崩。所以这篇文章想聊的不是怎么让AI写得更快而是怎么给合并这个动作装上一套有证据链的评审机制。我会围绕一个我实际在用的代码评审 Skill 展开讲清楚它解决什么问题、内部是怎么组织的、怎么落地到日常流程里以及我在用它的过程中踩过的那些坑。关键词里的 AI、代码评审、Skill、Agent、git diff基本就是这条链路上的五个核心节点我们一个一个拆。先说清楚适合谁看如果你只是偶尔用AI补个函数、改个bug那这篇文章里的很多机制你可能用不上但如果你所在的团队已经开始让AI参与真实业务代码的产出或者你自己在维护一个有一定复杂度的仓库那这套思路大概率能帮你把敢不敢合并这个心理负担降下来。2. 为什么敢不敢合并是个真问题而不是心理作用2.1 合并决策的本质是一次风险定价很多人把代码评审理解成看看写得对不对这个理解太浅了。评审真正在做的事情是给这次改动定一个风险价格合进去之后出问题的概率有多大出问题之后的排查成本有多高以及这个改动带来的收益是否值得承担这个风险。人做评审的时候其实是在无意识地做这套计算。看到一个改动只动了一个私有方法、有对应的单元测试、调用方只有一处心里就踏实风险定价低敢合。看到一个改动动了公共接口、改了配置默认值、还顺手格式化了一大片无关代码心里就发毛风险定价高不敢合。AI生成代码的问题在于它把改动规模和改动意图之间的关系打乱了。人写代码通常是一步步来的每一步都有明确的意图diff 读起来是有叙事线的。AI不一样它可能一次性把五件事揉在一起给你而且它不会主动告诉你我顺手改了这里。于是评审者失去了叙事线风险定价就失去了依据。2.2 纯靠人读diff的三个硬伤我总结下来人工评审在面对AI产出时有三个绕不过去的硬伤。第一个是注意力衰减。人对diff的注意力是有限的前一百行还能逐行看到第三百行就开始跳读到第五百行基本就是扫一眼结构。而AI生成的diff往往又长又密正好踩在这个衰减曲线上。第二个是上下文丢失。评审者脑子里装不下整个仓库的调用关系。AI改了一个函数的返回值类型评审者未必记得这个函数在另外三个文件里被调用过而且其中一处依赖了旧类型。这种跨文件的隐性依赖靠人脑记是不现实的。第三个是证据不可追溯。人评审完说一句我觉得没问题这句话背后没有任何可验证的依据。过两周出了问题回头查当时为什么合进去只能找到一句当时看着还行。这不是评审者不负责而是整个流程没有留下证据的习惯。2.3 证据链评审要解决的正是这三件事所谓有证据链的代码评审核心思路是把评审从人的主观判断变成可验证的检查项集合。每一次合并决策都要能回答几个具体问题这次改动动了哪些文件、哪些函数、哪些调用点有没有测试覆盖到这些改动有没有静态检查通过有没有潜在的风险模式被命中这些问题一旦被结构化地收集起来评审者面对的就不再是一坨diff而是一份带结论的报告。报告里每一条结论都指向具体的证据比如第37行新增了一个空指针解引用风险因为上一行的返回值可能为null证据是第35行的条件分支没有覆盖null情况。这就是我推荐的那个代码评审 Skill 的立足点。它不是一个帮你读代码的工具而是一个帮你收集证据、组织证据、呈现证据的流程封装。下面我们进入它的内部结构。3. 这个代码评审 Skill 的内部结构从diff到证据链的四层拆解3.1 第一层diff解析与改动单元切分任何评审的起点都是git diff。但直接把原始diff丢给人看信息密度太低。这个Skill的第一层做的事情是把diff切分成有意义的改动单元。什么叫改动单元简单说就是一组逻辑上相关的改动。比如AI为了修一个bug改了函数A的实现、加了函数A的测试、更新了调用函数A的地方这三处改动虽然分散在不同文件但逻辑上是一件事应该被归为一个单元。切分的依据主要有几个文件路径的相似度、改动行的邻近性、函数/类边界的对齐、以及改动类型的聚类新增、删除、修改。我实测下来按函数边界切分是最稳的因为函数是代码里最自然的语义单元。这一步的产出是一份结构化的改动清单每个单元包含涉及的文件列表、改动的行范围、改动类型、以及一个初步的摘要。这个摘要不是给人看的最终结论而是给后续层做输入用的。3.2 第二层静态证据采集有了改动单元第二层开始采集证据。这一层是纯机械的不涉及任何主观判断采集的都是客观事实。采集的证据类型包括语法层面的检查结果比如lint输出、类型检查结果如果项目有类型系统、单元测试的覆盖情况哪些改动行被测试覆盖了哪些没有、以及调用关系分析改动的函数被哪些地方调用。这里有个细节值得说调用关系分析不能只看直接调用还要看间接调用。我遇到过一种情况AI改了一个工具函数的默认参数直接调用方只有两处但这两处又分别被其他模块调用实际影响面是七处。如果只做直接调用分析就会漏掉后面五处。采集完的证据会被打上标签比如覆盖已测试、覆盖未测试、调用直接、调用间接、风险类型变更。这些标签是后续判断的基础。3.3 第三层风险模式匹配第三层是我觉得最有价值的一层。它做的事情是把改动和一组预定义的风险模式做匹配。风险模式是什么就是那些历史上反复导致问题的代码改动特征。比如公共接口的签名变更、配置默认值的修改、异常处理的删除、边界条件的调整、并发相关代码的改动、以及大面积的格式化改动混在功能改动里。这些模式不是拍脑袋定的而是从真实的故障复盘里提炼出来的。我自己的项目里就有一条模式叫默认值变更因为曾经有一次AI把一个超时时间的默认值从30秒改成了3秒测试环境没暴露上线后大量请求超时。匹配到风险模式之后Skill不会直接下结论说有问题而是标注出来并附上具体的证据位置。评审者看到的是第120行修改了超时默认值从30秒变为3秒该配置在配置文件中有覆盖但生产环境配置未同步更新而不是一句干巴巴的注意默认值。3.4 第四层证据链组装与呈现最后一层是把前面三层的结果组装成一份可读的报告。报告的结构通常是改动概览、逐单元的详细证据、命中的风险模式、以及未覆盖的检查项。这里有个设计原则很重要报告要能回答如果我不合并理由是什么如果我合并我承担了什么风险。所以报告里会明确列出已确认无风险的项和存在未验证风险的项让评审者一眼看到决策的边界在哪里。我特别喜欢这个Skill的一点是它会把未覆盖的检查项单独列出来。比如某个改动没有对应的测试它会明确写该改动无测试覆盖建议人工重点审查。这种诚实的呈现方式比那些假装什么都检查过的工具靠谱得多。4. 把Skill接进日常流程三种落地方式和各自的适用场景4.1 本地预检提交前的自检关卡最轻量的落地方式是在本地提交前跑一遍。开发者写完代码准备git commit之前先让Skill对当前工作区的改动做一次评审生成报告。这种方式的好处是反馈快开发者自己就能看到问题不用等到评审环节。我自己的习惯是AI生成代码之后先不急着提交跑一遍预检把报告里标红的地方过一遍。很多时候能发现一些低级问题比如忘了删调试日志、改了不该改的配置。适用场景是个人开发或者小团队流程还没那么重主要靠开发者自觉。缺点是依赖人的主动性如果开发者跳过这一步后面就没有兜底。4.2 提交钩子把预检变成强制动作如果团队希望更硬一点可以把Skill挂到pre-commit或者pre-push钩子上。这样每次提交或推送都会自动生成评审报告报告可以存到本地或者上传到指定位置。这里要注意一个平衡钩子不能太重否则会拖慢开发节奏。我的做法是钩子只跑快速检查语法、类型、风险模式匹配耗时的检查比如全量测试覆盖分析放到CI里跑。适用场景是有一定规范要求的团队希望评审有统一的起点。缺点是如果钩子设计得不好容易引起开发者反感觉得被卡脖子。所以报告的语气和呈现方式很重要要让人觉得是帮忙而不是找茬。4.3 CI集成作为合并门禁的一部分最重的落地方式是把Skill集成到CI流程里作为合并请求的一个检查项。合并请求创建后CI自动跑评审生成报告并附在请求上。如果报告里有高风险项可以配置成阻止合并或者至少要求评审者显式确认。这种方式的好处是证据链完整每次合并都有对应的评审报告存档事后追溯有据可查。缺点是配置成本高而且需要团队对什么算高风险有共识否则容易变成形式主义。适用场景是多人协作、对代码质量有较高要求的项目。我参与过的一个项目就是这么做的效果不错但前期花了不少时间调规则把误报率降下来。落地方式反馈速度强制力配置成本适合团队规模本地预检秒级弱低1-3人提交钩子秒级到分钟级中中3-10人CI集成分钟级强高10人以上5. 实测中那些让我印象深刻的坑和应对5.1 误报太多会让人直接忽略报告我刚开始用的时候把风险模式配得太宽结果一份报告里标了二十多处潜在风险其中大部分是误报。开发者看了两次之后就再也不看报告了直接点合并。这个坑的本质是证据链的价值在于信噪比不在于覆盖度。一条被验证过的真风险比二十条模棱两可的提示有用得多。后来我把规则收紧只保留那些历史上真实导致过问题的模式误报率降下来之后报告才重新被重视。我的建议是初期宁可漏报不要误报。漏报的代价是偶尔出问题误报的代价是整个机制被废弃。5.2 改动单元切分不准会导致证据错位有一次Skill把一个改动切成了两个单元结果证据采集的时候测试覆盖的证据挂到了错误的单元上报告里显示该改动有测试覆盖实际上覆盖的是另一个单元。这个问题的根因是切分逻辑太依赖文件路径而那次改动恰好跨了文件但逻辑上是一件事。后来我调整了切分策略加入了函数调用关系的权重跨文件但调用链相关的改动会被归到一起。这个坑提醒我任何自动化分析都有边界评审者不能完全把判断权交出去。报告是辅助不是替代。5.3 风险模式需要跟着项目演进风险模式不是一次配好就完事的。项目在变技术栈在变新的问题类型会不断出现。我现在的习惯是每次线上出问题复盘的时候都问一句这个问题如果提前用Skill检查能不能发现如果能就补一条模式如果不能就想想为什么不能。这样下来风险模式库是活的跟着项目一起长。我见过一些团队把规则配好就不管了半年后规则和实际完全脱节报告也就没人看了。5.4 报告的可读性比技术深度更重要我早期做的报告技术上很完整但读起来像天书。后来我改了一版把结论前置证据后置用大白话写摘要技术细节折叠起来。改完之后开发者反馈说终于知道该看哪里了。这件事让我意识到评审报告的第一读者是忙碌的开发者不是审计员。报告要能在三十秒内让人抓住重点剩下的细节留给愿意深挖的人。6. 从敢不敢合并到知道为什么敢合并回到最开始的那个问题AI写代码之后真正难的是敢不敢合并。这个敢字背后其实是对风险的认知清晰度。认知越清晰越敢做决定认知越模糊越倾向于拖延或者盲目合并。有证据链的评审机制做的事情就是把模糊的认知变清晰。它不替你做决定但它把决定所需的信息摆在你面前这次改动动了什么、影响面多大、有没有测试、有没有命中已知风险、哪些地方还没验证。我用这套机制最大的感受是评审从凭感觉变成了看清单。以前合一个AI生成的改动心里是虚的合完之后还惦记着现在合之前看一眼报告知道风险在哪、边界在哪合完之后心里是踏实的。这种踏实感才是效率真正提升的前提。如果你也在被AI生成代码的合并问题困扰我的建议是从最小可用开始先做本地预检把风险模式配得保守一点跑一段时间积累一些真实案例再逐步往CI集成走。不要一上来就搞大而全的规则库那样大概率会因为误报太多而被放弃。最后分享一个我自己的小习惯每次合并一个AI生成的改动之后我会在合并信息里附一句这次评审的关键结论比如已确认无接口变更测试覆盖完整。这句话看起来不起眼但过几个月回头看它就是那次决策的证据。证据链不是工具给的是习惯养出来的。