1. 代码审查为什么还需要一个“辅助引擎”
先说个我自己的经历。去年有一次上线,后端改动只有十几行,跑完测试我就直接合并了,结果线上报表数据错了一整天。回查原因时发现,问题恰好藏在那十几行 diff 里——一个字段在组装时被提前覆盖了。给我 review 的同事那天也在忙别的,草草看了一遍,回复是“看着没问题”。不是他不负责,是人工 review 在这种琐碎改动上,真的很难每次都保持敏锐。
后来我开始把一部分 review 工作交给 AI 助手来做,就是围绕open-code-review这套思路搭的流程。说白了,它不是一个传统的“安装即用”软件,而是一套开放的代码审查方案:以 Claude Code 作为审查执行引擎,配一份团队可以随意改的审查规则文件(CODE_REVIEW.md),再加上手动、提交前、CI 三种触发链路。这样 AI 审出来的内容,不是你随手问一句“帮我看看代码”那种空泛回答,而是按你团队自己的规范、自己的输出格式,产出一份能直接拿去合并参考的审查意见。
这个方案适合谁?我的答案是:独立开发者、三五个人的小团队,以及在大团队里想给现有 review 流程加一道“AI 预审”的人。它解决的核心问题有三个:review 时间滞后、人工疲劳导致的漏看、以及代码规范执行不统一。如果你也经历过“review 只是走个过场”的尴尬,那这篇文章应该能给你一些可以直接落地的思路。
这套流程跑通之后,我的一个切身体会非常明显:人工 review 的价值被释放出来了。AI 负责挑那些“一眼假”的问题——风格不一致、明显的空指针风险、危险的 API 调用、缺少错误处理之类的,而我只需要重点关注 AI 给不出的判断——业务逻辑是不是真的对、架构方向是不是合理。这样的分工,比让 AI 替你做全部判断,或者完全不信 AI,都要靠谱得多。
2. 把 Claude Code 装对:VS Code 集成与首次运行配置
工欲善其事,必先利其器。open-code-review的整个执行引擎依赖 Claude Code,而这个工具又和 VS Code 的集成深度相关,所以第一步不是急着写审查规则,而是把运行环境弄扎实。这一节我会把安装、账号、首次配置这几个环节里容易踩的坑一次说清楚。
2.1 安装前要确认的三件事
在开始安装之前,有件事必须事先确认好,否则装到一半会卡住:Claude Code 这类服务对可用区域有官方限制。如果你在执行命令或打开界面时遇到类似unsupported_country_region_territory的报错,这说明当前网络出口 IP 或账号的区域设置不在官方支持范围内。这是服务商的合规限制,不是配置错误,我的建议是不要尝试任何“非常规手段”去绕过,而是确认自己的网络环境与账号区域设置是否满足官方支持条件,按正规渠道解决问题。我曾经在这个问题上绕了很久,最后发现就是区域设置不对,调整完之后一直很稳定。
确认可用区域之后,再看以下三件事:
- Node.js 版本:Claude Code 作为命令行工具运行在 Node.js 上,建议使用 LTS 版本,太老的版本可能跑不起来。
- VS Code 版本:建议保持在一个较新的稳定版本,老版本对终端集成和扩展 API 的支持会有差异。
- 终端类型:Windows 上建议用 PowerShell 7+ 或 Windows Terminal,避免用老的 cmd.exe,因为部分交互式 UI 的渲染在 cmd 下会崩溃。
这三件事都是“看起来不起眼,但没弄对会让你怀疑人生”的细节。
2.2 VS Code 里拉起 Claude Code 的两种姿势
安装好命令行工具之后,在 VS Code 中使用有几种不同的方式。我先说最简单的那种:
第一种是直接在 VS Code 的内置终端里运行 Claude Code 的启动命令。这样做的好处是,工具能自动感知当前工作目录,而且你可以在同一个终端里同时操作 Git、跑测试、看 AI 的审查意见,切换成本很低。大多数情况下,这是我最常用的方式。
第二种方式是利用 VS Code 的集成终端分屏,左侧是编辑器,右侧是 Claude Code 的交互界面。这个方式适合做代码审查时使用,因为你能一边看代码一边把审查指令丢给 AI,AI 的输出会直接出现在右侧终端里,不用来回切换窗口。
不管是哪种方式,Claude Code 在首次启动时会要求你完成登录认证。这一步走完之后,它会问你是不是要创建一个CLAUDE.md的项目记忆文件。我的建议是选“是”,后面我们会用这个文件来存放一些全局约定。这个文件的作用非常像给 AI 的一块“便利贴”,它会一直挂在上下文里,提醒 AI 你的项目是什么、有哪些约定,后面讲规则文件的时候我会再展开。
2.3 账号层面的坑:区域不可用与权限收窄
第一次登录时,你可能会碰到网络连接异常或权限提示。这个阶段有两个值得说的经验:
第一,登录成功不代表所有网络请求都畅通。Claude Code 运行时既需要访问模型服务,也可能访问一些资源站获取更新,如果你的网络环境对这些域名有限制,表现就是时好时坏。遇到这种情况,先确认网络出口是否稳定,再确认账号所在区域的官方支持列表。我见过很多朋友卡在这一步,其实是代理规则太粗放导致的,正常情况下不需要任何特殊配置就能稳定运行。
第二,权限收窄是个好习惯。Claude Code 被授予的能力越多,它能做的操作就越多,但也意味着误操作的风险越高。在初始化之后,我强烈建议限制终端命令的执行权限,改为“每一步需要你确认”。虽然这样会稍微麻烦一点,但审查任务本身不是高频操作,安全性和可控性远比流畅性重要。尤其是后面我们要接 Git 钩子和 CI,权限控制不好会出大问题。
2.4 第一份 CLAUDE.md 项目记忆文件
一旦CLAUDE.md创建成功,你就有了一个和 AI 进行“项目级对话”的持久记忆文件。这个文件的内容不需要太长,但至少应该包括:项目是什么、技术栈是什么、代码目录结构大概是什么样、希望 AI 在审查时特别关注什么。
我自己的第一版CLAUDE.md长这样:
# 项目记忆 ## 项目定位 一个面向中小团队的开源代码审查辅助方案,通过 Claude Code 自动生成审查意见。 ## 技术栈 Node.js + TypeScript,使用 Git 做版本管理,常用包管理器为 npm。 ## 目录说明 - src/:核心源代码 - scripts/:审查触发脚本 - .github/workflows/:CI 流程定义 ## 审查约定 - 关注安全性、可维护性,其次才是风格问题 - 输出必须具体,给出文件、行号和建议改法这份文件在每次对话时都会被 Claude Code 自动读取。换句话说,你在后面写的审查规则都不需要重复交代项目背景,AI 会自动结合这个记忆文件来理解你的指令。这一步做扎实了,后面所有审查指令的效果都会更好。
3. 设计 CODE_REVIEW.md:让 AI 按你的标准说话
环境装好之后,最核心的部分来了:怎么让 AI 审查得“像你自己”。我见过太多人用 AI 做 review,结果是直接把 diff 丢给它,说一句“帮我看看”,拿回来的意见要么太空泛——比如“代码质量可以进一步优化”,要么就是只盯着换行和命名不放,反而是真正的业务风险被忽略了。
问题不在 AI,在于你没有给它一份足够清晰的审查标准。于是我在实践open-code-review的过程中迭代出了一份CODE_REVIEW.md,把它作为 AI 审查时必须遵循的操作手册。这一节就把这份规则的设计思路和完整内容拆开讲。
3.1 为什么不能直接让 AI “随便看看”
直接丢 diff 让 AI 看的最大问题是:它的注意力是平均分配的。没有明确的优先级时,AI 会倾向输出那些“看起来像问题”的问题,哪怕这些问题对业务毫无影响。比如,一个后端接口里变量命名不够统一,和一个未处理的空指针异常,在 AI 眼里可能都被识别成“需要修改”,但在人的优先级里,后者才是致命的。
CODE_REVIEW.md的作用就是给 AI 一个轻重缓急的排序器。你要告诉它:什么问题是阻断合并的,什么问题是建议修改的,什么问题只是可选优化。没有这个排序,AI 给你列了一个 20 条的修改清单,你反而不知道怎么处理了。
还有一个常见误区是:规则写得太抽象。比如“请审查代码的健壮性”,AI 确实能理解这句话,但它无法确定你想要的“健壮性”具体包括哪些场景。所以规则要尽量具体,用“如果……那么……”的句式来写,这样才能把 AI 的能力收敛到你想让它关注的地方。
3.2 一份能直接抄的审查规则大纲
下面这份规则是我目前在生产环境里用的版本,你可以直接复制到仓库根目录的CODE_REVIEW.md文件里,再按自己团队的情况增删。
# 代码审查规则 # 目标 本文件定义化学代码审查的检查标准。每次审查前,必须严格依据本规则执行。 ## 一、阻断级别问题(必须修复,否则禁止合并) 1. 安全性:任何 SQL 拼接、shell 命令拼接、不安全的反序列化、硬编码密钥。 2. 正确性:空指针解引用、数组越界、并发修改异常、明显的逻辑短路。 3. 数据完整性:直接在生产流量路径上修改核心数据结构,且没有迁移方案。 4. 依赖风险:引入高风险许可协议或已知存在严重漏洞的依赖版本。 ## 二、建议级别问题(应当修复,非阻断) 1. 代码风格:命名不一致、函数过长、明显可以提取的重复代码。 2. 性能隐患:明显的重复查询、不必要的大对象拷贝、未使用索引的查询。 3. 可维护性:缺少必要的注释、魔法数字、过深的嵌套、无法测试的代码。 4. 错误处理:吞掉异常、错误的日志级别、缺少用户可理解的错误信息。 ## 三、可选优化(不强制) 1. 表达式简化 2. 更优雅的语法糖用法 3. 性能微优化 ## 四、审查输出格式 必须使用如下格式输出: ### 审查结论 [PASS] 或 [NEED_CHANGE] ### 阻断问题 - 文件路径:行号 | 问题描述 | 建议改法 ### 建议问题 - 文件路径:行号 | 问题描述 | 建议改法 ### 可选优化 - 文件路径:行号 | 问题描述 | 建议改法 ### 一句话总结 [不超过 50 字]这份规则的第一版可能只有前两节,后面是在实际使用中逐步完善的。你会发现它跟网上常见的“AI 审查 Prompt”有很大区别:它给了 AI 明确的输出规范。很多时候 AI 审查结果难用,不是因为 AI 看得不认真,而是因为它给的结论太散,没有统一格式。一个固定格式的审查结论,可以让你直接把它粘贴进 PR 评论区、打进 CI 日志,或者喂给后续处理的脚本。
3.3 输出格式的重要性:结构化才能被消费
为什么我特别强调输出格式?因为 review 的产出是要被“消费”的。在自动化链路里,你的下游可能是 CI 脚本,可能是通知机器人,也可能是团队 Wiki。如果输出是两段风格随意的散文,那这些脚本都没法稳定地解析它。
比如我的 CI 流程就用了这样一个简单逻辑:从 Claude Code 的审查输出里判断是否包含[NEED_CHANGE]标记,一旦检测到就把这条流水线标记为失败。如果 AI 审查输出的是一大段自然语言,这个判断逻辑就非常脆弱,因为文本表达千变万化。但有了固定的标记位,问题就简单得多。
所以,规则文件里的“输出格式”部分建议单独成节,像写接口文档一样对待它。你要在规则里明确告诉 AI:哪些字段必须有、用什么符号标识、放在第几行。投入这十几分钟的设计,后面自动化能省下无数时间。
4. 三种触发方式:从手动到自动的完整链路
规则文件写好了,接下来是触发链路。open-code-review这个方案里,我设计了三种触发方式,对应不同的使用场景:日常开发中的手动触发、提交前的自动增量审查、合并前的 CI 全量审查。三种方式层层递进,组成了一个从“我自己想审”到“必须审完才能合”的完整闭环。
4.1 手动触发:/review 斜杠命令
最简单的触发方式是手动。你只需要在 Claude Code 的交互终端里输入一句指令,它就会按CODE_REVIEW.md的规则对指定范围执行审查。
我的典型用法是这样的:
> 对照 CODE_REVIEW.md,审查当前 Git 暂存区中的改动这一句指令的含义很明确:只审查git diff --cached里出现的文件,不牵扯无关内容。这样做的好处是范围小、反馈快,十几秒就能得到结果,适合开发中途自查。
另一个我经常用的变体是指定某个文件或某个目录:
> 对照 CODE_REVIEW.md,重点审查 src/core/validate.ts 这个文件的改动这种手动方式很适合那种“刚写完一块代码,心里有点不踏实”的时刻。它不打扰你的工作流,而且你可以在把改动给别人看之前,先让 AI 过一遍,把明显的问题消掉。很多 review 冲突,其实在这种自我预审阶段就能解决掉一半。
4.2 提交前触发:Git pre-commit 的增量审查
手动触发很好,但问题是,人总是会忘。所以我把第二道防线放到了 Git 钩子里:在每次git commit之前,自动对暂存区的改动做一次增量审查。只要审查输出里出现[NEED_CHANGE],就中断提交,提醒你先处理问题。
这个钩子的脚本写起来其实不难,在.git/hooks/pre-commit里加上一段逻辑即可。以下是我实际用的脚本骨架:
#!/bin/bash # 增量审查:暂存区改动 STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(ts|js|tsx|jsx)$' | head -20) if [ -z "$STAGED_FILES" ]; then exit 0 fi echo "Running AI code review on staged files..." REVIEW_OUTPUT=$(claude -p "对照 CODE_REVIEW.md,审查以下文件的暂存区改动:$STAGED_FILES" 2>/dev/null) if echo "$REVIEW_OUTPUT" | grep -q "\[NEED_CHANGE\]"; then echo "AI review found blocking issues. Please fix them before committing." echo "$REVIEW_OUTPUT" exit 1 fi exit 0说几个我在实际使用过程中调过的细节。第一,head -20限制一下文件数量,避免一次提交几百个文件时审查超时。第二,-p参数是让 Claude Code 以非交互模式运行,适合脚本调用。第三,我刻意把审查结果打印出来,这样你被中断提交时,能立刻看到具体问题,而不用重新跑一次审查。
有人可能会问:这个钩子会不会拖慢提交速度?以我目前的体验,普通规模的改动(几个文件)大概需要 10 到 30 秒。对于追求“秒提交”的开发者来说,这个时间确实有点影响。所以我的建议是,提交前的钩子只做增量审查,把审查范围控制到最小值,把完整的检查留给 CI 阶段。
4.3 合并前触发:CI 里跑一次完整审查
如果说前两种触发方式是为了“帮开发者自己发现问题”,那 CI 里的审查就是为了“兜底”。
我的做法是:在 GitHub Actions 工作流里加一个 job,专门在创建 Pull Request 时执行一次全量审查。每次 PR 的 diff 会被完整交给 Claude Code,按CODE_REVIEW.md规则审查,并把结果作为 PR 评论发出来。
一个简化版的工作流定义:
name: AI Code Review on: pull_request: types: [opened, synchronize] jobs: ai-review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: 20 - name: Run AI Review env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | DIFF=$(git diff origin/main...HEAD -- '*.ts' '*.tsx' | head -c 20000) claude -p "对照 CODE_REVIEW.md,审查以下 diff:$DIFF"这个流程我跑了几个月,有一个心得:CI 里的 AI 审查不是用来卡人的,而是用来给 reviewer 提供一份“机器视角的预检报告”。团队成员在打开 PR 之前,先看到 AI 的结论,心里就有个底:哦,这个改动里有几个风格问题已经被指出了,我直接看那几处就行了。这比 reviewer 自己从头看一遍 diff 要高效得多。
5. 实测中踩过的坑:误报、上下文、安全性
把open-code-review这套流程真正用起来之后,我遇到的问题并不比解决的问题少。这一节是我最想写的部分,因为网上能找到的教程很少会把失败经历写出来。我会按从“小问题”到“大问题”的顺序,把这些坑一个个摊开来讲。
5.1 AI 的“假警报”和规则收敛办法
第一个坑是误报。AI 审查刚开始时,它的输出里会掺杂不少“看起来对但实际不对”的意见。比如,它经常会对一段可读性还不错的代码建议“提取公共函数”,或者对某种设计模式表示“这不够优雅”。这类意见不是说完全没道理,而是它不符合团队当下的技术债现实——有时候我们故意写一段“丑代码”只是为了兼容旧系统,结果 AI 每次都提醒你改,这就成了噪音。
我的解法是:在规则文件里增加一个“不允许提的建议类型”清单。比如明确写上“不应建议大规模重构,除非与当前改动直接相关;不应建议修改与本次改动无关的既有代码”。这一步操作不要省。你以为 AI 读了规则就懂了,但实际上每次都有偏差,必须在规则里“圈禁”它的行为边界。收敛之后,误报率下降得肉眼可见。
还有一个很实用的收敛方法:在审查指令里增加一句话——“只针对本次改动本身提出意见,不得延伸到未修改的上下文”。这句话对控制 AI 的审查范围非常有效,它能把 AI 的注意力牢牢锁在 diff 上,而不是顺着代码逻辑去点评整个模块的历史问题。
5.2 上下文窗口与 diff 截断的折中方案
第二个坑是上下文长度。对于一个代码仓库来说,完整的 diff 可能非常长。我见过一次大功能分支的 diff 有 3 万行,如果直接丢给 AI,它根本无法在上下文窗口内完整处理,要么报错,要么只审查了开头一部分。
为了解决这个问题,我一开始的做法是简单粗暴地截断:取前 2 万字符。但效果非常差,因为被截掉的往往是 diff 的后半部分,而很多时候严重的问题恰恰藏在后面。后来我换了一个思路:按风险等级做分层审查。
- 第一层:只审查所有被修改文件的函数签名和关键调用关系,这部分能快速发现接口不匹配的问题。
- 第二层:对改动最大的几个文件做全量审查。
- 第三层:如果还有剩余上下文,随机抽样审查其他文件。
这样做的代价是速度变慢了,但覆盖率反而上来了。另一个可行的方案是让 AI 用工具自主读取文件,而不是把 diff 一次性喂给它。Claude Code 具备读取本地文件的能力,你可以让它先自己看 diff 统计信息,再按需去读具体文件内容。这个做法比“一股脑塞给它”更聪明,也更接近一个真实 reviewer 的工作方式——先看概览,再挑重点深入。
5.3 不要把你不理解的代码直接贴进终端
第三个坑,也是我特别想提醒各位的,是一个安全习惯问题。网上、AI 对话里偶尔会出现类似warning: don't paste code into the devtools console that you don't understand的警告。这句话的本意是:如果你看不懂一段代码的作用,就不要盲目地把它粘贴到浏览器控制台或终端里执行。因为它可能是恶意代码,可能窃取你的账号凭证,也可能在你机器上执行任意操作。
这个警告不仅适用于浏览器控制台,也同样适用于 AI 辅助开发流程。Claude Code 会基于你的指令自动执行一些命令,而它执行的所有命令,本质上都是代码。我在实际使用中有一条铁律:AI 给出的命令,先看清要干什么再回车。尤其是当它建议执行rm、curl、npm install、修改系统配置这类操作时,哪怕步骤繁琐,我也一定要人工确认命令内容和目标路径。审查流程本身就是为了降低风险,如果因为盲目信任 AI 而引入新的安全隐患,那就本末倒置了。
另外一个相关经验是:不要把生产环境的真实数据或密钥放进审查上下文。你让 AI 审查一个涉及 API key 的配置模块,它在输出里有可能直接复述这些敏感内容,而这些内容会进入日志或评论系统,留下不必要的暴露面。我的做法是:在审查前先对敏感内容做脱敏处理,或者只在输出里保留变量名而不保留值。
5.4 人机边界:哪些 case 必须由人拍板
最后,我想认真聊聊 AI 审查的边界。我用了很长时间才意识到:AI 审查的产出不应该被当作“最终结论”,而应该被当作“预检报告”。它擅长发现的,是那些有明确规则可依的问题——空指针、SQL 注入、风格不一致、明显的重复代码。这些问题的特点是“客观存在”,只要代码写得不对,谁来看都是问题。
但有很多真正重要的判断,AI 目前给不了。比如:这次改动是否符合业务的长远方向?引入这个新依赖是否值得团队后续花成本去维护?这个接口设计是否考虑了下一位使用者的真实场景?这些问题没有标准答案,依赖的是人对业务语境的理解和判断,这部分只能由团队里懂业务的人来拍板。
所以我设计这套流程时,刻意让 AI 停留在“提建议”的层面,而不是“做决策”的层面。NEED_CHANGE标记只是告诉提交者“这里需要优先关注”,不代表“这里一定要按 AI 说的改”。最终的驳回权、合并权,始终掌握在人的手里。这个边界设置好,AI 审查和人工 review 不仅不冲突,反而会形成一种很顺滑的协作关系。
从我几个月的实操体验来看,这套基于open-code-review思路搭起来的 AI 审查流程,最明显的收益不是“抓出了多少 bug”,而是让我在合并代码时,心里踏实了。以前提交一个改动,总担心哪里漏看了,现在反正有 AI 先扫一遍,我自己再做一轮针对性的业务逻辑检查,double check 下来,反而比从前单纯靠人审更从容。如果你也想在自己的项目里跑通这套流程,我的建议很简单:先从手动触发开始用,等规则文件调顺了,再加 Git 钩子和 CI。步子别迈太快,AI 审查这东西,磨刀不误砍柴工。