LLM reviewer的价值在于捕获人类易忽略的边界问题(空指针、错误吞掉、假测试),关键是把评论范围收窄并把误报当配置bug修。
当一个 LLM 审核员能捕捉到人类会略过的枯燥问题——空指针检查缺失、被吞掉的错误、一个什么都没断言的测试——而其他时候保持沉默,它就证明了自己的价值。一旦它每个 PR 写十二条评论,其中一半只是在复述 diff 本身已经说明的内容,它就变成了累赘。两者之间的区别几乎完全取决于你如何给它划定范围和设置门槛,而不是你选用了哪家供应商。
我在几个仓库上跑过 LLM 审核,有托管工具也有自建的 GitHub Action。那些让机器人活过第二周的团队都做了同一件事:把机器人定位为顾问性质,缩小它可以评论的范围,把每一个误报都当作配置 bug 来修复,而不是当作需要忍受的噪音。
Linter 和类型检查器已经包揽了确定性的那层:格式化、未使用的变量、明显的类型不匹配。LLM 只值得在它之上的那层模糊逻辑添加——那种静态规则无法编码的推理。
实际上,有价值的发现集中在几个类别:看起来没问题但实际上吞掉或误分类了错误的异常处理、新代码中的差一错误和边界逻辑、跑绿了但实际上没有断言其所声称行为的测试,以及安全相关的坏味道,比如未参数化的查询或粘贴到配置中的密钥。它还真的很擅长发现"这个函数的名字已经不再匹配它的行为"——这种漂移在第三个文件之后人类审核员就会停止注意到。
它不擅长的是任何需要它看不到的仓库级上下文的东西。问它"这会破坏两层级目录之外的调用方吗",它会自信地猜测,因为它拿到手的只有 diff。这个猜测就是大多数噪音的来源。
要点:把 LLM 指向 linter 做不了的判断题,让它远离需要 diff 之外上下文的问题。
杠杆效应最高的单个设置是评论预算。给它设上限——每个 PR 最多三到四条内联评论。强迫模型对发现结果排序和筛选,对信号质量的提升比任何 prompt 调优都有效,因为它把"列出你注意到的所有东西"变成了"哪两件事最值得人类关注"。
除了预算上限,四条规则能持续减少抱怨:
顾问性质,绝不阻塞。 机器人发帖评论;它不设置必需的状态检查。一个会幻觉的强制 LLM 门禁有一天会被整个团队静音。
只评论改动的行。 审核完整文件会引诱模型去重新争论这个 PR 里没人动过的代码。
完全压制风格意见。 如果你的格式化工具在 CI 里跑了,LLM 就没有理由提命名或空格。在 prompt 里明确说出来。
跳过琐碎 diff。 锁文件更新、生成代码和纯重命名不需要你的意见。
要点:每个 PR 三条评论的预算、只针对改动行、没有阻塞权,这才是区分人们愿意保留的审核员和被静音的审核员的关键。
你有三大类选项,正确的选择取决于你需要多少控制权对比你想多快让它跑起来。
像 CodeRabbit 和 Qodo Merge(开源 PR-Agent 的后继者)这样的托管工具,几乎不需要任何工作就能给你一个称职的审核员,而且它们帮你处理 diff 分块和评论 threading。代价是你通过它们的旋钮来调优行为,而且你的代码会经过它们的基础设施——这可能过不了你的合规门槛。
自定义 Action 会花你一个上午,但给你完全的 prompt 控制权、预算控制权和模型选择权。截至 2026 年中,Anthropic 和 OpenAI 的通用前沿模型在代码推理能力上都足够强,模型选择的重要性已经低于 prompt 纪律。这些工具每一个都会偶尔提出一个错误或重新引入 bug 的"修复"建议——整个类别诚实的技术局限在于,你不经过阅读就无法信任一个建议。
要点:从托管工具开始验证价值,只有当你遇到无法通过配置绕过的行为或数据驻留障碍时,才迁移到自定义 Action。
如果你走自定义路线,形态很小。一个触发于 PR 的 workflow,拉取 diff,用一个严格限定范围的 prompt 发送给 API,然后把顶级发现结果发回来。下面是触发器的骨架:
name: llm-review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
permissions:
pull-requests: write # to post review comments
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get PR diff
run: git diff origin/${{ github.base_ref }}...HEAD > pr.diff
- name: Run review
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
run: python review.py pr.diff
Prompt 是纪律所在的地方。在我测试中最有用的指令是让模型为沉默辩护——告诉它返回零条评论是有效且经常是正确的答案:
SYSTEM = """You review a git diff for a pull request.
Report ONLY: likely bugs, swallowed errors, missing edge-case handling,
tests that don't assert their stated behavior, and security issues on
CHANGED lines. Ignore style, naming, and formatting.
Return at most 3 findings, ranked by severity. If nothing meets the bar,
return an empty list — that is the correct answer for most PRs.
Each finding: {file, line, one-sentence issue, suggested fix}.
Respond as JSON only."""
解析那个 JSON,丢弃不在改动行上的任何内容,把幸存者作为审核评论发布。请求结构化 JSON 而不是自由格式散文,这是使"只改动的行"和预算过滤器在代码中可强制执行而不是寄希望于 prompt 的关键。
要点:请求带排名的 JSON 并明确空列表选项,在模型响应后强制执行过滤器,而不仅仅是在 prompt 内部期望它们。
两个数字几乎能告诉你一切。追踪机器人评论被人类标记为有用解决与被驳回的比例,以及机器人实际发表评论的频率。一个健康的审核员在大多数 PR 上保持沉默,在开口时能真正捕捉到问题。如果它对每个 PR 都在评论,你的门槛太低了。如果没有人曾经响应它的评论,关掉它——一个被静音的机器人比没有机器人更糟,因为它训练团队完全忽略自动化审核员的声音。
给它两周的试用期和一个明确的终止开关,并提前告诉团队,噪音评论是需要报告的 bug,而不是需要忍受的礼仪。这种框架让人们提交配置修复而不是默默厌恶这个东西。
要点:如果它少于三分之一的评论被响应,问题在于你的范围划定,而不是模型。
独立开发者和小型团队应该从托管工具开始——CodeRabbit 或 Qodo Merge——设置为纯顾问模式,因为设置成本接近于零,你会在调优之前学到什么值得捕捉。有领域特定规则、严格数据驻留需求或对评论量有强烈意见的团队应该构建自定义 GitHub Action,这样预算和范围就住在他们控制的代码中。无论你选哪个,保持非阻塞、限制在三到四条评论,并仅限于改动行。目标不是做一个像资深工程师一样审核的机器人——而是一个可靠地捕捉繁琐错误的机器人,这样人类可以把注意力花在设计上。