AI 代码评审深入:把审查变成可落地的工作流
一、回顾:AI 代码评审的价值
站内基础篇「ai-code-review」已经说明,AI 代码评审的核心价值在于把资深工程师的注意力,从重复、机械的挑错中解放出来。这里不再复述概念,只补三点容易被人忽略的事实:
- AI 评审最擅长的是「覆盖广度」。一个人一次最多盯住十几个文件,AI 可以在几秒到几分钟内把整个改动差异(diff)扫一遍,且不会因为疲劳漏看。
- AI 评审最不擅长的是「意图判断」。它不知道这次改动的业务目标,也不清楚历史债务为何存在,所以它给出的结论需要人来加权。
- 因此,本篇的立场是:AI 评审不是替代人工评审,而是把人工评审从「找低级错误」升级到「做架构与意图判断」。下面所有设计都围绕这个分工展开。
二、评审维度清单
要把 AI 评审变成可落地的流程,第一步是给它一张「查什么」的清单。建议固定为六个维度,并让提示词或配置每次都按这个顺序逐项检查。
1. 正确性(Correctness)
- 边界条件:空集合、空字符串、负数、零、极大值。
- 并发与竞态:共享状态是否有锁或多线程保护。
- 控制流:是否可能走到未初始化分支、死循环、资源未释放。
- 数值与类型:整数溢出、浮点比较、类型强制转换。
2. 安全(Security)
- 注入类:SQL 注入、命令注入、LDAP/NoSQL 注入、模板注入。
- 越权类:缺少鉴权、缺少鉴权后的资源归属校验(IDOR)。
- 密钥与凭证:硬编码 token、密钥、私钥、口令出现在改动中。
- 依赖与供应链:引入的库版本是否存在已知漏洞(需结合 SCA 工具)。
3. 性能(Performance)
- 循环内查询数据库或发起网络请求。
- N+1 查询、全表扫描、缺少索引。
- 不必要的大对象拷贝、同步阻塞调用。
- 缓存缺失或缓存穿透、缓存键设计不合理。
4. 可维护性(Maintainability)
- 重复代码、过长的函数与过深的嵌套。
- 命名是否传达意图、是否有误导性注释。
- 魔法数字、全局可变状态、隐式依赖。
- 改动是否破坏了既有模块边界。
5. 测试覆盖(Test Coverage)
- 新增分支是否配套单元测试。
- 关键路径是否有集成测试或端到端测试。
- 测试是否覆盖失败路径与异常路径。
- 测试是否可能因为断言过松而「假绿」。
6. 规范(Conventions)
- 与团队代码风格、提交规范是否一致。
- 接口契约、错误处理风格是否统一。
- 日志、监控、链路追踪是否按约定埋点。
三、实战工作流
一个可落地的 AI 评审工作流,应当回答三个问题:什么时候触发、评论如何分级、哪些情况必须人工介入。
3.1 触发:在 Pull Request 上自动跑
最自然的触发点是 Pull Request 的开启与更新。下面是一段 GitHub Actions 配置示例,它在 PR 更新时拉取 diff,调用你自己的评审服务(或 LLM 网关),再把结果以评论形式回写。
name: ai-code-review
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
pull-requests: write
contents: read
jobs:
review:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 获取差异
id: diff
run: |
git fetch origin ${{ github.event.pull_request.base.ref }}
DIFF=$(git diff origin/${{ github.event.pull_request.base.ref }}...HEAD)
echo "diff<<EOF" >> "$GITHUB_OUTPUT"
echo "$DIFF" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: 调用 AI 评审
env:
REVIEW_TOKEN: ${{ secrets.REVIEW_TOKEN }}
PR_DIFF: ${{ steps.diff.outputs.diff }}
run: |
# 将 PR_DIFF 与提示词一起提交给评审网关,
# 评审网关调用 LLM 并把结构化结果回写到本工作流。
curl -s -X POST https://review-gateway.internal/v1/review \
-H "Authorization: Bearer $REVIEW_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"diff\": $(jq -Rn --arg d "$PR_DIFF" '$d | tojson')}"
- name: 回写评论
uses: actions/github-script@v7
with:
script: |
// 读取评审网关产出的评论文件,逐条写入 PR 评论
const fs = require('fs');
const comments = JSON.parse(fs.readFileSync('review-result.json', 'utf8'));
for (const c of comments) {
await github.rest.pulls.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
body: c.body,
commit_id: context.payload.pull_request.head.sha,
path: c.path,
position: c.position
});
}
3.2 分级:让评论带严重度
AI 不应该把「拼写笔误」和「SQL 注入」放在同一优先级。建议统一四级严重度,并在每条评论里标注:
- 严重(Blocker):安全漏洞、数据丢失风险,必须修。
- 高(High):正确性或并发缺陷,强烈建议修。
- 中(Medium):可维护性、性能隐患,建议修。
- 低(Low):风格、规范,可酌情处理。
下面是一段提示词示例,要求模型按维度与严重度产出结构化结果,而不是自由发挥。
你是一名资深代码评审工程师。请对以下 Pull Request 差异进行评审。
要求:
1. 逐项检查以下维度:正确性、安全、性能、可维护性、测试覆盖、规范。
2. 每条问题必须包含:文件路径、近似行号(基于 diff 行号)、严重度(严重/高/中/低)、问题说明、修改建议。
3. 严重度定义:
- 严重:安全漏洞、数据丢失风险。
- 高:正确性或并发缺陷。
- 中:可维护性、性能隐患。
- 低:风格、规范。
4. 不要编造行号;若无法确定行号,请基于 diff 片段定位。
5. 不要给出与改动无关的建议。
6. 输出严格为 JSON 数组,不要输出额外解释文字。
待评审差异:
{{DIFF}}
3.3 人工复核门槛:哪些情况不允许 AI 直接放行
AI 评审的结论不计入合并门槛是行业常见做法。参考 GitHub Copilot 代码审查的官方行为,它的评审始终以「Comment」形式留下,而不是「Approve」或「Request changes」,因此不会算作合并所需的审批、也不会阻止合并(已核验)。基于此,建议设置以下人工复核门槛:
- 任何「严重」或「高」评论未解决前,必须由一名人类评审者手动批准。
- 涉及鉴权、支付、数据迁移、权限模型的改动,强制二级人工复核。
- 自动评审失败(服务超时、输出无法解析)时,降级为纯人工评审,不得静默放行。
- AI 评审仅作为参考意见,最终合并决策权在人工。
四、工具箱
不同团队规模与平台,适合的工具不同。下面给出四类,部分细节标注为待核实。
4.1 各平台 Copilot 类审查
- GitHub Copilot 代码审查:在 PR 的 Reviewers 里请求 Copilot 即可,通常不到 30 秒返回;支持 Lite(默认值,偏向常见 bug、安全漏洞、风格)与 Balanced(更深入的复杂逻辑与跨服务分析,使用更高推理能力的模型)两档审查力度(已核验)。可通过
.github/copilot-instructions.md、AGENTS.md、.github/instructions/**/*.instructions.md做仓库级与路径级的自定义审查指引(已核验)。 - GitLab Duo 等同类能力的具体覆盖范围与定价,本文列出但待核实。
4.2 CodeRabbit
官方定位为 AI 代码审查产品,强调对每个 Pull Request / Merge Request 自动审查,并提供优先级排序、风险分级与「理解你的队列」等能力,包括一个把 PR 当看板(Kanban)来管理的视图(已核验)。它宣称在 AI 代码审查领域有业界领先的上下文能力,并支持持续学习(已核验)。关于其具体支持的严重度标签、与 Sonar/Q linter 的集成深度、价格档位,本文待核实。
4.3 SonarQube + AI
SonarQube 长期以静态分析、代码异味、安全热点著称。近年 Sonar 引入了 AI 辅助能力,例如自动生成修复建议与更自然的评审解释(具体功能名称与可用性待核实)。建议把 Sonar 的规则引擎作为「硬规则」层,把 LLM 作为「解释与建议」层,二者互补:Sonar 负责稳定、可复现的告警,AI 负责把告警翻译成人话并给上下文。
4.4 自定义 LLM 评审 bot
当团队有私有代码、强合规要求,或想嵌入自有规范时,自建 bot 最灵活。核心组件:
- 取 diff 的程序(如上文 GitHub Actions)。
- 提示词模板(如上文结构)。
- 一个把结构化结果写回 PR 的服务。
- 一个「误报反馈」通道,让工程师标记假阳性,用于迭代提示词。
下面是一个最小可运行的 Python 评审回写片段示例:
import json
import os
import requests
def post_review_comments(repo: str, pr_number: str, comments: list[dict]) -> None:
"""把结构化评审结果逐条写回 GitHub Pull Request。"""
token = os.environ["GITHUB_TOKEN"]
base = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments"
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/vnd.github+json",
}
for c in comments:
payload = {
"body": f"[{c['severity']}] {c['message']}\n建议:{c['suggestion']}",
"commit_id": os.environ["PR_HEAD_SHA"],
"path": c["path"],
"position": c["position"],
}
resp = requests.post(base, json=payload, headers=headers, timeout=30)
resp.raise_for_status()
if __name__ == "__main__":
with open("review-result.json", encoding="utf-8") as fh:
data = json.load(fh)
post_review_comments(
repo=os.environ["GITHUB_REPO"],
pr_number=os.environ["PR_NUMBER"],
comments=data,
)
五、陷阱
把 AI 评审接进流程后,这些坑最常见,也最容易被忽视。
5.1 假阳性:AI 说错了
AI 可能把正确的代码判成有 bug,尤其在它不了解项目约定时。典型场景:
- 把「故意的兼容写法」当成冗余。
- 把「框架要求的样板代码」当成可删除重复。
- 在没有完整上下文时,误判变量未使用或未初始化。
应对:每条 AI 评论都可一键标记误报,并沉淀进提示词与 AGENTS.md,减少重复误报。
5.2 假阴性:AI 没看见
比假阳性更危险的,是它沉默地放行了真问题。原因通常是:
- 上下文不足,只看单文件而漏掉跨文件影响。
- 改动依赖了它没读到的配置或生成代码。
- 提示词没覆盖到的维度被直接跳过。
应对:把安全、权限、数据迁移类改动设为强制人工复核;对关键路径保留 Sonar 之类的硬规则兜底。
5.3 盲目采纳:把 AI 当权威
- 不要因为 AI 没评论就认为代码没问题。它没看到的,不等于不存在。
- 不要让 AI 评论直接自动合并。合并决策必须人工拍板。
- 警惕「AI 已经审过了」带来的责任稀释:最终对线上事故负责的,仍然是人和团队。
5.4 上下文不足漏看跨文件问题
单 PR diff 往往不够。一个接口签名改动,影响的是所有调用方;一个共享类型改名,可能让其他服务编译失败。建议:
- 让评审 bot 在必要时拉取被改动符号的定义与调用方(通过代码检索或索引)。
- 对「破坏性改动」加标签,触发更大范围的扫描。
- 跨仓库、跨服务的改动,提升人工复核等级而不是依赖 AI。
小结
AI 代码评审的价值不在「替代人」,而在「把人从低级错误中解放出来」。落地时请记住四件事:第一,用固定的六维清单约束 AI 查什么;第二,让评论带严重度,使严重与高级别问题不被淹没;第三,设置人工复核门槛,AI 结论只作参考、不计入合并审批;第四,正视假阳性、假阴性与盲目采纳三类陷阱,用反馈闭环和硬规则兜底。把这几条串起来,AI 评审才会从玩具变成真正可依赖的工作流。
参考与延伸阅读
- GitHub Docs:Using GitHub Copilot code review(审查行为、力度档位、自定义指令)已核验。
- CodeRabbit 官网:AI 代码审查的产品定位与自动审查、风险分级、PR 看板能力已核验。
- GitHub Copilot 代码审查不计入所需审批、不阻止合并的官方说明已核验。
- SonarQube 的 AI 辅助修复与解释功能的具体名称与可用性待核实。
- GitLab Duo 代码审查等同类平台能力、CodeRabbit 的严重度标签与价格档位待核实。