我为什么坚持自己撰写 PR 描述 | Laravel
我认为,即使 Agent 完成了大部分实现工作,作为开发者,我们依然应该亲自来撰写 Pull Request 的描述。
这并不是因为 Claude 或 Codex 不会写。它们当然会,而且通常能产出比我自己更详尽的内容。
我主张自己撰写,主要基于两点原因:
撰写描述的过程,迫使我们去理解并阐释待审查的代码变更。
审查者需要的,是来自我们人类作者的上下文背景,而非由编写代码的 Agent 生成的差异摘要。
#写作是一个检查点
许多开发者正将具体的实现工作交给 Agent,这本身未必是坏事。它们很擅长这个,在大多数情况下表现确实非常出色。
但当我们把越来越多的代码编写工作移交出去后,我认为团队找到保持与代码及其变更联系的方式至关重要。
Pull Request 的描述正是其中一种方式。
如果代码、测试、Commit 消息甚至 PR 描述都由 Agent 生成,那么我们究竟是在哪个环节强迫自己去理解和解释这些变更呢?
希望我们都已经在审查 Agent 产出的代码。我绝非暗示使用 Agent 生成的描述就代表你不懂自己的改动。
但亲手撰写描述,会形成一个自然的检查点。
“这里到底发生了什么变化?”
“为什么会变?”
“Diff 里看不出但存在潜在后果吗?”
“审查者需要知道什么?”
如果你无法在不让 Agent 自我解释的情况下回答这些问题,这通常意味着你需要花更多时间去审视这个变更。
#Claude 自信
此外,我现在称之为 “Claude 自信” 的现象也值得关注。
Claude 极其自信。它做完改动、跑完测试后,会告诉你一切准确、健壮、向后兼容且随时可发布。
公平地说,它经常是对的。但 “Claude 很自信”和“我理解这个变更”是两回事。
我们很容易对代理产生的信心深信不疑,尤其是在它既编写了代码实现,又解释了其正确性的情况下。
随着这些工具的不断进步,我认为我们需要对此保持警惕。描述问题、让代理去执行,然后以较高的抽象层级评估结果,这变得太容易了。
#PR 描述是写给人看的
这里还有一个更实际的原因。Claude 生成的描述非常详尽,会告诉你改了什么、为什么改、哪些文件动了、如何测试的,以及莫名其妙地强调哪些部分…… 至关重要。
PR 描述不是用来包含所有变更细节的。那是 diff 的作用。
PR 描述是为了让另一个人去阅读。它应提供足够的上下文,让读者理解:
这个 PR 为什么存在
它改变了什么
它如何融入更广泛的工程背景
任何奇怪、有风险或非显而易见的地方
你特别希望他们关注或提供意见的点
它应当简明,但有用。
#实际场景
下面是一个略微夸张的例子,展示了当代理自动发起 PR 时,常见的 PR 描述风格:
#摘要
此 PR 通过添加验证逻辑改善了工作区删除流程,防止用户删除仍包含活跃部署的工作区。
#变更内容
在
deleteWorkspace中添加了hasActiveDeployments检查新增
WorkspaceHasActiveDeploymentsError更新工作区删除 API 处理器,使其返回 409 响应
添加单元测试,覆盖有/无活跃部署的工作区场景
更新 API 响应类型
在工作区设置 UI 中添加错误处理
添加用户可见的错误消息,提示删除被阻止
#实现细节
deleteWorkspace函数现在会在执行原有删除逻辑前查询 deployments 仓库。如果发现一个或多个活跃的 deployment,就抛出WorkspaceHasActiveDeploymentsError。API 层捕获这个错误并映射为 409 响应……#测试
添加了无活跃 deployment 时删除的单元测试
添加了有一个活跃 deployment 时删除的单元测试
添加了有多个活跃 deployment 时删除的单元测试
确认原有的 workspace 删除测试依然通过
运行了
pnpm test workspace运行了
pnpm typecheck#向后兼容性
这个改动完全向后兼容。对于没有活跃 deployment 的 workspace,删除行为保持不变。
这份描述并没有什么特别不对的地方,甚至可以说相当详尽。
但其中大部分内容对我审查这个改动没什么帮助。
实现细节我审 PR、看 diff 的时候自然会看到。测试那一节基本上只是在告诉我测试都跑通了。至于“完全向后兼容”这种说法,我也不太可能仅凭一句话就信了——这正是我审查时要重点关注的内容之一。
作为这个改动的设计者和负责人,我更希望看到的是这样的描述:
禁止用户删除仍有活跃 deployment 的 workspace。
之所以做这个改动,是因为目前删除 workspace 后,这些 deployment 会处于异常状态。我考虑过自动清理它们,但觉得目前让用户先手动删除会更安全。值得关注:我不太确定 409 是不是合适的响应码,特别希望能听到大家对这个问题的看法。
虽然更简短,但提供的恰恰是审查者真正需要的东西:
这个改动为什么存在,而不是改了什么
只看 diff 可能得不到的背景信息
过程中做出的决策和权衡
不确定性,而非把每个决定都描述得理所当然
审查方向,以及我的注意力在哪里真正有价值
告诉我“做了什么”、“为什么做”和“在哪里做”。不用说“怎么做”。
#处理更多事情时,上下文更重要
随着 Agent 让我们能同时处理更多任务,我发现跟踪事情进展变得更加困难。
我们在 Laravel 的大多数人都专注于同一件大事——Laravel Cloud,但在这件大事内部,包含无数看似同时发生的小事。
谁在做什么?这个 Pull Request 为什么存在?它如何融入更大的工作?项目实际去向何方?
当我打开队友的 Pull Request 时,我不希望阅读由机器人生成的 1,500 字内容。我希望那个变更的负责人——Agent 背后的人类协调者——能向我说明情况。
然后我才会去读代码。
#最后的真心话
让 Agent 写代码。让它们帮助我们探索问题、编写测试、重构代码并提高效率。
但当需要向另一个人类解释变更时,我认为这部分应该来自人类。
并非因为 Claude 和 Codex 做不到,而是因为你拥有这个变更,你就应该拥有它的解释权。