ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI写代码后,评审比生成更难:用证据链Skill提升合并决策效率

AI写代码后,评审比生成更难:用证据链Skill提升合并决策效率 1. 当代码生成变得廉价合并决策反而成了瓶颈最近半年我身边几乎所有团队都在用 AI 辅助写代码。从补全单行到生成整个模块效率提升是肉眼可见的。但一个很奇怪的现象出现了代码产出速度翻了几倍上线速度却没怎么变。卡点不在写而在“敢不敢合”。我观察到的典型场景是这样的一个 Agent 或者 AI 助手给你生成了 300 行改动你看了一遍逻辑好像对命名也还行测试也过了。但你心里总有个声音在问——“它为什么这么改有没有漏掉边界这个函数被谁调用了改完之后会不会影响别的模块”于是你花 40 分钟去翻 git diff、查调用链、跑回归最后发现真正需要判断的地方只有 5 行。大量时间消耗在“建立信任”上而不是“做决策”上。这就是我想聊的核心问题AI 写代码之后真正稀缺的能力不是生成而是评审。而评审的关键是能不能快速拿到一条完整的“证据链”——从需求到改动、从改动到影响、从影响到验证每一环都有据可查。我最近在用的一个代码评审 Skill就是围绕“证据链”这个思路设计的。它不是帮你写代码而是帮你在合并之前把该看的证据一次性摆到桌面上。这篇文章适合两类人看一类是已经在用 AI 写代码、但被评审环节拖慢的开发者另一类是在搭 Agent 工作流、想把“评审”这一步自动化的工程师。我会从为什么评审比生成更难讲起然后拆解这个 Skill 的设计逻辑、实操步骤、我踩过的坑以及怎么把它接进你现有的工作流。全程不聊虚的只讲能直接抄的做法。2. 为什么“敢不敢合并”比“能不能生成”更难2.1 生成是概率问题合并是责任问题AI 生成代码的本质是概率补全。它根据上下文猜下一个 token猜得对不对取决于训练数据里类似场景多不多。这件事的风险是可控的——生成错了你改就是了成本很低。但合并是另一回事。合并意味着你签字画押这段代码进入主干出了问题你负责。这时候你需要的不是“看起来对”而是“我能证明它对”。证明需要证据改动意图是什么、影响了哪些调用方、测试覆盖了哪些路径、有没有引入新的依赖。没有这些证据合并就是赌博。我见过太多团队的做法是AI 生成完人肉扫一眼测试过了就合。短期没问题长期一定出事故。因为人肉扫一眼的覆盖率极低尤其是改动超过 200 行的时候你的注意力会在第 50 行之后断崖式下降。2.2 传统 Code Review 工具为什么不够用市面上的代码评审工具我基本都用过。它们的能力集中在“展示 diff”“加评论”“跑 CI”这三件事上。但 AI 时代的评审需求变了改动来源变了以前是人写的现在是人和 AI 混着写。你分不清哪段是人深思熟虑的哪段是 AI 顺手补的。改动规模变了以前一个 PR 几十行现在 AI 一次生成几百行很常见。传统 diff 视图在这种规模下基本失效。评审重点变了以前重点看“写得对不对”现在重点看“改得该不该”。因为 AI 写的代码语法通常没问题问题出在意图和影响范围上。提示如果你现在的评审流程还是“打开 diff 从头看到尾”那在 AI 辅助开发下你的评审时间会随着改动量线性增长而漏检率会指数增长。2.3 “证据链”到底指什么我说的证据链是一条从意图到验证的完整链路包含五个环节意图证据这次改动要解决什么问题对应哪个需求、哪个 issue、哪段对话改动证据具体改了哪些文件、哪些函数、哪些行改动的粒度是否合理影响证据这些改动会影响哪些调用方、哪些接口、哪些数据流验证证据跑了哪些测试覆盖了哪些分支有没有新增的边界用例风险证据有没有引入新依赖有没有改动公共模块有没有性能敏感路径这五条证据齐了你才敢说“我评审过了”。缺任何一条你都是在凭感觉合并。而这个 Skill 的价值就是把这五条证据自动收集、结构化呈现让你从“翻 diff”变成“读报告”。3. 这个评审 Skill 的核心设计把 diff 变成可追溯的证据包3.1 它解决的不是“看代码”而是“建立上下文”我第一次用这个 Skill 的时候最大的感受是它没有试图帮我“读懂代码”而是帮我“建立上下文”。这两件事差别很大。读懂代码是人的事AI 替代不了。但建立上下文是机械的事完全可以自动化。比如这次改动涉及哪几个 commit每个 commit 的 message 说了什么关联的 issue 里有哪些讨论改动前后函数的调用关系变了没有这些信息散落在 git log、issue tracker、IDE 的调用图里人肉收集要十几分钟Skill 几秒钟就能拉齐。它的工作方式是以 git diff 为起点向外辐射收集证据。diff 是核心但不是全部。它会顺着 diff 里的文件路径、函数名、变量名去查调用关系、查测试覆盖、查历史提交。最后输出一个结构化的证据包而不是一个扁平的 diff 视图。3.2 证据包的五个字段与生成逻辑这个 Skill 输出的证据包结构大致是这样的我用一个真实例子脱敏后展示字段内容生成逻辑intent改动意图摘要从 commit message 关联 issue 对话记录中提取changes改动清单按文件、函数、行号粒度拆解 diffimpact影响范围基于静态调用分析 测试文件匹配verification验证状态读取 CI 结果 测试覆盖率变化risk风险标记规则匹配公共模块、依赖变更、性能路径每个字段的生成逻辑都值得说一下。intent不是简单复制 commit message而是把多个来源的信息做了一次摘要。因为 AI 生成的 commit message 经常是“update code”这种废话它需要从 issue 和对话里补全真实意图。impact是最有价值的部分它会告诉你“你改了这个函数有 7 个地方在调它其中 3 个没有测试覆盖”。这句话直接决定了你敢不敢合。3.3 为什么用 Skill 而不是插件或独立工具这里要解释一个选型问题。市面上做代码评审的工具形态有三种IDE 插件、独立 Web 工具、Skill/Agent 形态。我选 Skill 形态理由有三个第一评审发生在工作流里不是发生在浏览器里。你写完代码下一个动作就是评审中间跳出去打开一个网页上下文就断了。Skill 可以嵌在终端、编辑器、CI 里不打断流。第二评审需要调用多个数据源。git、issue、CI、测试报告这些数据源各有各的接口。插件通常只能拿到 IDE 内的信息独立工具需要你手动导入。Skill 的定位就是“编排多个工具”天然适合这种场景。第三评审规则需要可定制。每个团队的“风险”定义不一样。有的团队公共模块改动必须双人评审有的团队依赖变更必须锁版本。Skill 的规则可以用配置文件写改起来比插件灵活得多。注意Skill 形态的代价是它依赖底层 Agent 的能力。如果 Agent 本身不稳定Skill 的输出质量也会波动。所以选 Skill 之前先确认你的 Agent 底座够不够稳。4. 从 git diff 到评审结论一次完整的实操链路4.1 环境准备与 Skill 接入我用的环境是终端 git 一个支持 Skill 的 Agent 运行时。接入步骤不复杂但有几个细节容易忽略。第一步确认你的 Agent 运行时支持 Skill 加载。不同运行时的加载方式不一样有的是配置文件有的是目录扫描。我建议先用一个最小 Skill 测试加载是否成功再上正式的评审 Skill。第二步准备数据源凭证。这个 Skill 需要读 git本地就行、issue tracker需要 token、CI 结果需要 API 地址。凭证不要硬编码在 Skill 里用环境变量注入。我踩过的坑是把 token 写进了 Skill 配置结果提交到了仓库虽然及时删了但教训很深。第三步配置评审规则。规则文件我建议从最小集开始先只配三条公共模块路径、依赖文件路径、性能敏感函数名。跑顺了再逐步加。一上来配几十条规则误报会让你直接放弃这个工具。# review-rules.yaml 示例 risk_rules: - name: public_module paths: [src/core/**, src/common/**] level: high - name: dependency_change files: [package.json, requirements.txt, Cargo.toml] level: high - name: perf_sensitive functions: [processBatch, renderFrame, queryIndex] level: medium4.2 触发评审一条命令拿到证据包接入完成后触发评审就是一条命令的事。我通常是在git add之后、git commit之前跑这样能在提交前发现问题。# 触发评审 Skill输出证据包 agent run review-skill --diff HEAD --output evidence.json跑完之后你会拿到一个 JSON 格式的证据包。但 JSON 不直观Skill 通常会再渲染一份 Markdown 报告。我更喜欢看 Markdown 版本因为可以直接贴到 PR 描述里。报告的开头是 intent 摘要然后是 changes 清单接着是 impact 分析最后是 risk 标记。我一般先看 risk如果有 high 级别的标记直接重点看那部分如果没有再按 changes 顺序过一遍。4.3 读懂 impact 字段调用链和测试覆盖的交叉验证impact 字段是整个证据包里信息密度最高的部分。它做了一件很聪明的事把调用链和测试覆盖交叉起来看。举个例子你改了一个函数calculateTotalimpact 会告诉你有 7 个地方调用它其中 4 个有测试覆盖剩下 3 个没有测试覆盖分别在orderService.ts、reportService.ts、exportService.ts这句话的价值在于它直接告诉你风险在哪里。有测试覆盖的调用方你可以信任测试没有测试覆盖的调用方你必须人肉看一遍。这就把“评审 300 行”变成了“评审 3 个调用点”效率提升是数量级的。我实测下来这个交叉验证的准确率大概在 85% 左右。误报主要来自动态调用和反射静态分析抓不到。所以看到 impact 说“没有调用方”的时候别全信尤其是用了依赖注入或者事件总线的代码。4.4 验证证据CI 结果和覆盖率变化怎么读verification 字段读的是 CI 结果和覆盖率变化。这里有个细节覆盖率变化比覆盖率绝对值更重要。如果这次改动让覆盖率从 72% 掉到 68%说明新增代码没有配套测试这是明确的风险信号。如果覆盖率从 72% 涨到 75%说明测试写得比代码多可以放心一些。绝对值 72% 本身说明不了什么因为不同模块的基线不一样。CI 结果我只看两件事有没有失败的 job以及失败的 job 是不是 flaky不稳定。flaky 测试会误导判断我一般会重跑一次确认。如果重跑还失败那就是真问题。提示把覆盖率变化阈值设成 2%。低于 2% 的波动可能是统计噪声高于 2% 的下降必须查原因。5. 踩过的坑证据链断裂的四种典型情况5.1 意图证据缺失commit message 是“update”这是我遇到最多的坑。AI 生成的 commit message 经常是“update code”“fix bug”“refactor”这种废话。意图证据一缺失整个证据链就断了——你不知道这次改动要解决什么问题后面的 impact 和 risk 都失去了判断基准。我的解法是在触发评审之前强制补全 commit message。具体做法是在 Skill 里加一个前置检查如果 commit message 少于 20 个字符或者匹配到废话模板就拒绝生成证据包提示你先补 message。# 意图证据前置检查 def check_intent(commit_msg): vague_patterns [update, fix, refactor, change, modify] if len(commit_msg) 20: return False, commit message 太短请补充改动意图 if any(p in commit_msg.lower() for p in vague_patterns) and len(commit_msg) 40: return False, commit message 过于笼统请说明具体改了什么、为什么改 return True, ok这个检查看起来很简单但效果立竿见影。因为一旦你被迫写清楚意图你在写的时候就会重新想一遍“我到底在改什么”很多低级错误在这一步就暴露了。5.2 影响证据误报动态调用抓不到前面提到 impact 的准确率大概 85%剩下的 15% 主要是动态调用。我遇到过一个典型案例一个函数通过事件总线被调用静态分析完全抓不到impact 显示“无调用方”。我差点就合了结果跑集成测试的时候炸了。后来我的做法是对 impact 显示“无调用方”的改动强制跑一次集成测试。静态分析说没有调用方不代表真的没有只代表静态分析看不到。集成测试是动态的能补上这个盲区。另外如果你的代码大量使用反射、依赖注入、事件驱动建议在 Skill 里加一条规则这类改动自动升级风险等级。因为静态分析在这类代码上的可靠性会大幅下降。5.3 验证证据过期CI 跑的是旧代码这个坑很隐蔽。CI 结果看起来是绿的但跑的是你 push 之前的代码。如果你在 CI 跑完之后又改了代码CI 结果就过期了。我的解法是在证据包里记录 CI 对应的 commit hash和当前 diff 的 hash 做比对。不一致就标记为“验证证据过期”提示重跑 CI。# 比对 CI commit 和当前 commit CI_COMMIT$(cat ci-result.json | jq -r .commit) CURRENT_COMMIT$(git rev-parse HEAD) if [ $CI_COMMIT ! $CURRENT_COMMIT ]; then echo 警告CI 结果对应 $CI_COMMIT当前代码是 $CURRENT_COMMIT验证证据已过期 fi这个检查我加进 Skill 之后至少拦住了三次“CI 绿但代码已变”的情况。每次都是小改动但小改动恰恰最容易让人放松警惕。5.4 风险证据漏报新依赖没被识别依赖变更的风险很高但识别起来有个坑不同语言的依赖文件格式不一样。JavaScript 是 package.jsonPython 是 requirements.txt 或 pyproject.tomlRust 是 Cargo.tomlGo 是 go.mod。如果你的规则只配了一种其他语言的依赖变更就会漏报。我的做法是把常见语言的依赖文件都列进规则并且定期检查有没有新增的语言。另外依赖变更不仅要看文件路径还要看内容——有时候依赖文件改了但只是版本号微调风险等级可以降一档。语言依赖文件风险等级JavaScriptpackage.json, package-lock.jsonhighPythonrequirements.txt, pyproject.tomlhighRustCargo.toml, Cargo.lockhighGogo.mod, go.sumhighJavapom.xml, build.gradlehigh6. 把评审 Skill 接进日常流程的三种姿势6.1 本地预评审提交前拦截这是我最常用的姿势。在git commit之前跑一次评审 Skill拿到证据包自己先过一遍。如果 risk 有 high 标记就重点看如果没有就快速扫一遍 changes。这个姿势的价值是把问题拦在本地。一旦代码 push 出去再发现问题修复成本就高了——要重新走 CI、重新评审、重新合并。本地拦截的成本最低。我一般会把这个命令做成 git alias这样敲起来快# 加到 ~/.gitconfig [alias] review !agent run review-skill --diff HEAD --output evidence.json cat evidence.md然后git review就能触发。实测下来本地预评审平均能拦住 60% 左右的问题剩下的 40% 需要 CI 和人工评审补。6.2 CI 集成自动生成评审报告CI 集成的姿势是每次 push 自动跑评审 Skill把证据包作为 CI artifact 上传同时在 PR 里贴一份 Markdown 报告。这个姿势的价值是让评审有据可查。以前评审是“我觉得没问题”现在是“证据包显示 impact 覆盖了 7 个调用方其中 4 个有测试3 个我人肉看过”。评审结论从主观变成客观。CI 集成有个细节要注意评审 Skill 的执行时间。如果 Skill 要跑几分钟会拖慢 CI。我的做法是把 Skill 拆成快慢两部分快部分只做 diff 解析和规则匹配几十秒出结果慢部分做调用链分析可以异步跑结果后补。6.3 Agent 工作流让评审成为生成的后置步骤如果你在用 Agent 写代码最顺的姿势是把评审 Skill 作为生成的后置步骤。Agent 生成完代码自动触发评审把证据包返回给 Agent让 Agent 自己先判断“这次改动敢不敢合”。这个姿势我还在摸索目前的效果是能拦住明显的低级问题但复杂判断还是需要人。比如 Agent 生成了一段改动评审 Skill 说“impact 有 3 个未覆盖调用方”Agent 会尝试补测试但补的测试质量参差不齐。所以我的做法是让 Agent 补完测试后再跑一次评审人工确认最终证据包。注意不要让 Agent 自己决定“合不合”。评审 Skill 提供证据决策权必须留给人。这是底线。7. 关于评审 Skill 的几个常见疑问7.1 它和传统静态分析工具的区别在哪传统静态分析工具比如 lint、类型检查、SAST关注的是代码本身的问题语法错误、类型不匹配、安全漏洞。评审 Skill 关注的是改动的问题这次改动该不该合、影响范围有多大、证据够不够。两者是互补的。静态分析告诉你“代码写得对不对”评审 Skill 告诉你“改动合不合得”。我一般先跑静态分析确保代码本身没问题再跑评审 Skill判断改动风险。7.2 小团队值得上吗值得但要简化。小团队不需要配几十条规则也不需要 CI 集成。我的建议是先用本地预评审姿势配三条核心规则公共模块、依赖变更、性能敏感跑两周看看效果。如果确实拦住了问题再考虑加规则和接 CI。小团队最大的优势是沟通成本低。评审 Skill 输出的证据包可以直接在群里贴大家看一眼就懂。这比开评审会效率高得多。7.3 证据包会不会太长没人看会。我第一版证据包输出 3000 多字没人看。后来我做了两件事分层输出和风险优先。分层输出是指默认只输出摘要intent risk impact 的关键结论详细内容折叠起来需要的时候再展开。风险优先是指把 high 级别的风险放在最前面让人第一眼就看到重点。改完之后证据包的平均阅读时间从 5 分钟降到 1 分钟但关键信息的触达率反而提高了。因为大家只看重点不被细节淹没。7.4 怎么衡量评审 Skill 的效果我用了三个指标评审时间从打开 diff 到做出合并决策的时间。我实测从平均 25 分钟降到 8 分钟。漏检率合并后发现的、本应在评审阶段发现的问题比例。我从 12% 降到 4%。证据完整度证据包五个字段齐全的比例。我从 60% 提到 92%。这三个指标不需要精确统计粗略估算就行。关键是看趋势不看绝对值。8. 我个人的使用体会用这个评审 Skill 大概三个月最大的变化不是效率而是心态。以前合并 AI 生成的代码心里总有点虚因为你知道自己没看全。现在有了证据包虚的感觉少了很多——不是因为你看了更多代码而是因为你知道哪些地方没看、为什么可以不看。这个转变很微妙。评审的本质不是“看完所有代码”而是“知道哪些代码可以信任哪些必须细看”。证据链的价值就在于它把“信任”从感觉变成了依据。还有一个体会是证据链会倒逼你写更好的 commit。因为你知道评审 Skill 会读 commit message你会不自觉地写清楚一点。这个倒逼效应是意外的收获但可能是最有价值的。最后分享一个小技巧把评审 Skill 的输出和 PR 模板结合起来。PR 模板里预留证据包的字段提交 PR 的时候自动填充。这样评审人打开 PR 就能看到完整证据链不用再去翻 CI、翻 issue。这个做法我们团队用了两个月评审效率提升很明显尤其是跨模块的改动评审人不用再问“这个函数谁在用”这种问题了。
返回列表