人人都用 LLM 的时代,我们该如何做 PR 审查?

HN Vibe Coding Practices 2026-09-08T05:51:53.274528

2026 年 9 月 5 日

游戏规则变了。当周围每个人都配上了现代大语言模型(LLM)时,原来那套我自以为不错的 PR 审查方式,已经不好使了。

多年来,PR 早已经变成一种仪式性的流程,承载着各种功能:让两三双眼睛盯着代码捉 bug,帮新同事熟悉更大的代码库和团队风格,让你了解队友们都在忙什么,等等。但这些作用,现在很多已经没那么重要了。多亏了 LLM,抓简单 bug、理解代码库、跟进同事的工作,都有更快、更高效的办法。

我并不是说要把 PR 取消掉。PR 仍然有意义,但意义已经改变了——我们组织 PR 的方式,自然也应该跟着变。

这篇文章想分享一下,在处理大量 LLM 参与开发的代码库时,我的做法有了哪些主要变化。显然,大家还在摸索当中,我预计再过几年,很多做法又会不一样。

读代码

直到不久前,我始终持有一个基本立场:每个人都需要亲自读代码。有一些 AI 爱好者认为这没必要。我很敬重 antirez,而他就提出过这个观点,所以我认真对待这种可能性。可是,尽管有这些声音,尽管模型能力越来越强,我依然觉得我们还没到那一步。代码是事实所在。到了 2026 年,我仍然认为,想做负责任、有成效的产品开发者,我们还是需要和代码保持某种联系。

我非常清楚,如果你让 Claude Code 做一个返回 JSON 的 API 端点——执行一条 SQL 查询,并把结果以 JSON 格式输出——它就能直接做对,不会搞砸。你让它补上自动化测试,让它补上文档,你知道结果会很好。但我没有审查这些代码。于是我有了一种负罪感:如果我没有亲自 review 代码,就这样把它用到生产环境里,真的负责任吗?

这是西蒙·威利森(Simon Willison)在5月5日那天说的话。放到现在,我会说得更远——在一个规格写得很清楚的编程任务上,5.6 Sol 写出来的代码,整洁程度跟我自己写的差不多,而且对边界情况的感知要敏锐得多。它不会因为累了就偷懒,既不会省掉手动验证,也不会漏掉单元测试。几分钟就能完成,而我得花上一整天。在我相当一部分产出里,我确实更信任它写的代码,而不是我自己写的。作为一个写代码赚钱写了差不多18年的人,承认这一点有点难堪,但事实就是这样。

我喜欢拿 Waymo 来类比——总会有一个临界点,电脑在统计意义上比人做同样任务时产生的缺陷更少,我觉得我们正在接近那个点。我甚至还没试过 Astra。

今天,对于一个已经用上大语言模型的团队,我认为务实的做法是取中间路线:读一部分代码[1]。对于一个准备合并的 PR,我希望看到:

  1. 作者在把它从草稿状态拿出来之前,先让自己的大语言模型做一次全面的自我审查[2]。

  2. 作者已经读过并理解了代码的关键部分。这个 diff 真的修复了那个 bug 吗?哪些函数实现了新功能?它们在哪里被调用?

  3. 作者大致浏览过辅助代码和测试。有没有改到不相关的模块?是不是突然多出来 300 行代码,只为覆盖一个根本没那么重要的场景?

  4. 评审人理解了问题本身,清楚改动前后的状态,并且和自己的大语言模型就这个分支是否合适做过一轮有意义的讨论。

尤其是,我不认为逐行读代码是评审人时间和精力的好用法。评审人当然应该让自己的大语言模型做一次对抗式审查(专门找茬的那种),去发现代码层面的缺陷,但那是相对次要的部分。

作为评审人,我经常和我的聊天机器人进行这样的对话[3]:

帮我审一下这个 PR。从产品或者用户视角说一下问题是什么,帮我快速回顾一下相关背景,解释改了什么、为什么这样改就能解决问题。哪些 bug 或代码质量问题值得提,也帮我指出来。
……(问题是这样,解决方法是这样,代码看起来还不错)……
那如果用户做了 X 呢?这种场景下这个方案是不是会很糟糕?
(顺着思路推演了一遍)你说得对,这个方案在这种情况下确实处理不好,因为……
那如果我们提前到这个更早的节点把数据注入进去呢?能修好吗?
…… 可以。

这样一来,我就有了一条高价值评论可以贴到 PR 上。

显然这只是个模拟出来的对话,但你明白我的意思。作为 reviewer,我能提供的最大价值,就是发现架构和产品层面的失误。而在当下,这种判断力往往不在写代码的 LLM 所拥有的上下文里,所以这仍然是人类该干的活[4]。

我还想更进一步说:架构/产品层面的 review 从来都是整个 review 中最有价值的部分。以前,想针对架构提出有质量的评论,通常得先把代码读明白。运气好的话 PR 描述写得不错,但能完整、清晰地覆盖所有相关讨论的描述少之又少。

当 LLM 读取一个 PR 的 diff 和它周边的上下文之后,这个会话就变成了一份活的、可以交谈的 PR 描述。你可以对自己关心的部分追问细节;可以确认代码中做了哪些假设;可以精确地获取你自己关心的问题,然后调动你的专业经验来判断把这条 PR 合进去到底是不是个好主意。如果要求 PR 作者提前写出一段静态文字,来满足所有潜在 reviewer 的这类需求,几乎是不公平的。更好的做法是:在 PR 上写清楚的摘要,然后让每个 reviewer 用自己的 LLM 去拉取他们各自需要的上下文。

这和我们长期以来认可的「好的 PR 评审」标准相比,已经发生了很大变化。最好的消息是:如果你接受这个思路,作为评审者,就不用再硬着头皮去读几千行 LLM 写的代码了。为什么要花几个小时,去做 GPT 几秒钟就能搞定的事?那种体验既痛苦,也不可持续,而且对大多数软件来说根本没有必要。太好了。

那些讨论式提问,不再有用

以前我做评审时,经常会提出一些并不指望对方改代码的问题。有时是因为某处代码不够清楚,或者涉及作者脑子里已有的上下文,而我不想在没搞懂的情况下多耗费时间,就会问:「这部分具体是怎么工作的?」或者「这样能覆盖到情况 X 吗?」多数情况下,这不过是一次共同学习的交流,最终可能让代码简化一点,或者多加一条注释。

但在一个大家都有 LLM 的团队里,我这样做只是在浪费作者的时间。我完全可以直接去问自己的 LLM,而且几乎总能找到答案。如果答案并不令人满意,说明代码本身确实有问题——那就不是一个问题了,而是一件该修的事。

直接打补丁,比解释更快

Niklas Gruhn 在最近一篇博客文章里写道:「不要当人肉代理。」这是条好建议,我至今仍然遵守。如果因为某种原因,我需要把 Codex 或 Claude 生成的原始结果直接展示给别人,我通常会先道个歉。

这种为对方着想的心情,放在 PR 评审里却会带来一个问题:

  1. 评审者用 LLM 跑代码,LLM 发现了一个 bug
  2. 评审者看懂了这个发现,对照代码确认问题确实存在
  3. 评审者用自己的话写一条总结,可能先让 LLM 出个草稿,再整理成评论发出去
  4. PR 作者看到评论,大致理解了问题
  5. PR 作者把评论粘贴进自己的 LLM,让 LLM 把

大多数人会觉得,reviewer 二话不说直接往里加 commit 很唐突,甚至算冒犯——但现在也许不一样了。除了避免“双重审核代理”之外,我猜还有一个原因:如果大部分代码本来就是 LLM 写的,那大家大概也不会那么在意具体的代码风格,或者“纯粹”的 PR 归属权了。有了 LLM,痛苦的合并冲突也成了过去式[5]。或许,让 PR 默认就是协作式的,整体来说反而更健康?

所以现在的情况很可能是:我 review 一个 PR 时,不会再丢下 5 条评论然后干等着,而是直接推几个 commit 上去,附带一个批准。作者能更快合并。太好了。

说清楚一点,我不认为这是全面性的转变。我上面描述的做法也许在某个项目里行得通,但如果我去开源项目开 PR,默认肯定不会这么做。除非那项目明显就是“氛围激进”型,否则我会非常不自在去让一个陌生人处理我自己都没细读过的代码。而且没错,如果项目要求代码必须纯手写,我也会照办。毕竟,那也挺有意思的。


  1. 我这里说的是错误影响范围有限的代码。如果你在做医疗设备或飞机,那你早就该知道,不该听我这种博主瞎说。↩︎

  2. 网上流传着很多“模型发现不了自己的错误”的说法。那纯属无稽之谈。换一个模型也许能找到更多 bug,但就算只是不加引导地来一句“帮我们 review 一下工作分支,看看有没有问题”,也常常能翻出一些有价值的东西,值得你在推送之前修掉。显然,模型要是一开始就没打出这些 bug 当然更好,但这就是当前工具的现实。↩︎

  3. 我在 Codex 里有一个“技能”,其实就是这个提示词的加长版。真正的版本里还带着点对 Claude 生成的 PR 描述的调侃。↩︎

  4. 有不少公司在做“熄灯工厂”式的项目,让 LLM 负责所有的规格、规划和长期开发。我再说一次,我认为我们还没到那一步。还是把精力放在当下真正有效的工具上吧。↩︎

  5. 这件事很少有人主动谈起。你们有没有意识到,我们现在能享受到的工具有多好?已经有软件能理解每次提交的语义意图,在数千行代码里,把几十处互相冲突的改动智能地理清脉络。

查看原文