代码评审(Code Review)和单元测试,一直是研发流程里最耗人力、又最容易被临时省略的两个环节。把大模型请进评审与测试环节,既能守住质量底线,又能把工程师从重复劳动里解放出来——这正是 AI 辅助研发最务实的落地姿势。
一、为什么把大模型请进 Code Review
人肉评审的瓶颈很明显:资深工程师的时间最贵,而大部分评审意见其实是高度模式化的——空指针风险、魔法数字、异常处理缺失、命名歧义、并发隐患。这些恰恰是语言模型擅长捕捉的信号。把第一遍”找茬”交给模型,让人聚焦在架构权衡、业务正确性和安全边界上,评审效率和质量都能上一个台阶。
单元测试同理。写测试最枯燥的部分是搭脚手架:构造入参、Mock 依赖、补边界用例。模型能根据函数签名和上下文,几秒内吐出可运行的测试骨架,工程师只需要校验和补充业务断言。它不是替代测试,而是把”从零写起”变成”审改即可”。
二、AI 代码评审的三种落地姿势
2.1 IDE 内联评审:写代码时即时反馈
在编辑器里选中一段代码,让模型给出改进建议。VS Code 配合支持聊天侧栏的插件,就能做到”选中即评审”。好处是零延迟、不打断心流,适合捕捉局部坏味道。
2.2 CI 门禁式评审:合并前自动把关
把评审作为流水线的非阻塞检查:通过就在 PR 里贴出建议,不通过也不强制卡死(避免误杀)。这是性价比最高的落地方式,详见我们用 GitHub Actions 搭建自动化工作流的思路,把模型调用串进同一个流水线即可。
2.3 PR 自动评论:团队协作的共识沉淀
在 Pull Request 里由机器人自动评论,所有成员都能看到模型的意见,还能把高频问题沉淀成团队规范。配合VS Code 的高效编辑技巧,开发者本地改完、推送后立刻收到评审,闭环最短。
三、写出高质量评审 Prompt
模型输出质量高度依赖 Prompt。一份能稳定产出可用评审的 System Prompt,应当明确角色、范围、输出结构和禁忌。下面是一段可直接套用的模板:
你是一名资深代码评审工程师,请对下面的 diff 做 Code Review。
要求:
1. 只关注真实风险,不要挑格式毛病的刺;
2. 每条意见给出:严重程度(阻塞/建议/可选)、问题位置、修复示例;
3. 特别关注:空指针/越界、资源未释放、并发竞争、异常吞掉、注入风险;
4. 不编造不存在的 API;不确定就写明"需确认"。
输出用 Markdown 列表,最多 10 条,按严重程度排序。
关键纪律是”不挑格式刺”和”不编造 API”——这两句能把模型从废话和幻觉里拉回来,显著提升信噪比。
四、单元测试生成:从函数签名到测试骨架
假设有一个计算购物车折扣的函数,让模型基于签名生成 pytest 骨架:
# 被测函数
def calc_discount(price: float, vip: bool, coupon: float | None) -> float:
if price <= 0:
raise ValueError("price must be positive")
rate = 0.9 if vip else 1.0
final = price * rate
if coupon:
final = max(0.0, final - coupon)
return round(final, 2)
# 模型生成的测试骨架
import pytest
@pytest.mark.parametrize("price,vip,coupon,expect", [
(100, False, None, 100.0),
(100, True, None, 90.0),
(100, True, 20, 70.0),
(100, True, 200, 0.0), # 优惠券不能让价格变负
])
def test_calc_discount(price, vip, coupon, expect):
assert calc_discount(price, vip, coupon) == expect
def test_negative_price_raises():
with pytest.raises(ValueError):
calc_discount(-1, False, None)
注意模型自动补了”优惠券不能让价格为负”和”负数抛异常”两个边界用例——这正是人容易漏、模型擅长的地方。你只需确认这些断言符合业务预期,再补上集成层面的用例即可。这和我们用Java 模式匹配化简分支逻辑、用结构化并发收敛异常路径的思路一脉相承:先把边界说清,测试才好写。
五、实战:用 GitHub Actions 接一个评审机器人
下面是一个最小可用的工作流:在 PR 打开或更新时,取出 diff,调用一个 OpenAI 兼容的聊天接口(本地 Ollama、云端网关均可),把评审结果作为评论回写。把密钥放在仓库 Secrets 里,切勿硬编码。
# .github/workflows/ai-review.yml
name: ai-code-review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: Run AI review
env:
LLM_BASE: ${{ secrets.LLM_BASE }}
LLM_KEY: ${{ secrets.LLM_KEY }}
run: python .ci/ai_review.py
脚本侧负责取 diff 并调用模型(伪代码骨架):
import os, subprocess, requests, json
diff = subprocess.run(
["git", "diff", "origin/main...HEAD"], capture_output=True, text=True
).stdout
resp = requests.post(
os.environ["LLM_BASE"] + "/chat/completions",
headers={"Authorization": "Bearer " + os.environ["LLM_KEY"]},
json={
"model": "local-model",
"messages": [
{"role": "system", "content": "你是代码评审工程师,只输出 Markdown 列表。"},
{"role": "user", "content": "评审以下 diff:\n" + diff[:12000]},
],
}, timeout=60,
)
review = resp.json()["choices"][0]["message"]["content"]
print(review) # 通过 gh pr comment 回写到 PR
生产环境记得给 diff 做长度截断、加超时与失败兜底,否则大模型偶发慢响应会拖垮整个流水线。
六、避坑清单:AI 评审的五个误用
模型不是银弹,用错方式反而会引入噪声。下面这张表是落地时最常见的五个坑:
| 误用 | 表现 | 正确做法 |
|---|---|---|
| 把评审当门禁硬卡死 | 模型误报导致合并不了,团队开始无视告警 | 非阻塞提示,严重问题才人工升级 |
| 让模型挑格式毛病 | 满屏”建议加空格”,信噪比崩塌 | Prompt 明确”只关注真实风险” |
| 盲信生成的测试 | 断言本身写错,绿了也是假阳性 | 人必须核对断言是否符合业务 |
| 喂未脱敏代码 | 密钥、PII 随 diff 外发 | CI 前做脱敏与 Secrets 扫描 |
| 无长度截断 | 超大 diff 触发限流或超时报错 | 截断 + 分文件分批评审 |
七、效果怎么度量
别只凭感觉。建议跟踪三个指标:评审平均耗时、被人工采纳的建议占比、上线后由评审漏掉的缺陷数。先在小团队灰度两周,确认信噪比达标再推广。记住一句话:AI 评审的目标是”让人少做重复判断”,而不是”替人做最终决定”。把这点想透,工具才真正变成研发的副驾。
八、团队落地路线图:三周灰度法
别一上来就全量铺开。最稳妥的节奏是三周分阶段灰度,每一阶段都有明确的退出标准,避免”上了又没人用”的烂尾。下面这张表可以直接当成推广计划抄走:
| 阶段 | 动作 | 退出标准 |
|---|---|---|
| 第一周 | IDE 内联评审,个人自愿试用 | 试用者反馈”有用”占比超六成 |
| 第二周 | CI 非阻塞评论,小团队 3–5 人 | 建议被人工采纳率稳定超三成 |
| 第三周 | 复盘指标,决定是否全量 | 合并前缺陷数同比下降可观测 |
每一阶段都要保留”一键关闭”的能力——模型偶发抽风时,能立刻退回纯人工评审,团队信任才不会在一次误报里崩掉。把自动化当成默认开启的辅助,而不是强制的门禁,这条灰度纪律比任何工具都重要。




