跳到主要内容

你的编码 Agent 写不出的 PR 描述

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的编码 Agent 完成了任务。Diff 很小,测试全绿,Lint 干净,而 PR 正文从头到尾只有一句话:"修复 X 模块中的 bug。"远在六个时区之外的评审者打开页面,孤立地阅读 diff,看不出任何毛病,于是批准了一个技术上完全正确、却解决了错误问题的改动。代码合入。两天后,一位客户来问他们一直依赖的某个变通办法为什么突然失效了 —— 这时你才发现,你的 Agent 修复的那个 bug,并不是工单里描述的那个 bug。

代码没问题。评审者很尽责。Agent 也严格按照吩咐做事。问题出在他们之间的那个交付物 —— pull request —— 它丢失了一切本可避免这次失误的信息。

这就是"推理链断层"(rationale gap),也是 Agent 辅助开发中那些吞吐量数字不会告诉你的一面。Faros AI 在 2026 年对 22000 名开发者的遥测显示:重度采用 AI 的团队合并的 PR 数量增加了 98%,但 PR 体积增大了 154%,评审耗时延长了 91%。一项针对 567 个 Agent 生成 PR 的实证研究发现:83.77% 最终被接受,而人类作者的对照组是 91.01% —— 但其中 45.1% 需要人工修改才能满足正确性、文档或代码风格要求。按一项行业测量,AI 撰写的 PR 比人类撰写的要多等约 4.6 倍的时间才会被评审者取走。瓶颈已经从"写代码"挪到了"读 Agent 留下的隐式推理"。

PR 正文到底是为什么存在的

一个 pull request 是两个交付物粘在一起。Diff 回答的是"这段代码做了什么"。描述回答的是"这段代码为什么存在"。这是两个来源不同的问题。前者可以从补丁里机械地推导出来,一个 LLM 读读 diff,就能写出像样的摘要。后者不行,因为答案不在 diff 里,而在别的地方:发起这项工作的工单、触发工单的用户投诉、你和同事在 Slack 上讨论"那个显而易见的修法其实是错的"的那条线程、上周四开始失败的某个 eval、Agent 在第一轮评审后丢弃的那次失败尝试。

人类作者会下意识地把这些信息编进 PR 正文里,因为他们就是亲历这些上下文的人。他们会写:"这是我们在事故里第三次见到这个问题,上次的修法是 XYZ,这次用了不一样的路线是因为……" —— 异地评审者从未参加那场对话,但对话本身已经在交付物里了。

Agent 同样有这些上下文 —— 通常还更多。它有发起本次运行的提示词、它被分配的工单文本、它被要求重现的失败 eval、它在一次中止尝试里丢弃过的旧 diff、它读代码时的所有工具调用记录,以及一份每个决策的书面记录。然后,在开 PR 的那一刻,它把这一切都丢掉了,只写下"修复 X 模块中的 bug。"上下文在运行时是存在的,只是在交棒的那一刻被丢弃了。

为什么 Agent 默认给出敷衍的 PR 正文

这不是模型能力的问题。能写出补丁的同一个模型,只要被要求,也能写出五段话的推理章节。Agent PR 之所以普遍敷衍,根源在结构,值得把原因说清楚。

Agent 的脚手架不评估 PR 正文。它评估的是测试是否通过、Lint 是否通过、diff 是否能干净地应用、以及任务指令是否被满足。PR 正文是提交前的最后一步,通常由一个通用的"概括这些改动"子提示词产出。没有任何 eval 会因为 Agent 提交了一段读起来像别的 PR 的更新日志的描述而把它判为失败。于是你拿到的是 Agent 能产出的最廉价的描述:对 diff 的字面摘要,所有承载"为什么"的内容都被剥离干净。

脚手架还会丢掉对 PR 正文最有用的那部分上下文。发起工作的那段提示词通常被第一轮推理消耗掉,然后随着运行推进被压缩出 Agent 的上下文窗口。Agent 中间的"我试了 X 然后回退,因为 Y"那部分推理,被存在草稿本或子 Agent 里,等到最后一次工具调用时就消失了。等 Agent 真的要调用 create_pull_request 的时候,它上下文里声音最大的是最近的工具输出和最终的 diff —— 不是最初的工单,也不是它走到这一步所经过的路径。Agent 写出来的 PR 正文就反映了这一点:它描述了终点,没描述旅程,因为旅程已经滑出了窗口。

第三个原因是评审反馈无法回流到脚手架。当人类评审者在评论里问"你为什么不用 X 方案?"时,Agent 会把它当作一条新消息,在 PR 的讨论串里就地回答。下一个开类似 PR 的 Agent 完全收不到任何信号,告诉它上一次本应该在正文里就预先回答这个问题。缺陷每次都在对话里被弥补,而从来没有被上升为脚手架里的一条规律。

异步评审真正需要什么

异步代码评审是一条低带宽信道。评审者没办法拍拍你肩膀问你。他们手里只有 diff、描述、关联的工单(如果有的话)、以及 CI 输出。一切让他们能决定要不要批准的信息,都得装进这个包里 —— 因为问一个问题的代价可能是一整天的往返。

人类作者学会了这一点,他们故意"过度解释"。他们会把自己已经否决的方案写出来,免得评审者再提一遍。他们会列出评审者应当挑战的假设,让对话往真正有价值的地方走。他们会贴上失败的 eval 链接或者客户工单,让评审者能核实这次确实是在解决正确的问题。这些都不在 diff 里。但正是这些东西,让异步评审能跑得动。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates