
AI 代码审查自动化:如何让 AI 代理帮你把关代码质量
从搭建审查流程到配置自动化检查规则和编写审查提示语,手把手教会你用 AI 代理建立一套持续运行的代码审查系统
原创。代码审查是保证质量的关键环节,但人手不够的时候怎么办?用 AI 代理搭一套自动化审查系统——从配置到落地,一遍搞定。
代码审查这件事,说重要吧,确实重要——能发现逻辑错误、风格问题、安全隐患。说麻烦吧,也真麻烦——尤其是独立开发者或者小团队,写代码都忙不过来,哪有精力每条 PR 都细细看一遍。
AI 编程工具已经在帮我们写代码了,能不能让它们也帮我们看代码?
答案是肯定的。现在有不少方案可以把 AI 代理接入代码审查流程,自动检查每次提交的代码质量,甚至在你点开 PR 之前就把问题列表列好了。这篇文章不讲大道理,直接说怎么搭一套能用的自动化代码审查系统。
核心思路:三层审查架构
一套完整的 AI 代码审查系统,我建议分为三层。三层各自负责不同粒度的问题,互相不重叠,也不遗漏。
第一层:静态规则审查
这一层的审查不依赖大模型,跑的是传统的 lint 规则。它应该捕获的问题包括:
- 语法错误和类型错误
- 不符合项目风格指南的代码格式
- 已经弃用的 API 调用
- 明显的安全问题(SQL 注入、XSS 风险)
这些用 ESLint、Pylint、Rubocop 之类的工具就行,直接集成到 CI 流程中。AI 模型对于这类问题反而不如传统工具准确——lint 规则是确定的,AI 可能还会漏掉。
配置要点:在 CI 中配置两种模式——严格的提交前检查(pre-commit hook)和宽松的 PR 检查(允许部分警告通过)。前者确保开发者在本地就能发现问题,后者在 PR 层面做兜底。
第二层:AI 逻辑审查
这一层是 AI 代理的主力战场。它在 lint 通过之后运行,审查代码的逻辑正确性和可维护性。AI 模型适合审查的问题:
- 函数逻辑是否正确处理了边缘情况
- 新增的代码是否破坏了现有架构
- API 调用方式和参数是否符合约定
- 新代码与现有代码库的风格一致性
这层审查不需要大模型也能做吗?恰恰相反。逻辑审查需要理解代码的业务意图,传统的静态分析工具做不到。而 AI 模型的上下文理解能力正好补上这个缺口。
配置方式:用 GitHub Actions 或者 GitLab CI,在 PR 创建或更新时触发一个 AI 审查代理。代理读取 PR 的 diff,对每个文件的变更生成审查意见。
第三层:人类确认
AI 审查的结果不是最终判决。最后一层始终应该是人的判断。
AI 审查输出的格式应该让人能快速浏览——最好的形式是在 PR 上以评论的方式列出问题清单,每个问题标明严重程度和文件位置。审查者扫一眼就能决定这个 PR 要不要合并,而不是要在 AI 的长篇大论里翻找关键信息。
—— 广告 ——
实战:用 GitHub Actions + AI API 搭建审查系统
下面是一个可以直接用的方案。不需要额外的平台,用已有的 GitHub 仓库和 AI API Key 就可以启动。
Step 1:创建审查工作流
在仓库的 .github/workflows/code-review.yml 文件中,创建一个当 PR 创建或更新时触发的工作流:
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: AI Code Review
run: |
# 获取 PR 的 diff
curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}" \
| jq -r '.body' > pr_description.txt
# 获取文件变更
curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" \
| jq -r '.[] | .filename + "\n" + .patch' > diff_output.txt这个工作流在 PR 创建或推送新 commit 时触发,获取变更的文件列表和 diff 内容,然后传给后续的审查步骤。注意要先配好 GitHub Token,否则无法访问 PR 信息。
Step 2:编写审查提示语
审查提示语是整个系统的关键。写得太宽泛 AI 就给一堆空洞的建议,写得太具体又可能漏掉重要问题。
一个经过实践验证的有效提示语结构:
你现在是一个资深代码审查员。请审查以下 diff,按照重要性列出发现的问题。
## 审查维度(按优先级排列)
1. **正确性**:是否存在逻辑错误、边界条件未处理、空指针/类型错误?
2. **安全性**:是否存在注入风险、密钥泄露、权限校验缺失?
3. **可维护性**:代码是否清晰、命名是否合理、是否引入了不必要的复杂度?
4. **性能**:是否有明显的性能问题(不必要的循环、重复计算等)?
## 输出格式
每个问题按以下格式输出:
- [严重程度: HIGH/MEDIUM/LOW] 文件路径:行号 — 问题描述
## 注意事项
- 只报告确凿的问题,不要猜测
- 忽略格式问题(代码风格已由 lint 检查覆盖)
- 如果这个 PR 没有问题,输出「✅ 未发现问题」
## 变更内容
{diff_content}
这个提示语的关键在于:
- 明确审查维度。让 AI 知道该看什么,不该看什么。格式问题已经被 lint 覆盖了,AI 不要再管。
- 严格输出格式。每个问题要有严重程度、文件位置和描述。这样才能被后续脚本解析并在 PR 上格式化显示。
- 设定期望。"只报告确凿的问题"这句话很重要——AI 容易过度审查,在没有问题的时候也编一些问题出来。
Step 3:集成 LLM API
将上面的提示语和 diff 内容发送给 LLM API。这里以 OpenAI 为例,其他模型同理:
# 将 diff 和提示语拼接为请求
MESSAGE=$(cat prompt_template.txt diff_output.txt | jq -Rs .)
curl -s -X POST "https://api.openai.com/v1/chat/completions" \
-H "Authorization: Bearer ${{ secrets.OPENAI_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "system", "content": "你是一个严格但公正的代码审查员。"},
{"role": "user", "content": '"$MESSAGE"'}
],
"temperature": 0.3
}' > review_result.jsontemperature 设置为 0.3,让输出更加确定和一致。审查任务不需要创意,需要的是准确。
Step 4:将审查结果发回 PR
最后一步,把 AI 的审查意见以 PR 评论的形式发布:
# 提取审查结果中的问题
ISSUES=$(cat review_result.json | jq -r '.choices[0].message.content')
# 发布为 PR 评论
COMMENT_BODY="## 🤖 AI 代码审查结果
$ISSUES"
JSON=$(jq -n --arg body "$COMMENT_BODY" '{"body": $body}')
curl -s -X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/json" \
-d "$JSON" \
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments"这样,每次有人创建 PR,AI 审查代理就会自动运行,在 PR 页面留下审查意见。你打开 PR 的时候,所有问题已经列在上面了。
进阶优化
增量审查
对于大型 PR,第一次审查时审查全部 diff 是可以的。但如果后续只是推送了小改动,每次都重新审查整个 diff 就很浪费 Token 和 API 费用。
解法是缓存上一次的审查结果,只审查新增的 diff 部分。在 GitHub Actions 中可以用缓存 action 来实现:
- name: Cache previous review
uses: actions/cache@v3
with:
path: .review-cache
key: review-${{ github.event.pull_request.head.sha }}按文件类型定制审查规则
不同类型的文件,审查重点不同:
- JavaScript/TypeScript:关注类型安全、异步处理、ES 模块兼容性
- Python:关注类型注解、异常处理、导入规范
- Go:关注错误处理模式、并发安全、接口设计
- 配置文件(YAML/JSON):关注格式正确性、密钥泄漏
在提示语中指定文件类型清单,让 AI 按不同标准审查不同文件:
JavaScript/TypeScript 文件:
- 检查 async/await 是否正确使用
- 检查是否有未使用的导入
Python 文件:
- 检查是否有缺少类型注解的函数
- 检查异常捕获是否过于宽泛
自定义忽略规则
有些文件不需要 AI 审查——比如自动生成的代码、第三方依赖的 vendor 目录、测试数据和 fixture。通过 .gitreviewignore 文件配置忽略清单:
vendor/
*.generated.*
test/fixtures/
package-lock.json
在审查脚本中先检查文件路径是否匹配忽略规则,匹配的直接跳过。
完整示例:一个 Python 项目的审查配置
下面以一个 Python Web 项目为例,展示完整的审查工作流。
假设你有一个 Flask 项目,目录结构如下:
my-flask-app/
├── app/
│ ├── __init__.py
│ ├── routes.py
│ ├── models.py
│ └── utils.py
├── tests/
│ └── test_routes.py
└── requirements.txt
完整的审查工作流文件 .github/workflows/code-review.yml:
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
issue_comment:
types: [created]
if: contains(github.event.comment.body, '/review')
jobs:
lint-and-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: 运行 lint 检查
run: |
pip install flake8 black
flake8 app/ tests/ --max-line-length=100
black --check app/ tests/
- name: 运行类型检查
run: |
pip install mypy
mypy app/
- name: AI 代码审查
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=${{ github.event.pull_request.number }}
REPO=${{ github.repository }}
# 获取 diff
curl -s -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$REPO/pulls/$PR_NUMBER/files" \
| jq -r '.[] | "## \(.filename)\n\n\(.patch)"' > diff_content.md
# 检查是否有需要审查的文件
if [ ! -s diff_content.md ]; then
echo "没有需要审查的代码变更"
exit 0
fi
# 构建审查提示
python3 .github/scripts/build_review_prompt.py diff_content.md
- name: 发布审查结果
run: |
python3 .github/scripts/post_review_comment.py对应两个 Python 辅助脚本:
.github/scripts/build_review_prompt.py:
import sys
import os
def build_review_prompt(diff_path):
with open(diff_path) as f:
diff = f.read()
# 读取项目规则
project_rules = ""
if os.path.exists(".review-rules.md"):
with open(".review-rules.md") as f:
project_rules = f.read()
prompt = f"""你是一个严格的代码审查员,负责审查以下 PR 变更。
## 项目规则
{project_rules if project_rules else "无特殊规则"}
## 审查要求
1. 检查逻辑错误和潜在的运行时异常
2. 检查安全漏洞(SQL 注入、XSS、路径遍历等)
3. 检查是否遵循了项目约定(命名规范、导入顺序等)
4. 检查测试覆盖率是否充分
5. 检查新增的依赖是否必要
## 输出格式
对于每个问题,按以下格式输出:
### [严重程度] 文件路径:行号
- **问题描述**:描述具体问题
- **建议修复**:可选的修复建议
严重程度分级:
- 🔴 CRITICAL:会导致生产事故的问题
- 🟠 WARNING:可能导致错误的问题
- 🟡 SUGGESTION:代码质量改进建议
## 变更内容
{diff}
"""
return prompt
if __name__ == "__main__":
prompt = build_review_prompt(sys.argv[1])
# 调用 LLM API....github/scripts/post_review_comment.py:
import os
import json
import requests
def post_review_comment(review_text):
token = os.environ["GITHUB_TOKEN"]
repo = os.environ["GITHUB_REPOSITORY"]
pr_number = os.environ.get("PR_NUMBER", "")
if not review_text.strip() or "没有问题" in review_text:
print("审查通过,无需发表评论")
return
comment_body = f"""## 🤖 AI 代码审查结果
{review_text}
---
*由 AI 自动审查,仅供参考。最终合并决策由项目维护者确认。*"""
url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments"
headers = {
"Authorization": f"token {token}",
"Content-Type": "application/json",
}
data = {"body": comment_body}
resp = requests.post(url, headers=headers, json=data)
print(f"审查评论已发布: {resp.status_code}")
if __name__ == "__main__":
with open("review_output.txt") as f:
review = f.read()
post_review_comment(review)有了这套完整的配置,只要你往仓库里 push 了工作流文件和辅助脚本,AI 审查就能自动运行。以后每次创建 PR 或修改 PR,机器人都会自动给出审查意见。
不同模型的选型建议
AI 代码审查的质量很大程度上取决于你使用的模型。不同模型在不同任务上的表现差异明显:
-
GPT-4o / Claude 3.5 Sonnet:适合做深度逻辑审查。上下文理解能力强,能发现跨文件的影响。但成本较高,适合 PR 级别的最终审查
-
GPT-4o-mini / Claude Haiku:适合做快速扫描。速度比大模型快 2-3 倍,成本低一个数量级。可以用在每次 commit 的预审查阶段,发现问题后再升级到大模型
-
DeepSeek-V2 / Qwen2:中国团队的模型,中文代码注释理解能力强。如果你的项目以中文写注释和文档,这些模型在理解代码意图方面有优势
一个实用的搭配方案是:每次推送 commit 时用迷你模型做增量快速审查,PR 创建时用大模型做全量深度审查。两层结合,成本和覆盖率可以达到较好的平衡。
常见问题与排查
Q: AI 审查总是说"没有发现问题",但我知道有 bug。怎么办?
A: 检查你的审查提示语是否太宽松。常见问题是提示语中用了"如果没有问题就不输出"这种条件,但 AI 倾向于回避冲突。改成"必须列出至少 3 个你可以审查的方面"会更有用。
Q: 审查结果太长,AI 列出几十条问题,大部分是无关紧要的。怎么调?
A: 在提示语中增加严重程度门槛。比如"只报告 MEDIUM 及以上严重程度的问题";或者在审查后的处理脚本中,设置一个 JSON 格式的输出,只显示 CRITICAL 和 WARNING 级别的问题。
Q: Token 消耗太大,每次审查都上百 K。怎么优化?
A: 只审查变更文件中新增和修改的部分,忽略未变更的代码。在获取 GitHub diff 时使用 patch 格式,减少冗余信息。另外可以对大文件设置阈值——超过 500 行的文件只审查函数签名和关键逻辑,跳过实现细节。
Q: AI 审查和人类审查的关系怎么处理?
A: 我的建议是:AI 审查负责发现"技术层面的问题"(逻辑错误、安全风险、代码风格),人类审查负责"业务层面的问题"(这个功能真有必要吗?产品逻辑对不对?)。两者分工不同,不存在谁替代谁的问题。
成本考量
AI 代码审查会产生 API 调用费用。一个中等规模的 PR(10-15 个文件变更)大概消耗 5-10K 输入 Token 和 1-2K 输出 Token。按 GPT-4o 的价格算,每次审查大约 0.03-0.06 美元。
对于独立开发者来说,这个成本可以忽略不计。对于团队来说,每天几十次审查也就是几美元——相比人工审查的时间成本,这点钱不算什么。
如果成本敏感,可以用更小的模型做第一遍快速扫描(如 GPT-4o-mini),只有发现可疑问题时才升级到大模型做深度审查。这种"双层审查"策略可以在保持质量的同时把成本降到最低。
另外还有两个省钱技巧:一是设置审查频率——只有特定 label 的 PR 才触发 AI 审查,而不是所有 PR 都审。二是设置文件路径白名单——只审查 src/ 目录的核心代码,忽略测试文件和配置文件的变更。
写在最后
AI 代码审查不会完全取代人工审查——有些东西只有人才看得出来,比如业务逻辑是否真的符合需求、架构决策是否长远可持续。
但它可以帮你省掉那些"肉眼找 bug"的时间。有了 AI 代理自动跑审查,你打开 PR 的时候基本确定问题已经过了一遍——不是完美的,但是比没有强太多。对于独立开发者,这意味着一个人也能扛住代码质量关。
关键是别把这个系统搞复杂了。一个 GitHub Actions 工作流、一个写好的审查提示语、一个 API Key,三样东西就能跑起来。先跑起来,再慢慢调。
© 2026 四月 · CC BY-NC-SA 4.0
原文链接:https://aprilzz.com/tutorials/ai-code-review-automation