AI 写代码越来越快,为什么 Code Review 反而更慢了?

发布时间:2026/6/30 15:06:30
AI 写代码越来越快,为什么 Code Review 反而更慢了? AI 写代码越来越快为什么 Code Review 反而更慢了副标题引入 Open Code ReviewOCR的真实经历我们如何把 AI review 从「30 条噪音」变成「12 条真正值得看」的评论。过去一段时间Molio 的开发流程发生了一个明显变化AI 写代码越来越多了。新功能、重构、修 Bug很多代码都是先由 Claude Code、Codex 等 Agent CLI 生成第一版再由工程师 review、修改、合并。原本以为AI 写代码之后研发效率会一路提升。结果真正跑起来以后我们发现新的瓶颈出现了。代码写得越来越快Code Review 却越来越慢。原因很简单写 1000 行代码可能只需要几十分钟认真 review 1000 行代码却往往比写代码更耗精力。随着 AI 提高了代码产出速度人类 reviewer 很快就成了整个流程里最慢的一环。于是我们开始尝试让 AI 去 review AI 写的代码。结果比想象中复杂得多。我们试过三种办法第一种是直接让大模型 review PR diff。优点很明显几乎零成本。但稳定性并不好。同一个 PR 连跑两次评论数量和内容都可能差很多。更重要的是模型很容易把注意力放到一些「显眼但价值不高」的地方例如一段中文字符串一个catch {}一个 magic number真正值得关注的语义问题反而容易被淹没。第二种是把 ESLint、TypeScript 检查收紧。它们确实能很好地解决规范问题。例如未使用变量空 catch类型错误风格一致性但是像 race condition、stale closure、path traversal 这类语义 Bug它们天然发现不了。第三种就是继续人工 Review。准确率最高但吞吐始终上不去而且 reviewer 很容易疲劳。后来我们逐渐意识到我们真正需要的其实不是一个更聪明的 AI而是一种职责划分LLM 负责发现语义 BugLinter 负责规范检查人只关注 AI 和静态分析都解决不了的问题于是我们开始尝试阿里的AI驱动的代码审查 CLI 工具—— Open Code ReviewOCR。OCR 比直接让 LLM Review多了一层什么刚开始我也以为 OCR 的价值只是「把 prompt 封装好了」。真正用下来以后发现它更多解决的是工程化问题。例如规则可以版本化。团队把规则写进.opencodereview/rule.json随仓库一起维护。规则修改可以走 PR可以 Git blame不再依赖某个人脑子里的 prompt。会主动补上下文。OCR 不只是把 diff 丢给模型而是会按需读取相关代码、类型定义、调用关系让模型拥有比单纯 diff 更多的信息。很多误报其实都是因为上下文不足。会做事实核查。OCR 内置了 REVIEW_FILTER_TASK会检查评论是否能够被 diff 直接反证。例如评论说文件里存在 XXX但 diff 根本没有 XXX。这种评论会直接被过滤。还能直接集成 GitHub PR。评论最终直接落到对应代码行reviewer 不需要切换工具。整个思路其实很合理ESLint 负责规范。OCR 负责语义。人负责架构和业务。可惜现实并没有这么理想。第一个坑LLM 太喜欢认真工作OCR 上线第一周我就把它关掉了。不是因为它不准。而是因为它太能说。一次 PR大概三四十条评论。其中大部分都是这里硬编码了中文字符串这里 catch 是空的建议抽一个 helper建议去掉 magic number建议不要嵌套三元表达式这些问题有没有道理都有。问题在于它们本来就是 ESLint 的职责。Reviewer 已经看过 ESLint再看一遍 AI 的重复提醒没有任何增益。真正重要的问题反而被埋没了。第二个坑我以为问题在 Workflow我的第一反应是做后处理。在 workflow 里加了一层过滤正则过滤低价值评论path line body 去重真实 PR 跑下来以后结果很尴尬。regex0 命中。因为 OCR 的评论写得非常正式。它不会说Looks good.也不会说This is fine.而是Hardcoded Chinese strings detected…这些完全匹配不到。去重也没什么效果。真正重复的评论LLM 会重新组织语言。如果按内容去重去不掉。如果按位置去重又可能把同一行两个真正不同的问题一起删掉。折腾了一晚上我发现自己一直在错误的地方用力。第三个坑读完源码我才找到真正的杠杆后来我把 OCR 的源码 clone 下来读了一遍。读完以后发现之前很多判断都是错的。真相一rule.json 不是硬规则我原来以为rule.json 是规则。实际上它只是作为Review Checklist放进用户提示词。如果 diff 里某个 token 特别显眼例如catch{}或者上传失败模型的注意力很容易被这些 token 吸走。仅仅写一句不要报告硬编码字符串。作用并不明显。后来我们改成把 NEVER REPORT 放到最前面给具体 token 示例效果才开始稳定下来。真相二默认规则和我们的目标相反继续读源码以后我们发现 OCR 默认的 TS/JS 规则其实鼓励报告硬编码字符串duplicate codenested ternaryasync error handlingnull check而这些很多正是我们不希望 AI 重复报告的内容。因此rule.json 不能只是补充规则而需要显式禁止这些类别。真相三merge_system_rule: false很重要最开始我还以为保留系统规则再追加自己的规则会更安全。实际上恰恰相反。如果系统规则在前鼓励报告硬编码字符串后面的用户规则再说不要报告模型很容易优先遵循前面的内容。因此我们最终选择merge_system_rule:false直接替换系统规则。真相四REVIEW_FILTER_TASK 不是质量过滤器以前我一直以为OCR 已经内置了低价值评论过滤。实际上不是。它只负责事实核查。能够证明评论与 diff 不一致它就删。至于评论有没有价值它完全不判断。因此低价值评论只能从 rule.json 源头控制。真相五Review 模式本身没有 Dedup读 task template 后才发现Review 模式没有 DedupTask。真正的评论去重只存在于 Scan 模式。这也解释了为什么 reformulated 重复评论会直接出现在 PR 里。真正的改动其实只有一个地方后来我们没有继续修改 workflow。而是回到 rule.json。核心思路只有一句话把模型的注意力从规范问题重新拉回语义问题。我们主要做了几件事把NEVER REPORT放到最前面每条规则都配具体 token 示例例如上传失败、void someAsync()、fs.*Sync()删除对模型没有帮助的说明性文字最后增加一句明确约束If your finding matches ANY of the above, DO NOT post it.同时保持merge_system_rule:false整个 workflow 里的 regex 和 dedup 逻辑也全部删掉了。验证结果我们用同一个 commit、同一个 PR再跑了一遍。指标调整前调整后评论总数3012低价值评论240发现的语义 Bug612那些反复出现的i18nmagic numberempty catchnested ternarycosmeticsync I/O 建议都没有再出现。与此同时新发现了一些真正值得 reviewer 关注的问题例如symlink 导致目录穿越风险MIME Type 欺骗Markdown placeholder 冲突WikiLink 解析顺序导致路径转换错误这些都是 ESLint 不可能发现也是人工 review 比较容易遗漏的问题。这也是我们真正希望 LLM 去做的事情。这次踩坑最大的收获回头看真正的问题并不是模型能力。而是我一开始没有找到正确的杠杆。我先写了一晚上 post-processing。后来花了两个小时读源码。真正修改 rule.json大概只用了半小时。最后起作用的也只有 rule.json。这件事让我重新认识了一点AI 工具越来越多但真正决定效果的往往不是模型本身而是工程化。Prompt 不是工程。Workflow 也不是工程。只有把规则、上下文、校验、CI 串成一套流程AI 才真正成为研发能力而不是一个聊天工具。写在最后如果你们也在尝试让 AI 参与 Code Review欢迎评论区分享你们的实践。例如不同模型下规则是否需要分别维护如何应用多套不同的 Review 策略比如AI 写的代码和人写的代码采用不同的review策略配置除了 OCR你们还在使用哪些工具这些问题我们目前也还在持续探索。Molio 是一个GitHub开源项目这套 OCR 配置也已经放进仓库Star项目随时关注动向。如果你有不同的思路欢迎一起讨论也欢迎直接提出 Issue。