在 agent 开发刚刚走到“从 issue 到 PR 可以全自动完成”的阶段之后,很多团队的体验其实都卡在同一步:PR 来了,代码结构挺像那么回事,测试也绿了,但审查者看着 diff,心里却虚得厉害。最近 HumanLayer 推出一个叫 /show-me 的技能,方向就是解决这个问题:让 agent 写的 PR 更容易被审查。乍看这只是一个面向 agent 工作流的辅助功能,但它背后触及的,是 AI 编程时代一个绕不开的核心矛盾——代码可以自动生成,理解却不能自动转移。
把话说明白一点:让 agent 写一段能跑的代码,已经不再是稀缺能力;真正难的,是让它把“为什么这样写”“边界在哪里”“我验证过什么”完整交给人类审查者。如果这些信息只是靠 PR 描述里的自然语言来补,那信任永远只能停留在“看起来合理”的层面。 /show-me 这类设计真正值得学的地方,不是那个被调用的技能本身,而是它把审查信息从“解释”变成了“可回放的展示”。这篇我想从这个问题出发,拆一拆 agent 生成的 PR 为什么难审,以及我们应该如何在日常开发里给这种工作流补上验证层。
1. agent 写的 PR,难点从来不是代码本身
1.1 你看到的是代码,但看不到代码背后的意图链
审查一个人类开发者提交的 PR 时,经验会帮你补上一整套背景:这个人为什么要动这层抽象、为什么不选另一个方案、他过去有没有踩过类似的坑。这些信息并不全都写在 PR 描述里,但你没有意识到的是,你正在依赖大量“社会性上下文”做判断。
而 agent 生成的 PR 没有这些背景。你能看到的是一个很标准化的输出:改动范围、描述、测试结果、甚至注释都写得很完整。可一旦问到“这里为什么用 A 而不是 B”“你有没有考虑过某种边界情况”“这个分支在真实环境下会不会触发”,你就很难从提交本身得到答案,因为 agent 的推理过程往往没有沉淀下来的载体。
这就是我觉得的第一层麻烦:代码可读,不代表意图可追溯。人类代码审查天然依赖“作者意图链”,而 agent 的原生产出通常是这个链路的片段式输出。它可能在某个中间步骤里想过边界情况,但没有记录,也没有在代码注释里表现;它可能在最后生成时统一优化了风格,却掩盖了最初的方案取舍。
1.2 描述越流畅,审查反而越要警惕
有一个现象值得单独拎出来:agent 写的 PR,描述往往特别顺滑。它有背景、有实现思路、有验证方式,措辞听上去非常笃定。而这个顺滑本身就是新的风险。
语言模型生成 PR 描述时,它的任务是“生成一段说明这段改动的文字”,而不是“严格记录这个改动过程中所有真实存在的犹豫和验证”。所以它会倾向于把最终代码的状态描述得很自洽,甚至把一些没有真正验证过的行为写得像已经验证过一样。这不是模型在撒谎,而是它的优化目标和工程严谨性的目标并不一致。
更麻烦的是,如果 agent 在中途改过一个方案,最终生成 PR 描述时通常会按最终版本来组织叙述。于是审查者看到的是一个整齐划一的故事,而整个过程中的来回试探、失败尝试、放弃路径,都没有被保留。传统审查能通过“提问—回答—反驳”来还原这些信息,但 agent 没有这种即时回答的能力,或者你需要额外跑一轮对话才能问清楚,成本立刻就上去了。
我在这类项目里常见的经验是:agent 型 PR 的 bug,往往不是差在代码能不能跑,而是差在一组没说清楚的假设上。比如它假设某个外部服务一定可用、某个输入不会为空、某个权限一定存在。你可以跑通测试,却很难凭肉眼看代码发现这些假设。这就是为什么只有“占位符式 PR 描述”和“一个链接的测试结果”是不够的;审查者需要的是能把这些假设暴露出来的过程材料。
2. 与其让 agent 解释,不如让它“展示”
2.1 解释和展示,对审查者的价值完全不同
先说什么是解释,什么是展示。解释是让 agent 用自然语言告诉你它做了什么;展示是让它通过一段可执行、可观测的流程,把行为结果摆在你面前。前者服务于“听起来正确”,后者服务于“看起来可验证”。
在人和人协作的代码审查里,解释是必要且高效的,因为双方共享大量背景。但在 agent 协作里,解释很容易变成一种自洽的表演:它生成的文字只是对代码当前状态的一种合理归纳,而不是对真实过程的忠实报告。你越依赖解释,越难发现它没有覆盖的部分。
/show-me 这个名字本身其实就很有讲究。它没有叫“explain more”,也没有叫“give me a summary”,而是要求 agent 把东西“给我看”。这意味着默认信息通道是行为产物:运行过的命令、调用过的接口、输出的日志、变化的界面、验证过的输入输出对,而不是一段又一段看起来很有道理的说明。
因此我觉得,这条功能名字背后是一个很重要的产品判断:对于 agent 生成的 PR,审查对象应该从“代码 + 叙述”变成“代码 + 可观察的验证行为”。自然语言只负责连接,真正支撑信任的是展示出来的证据。
2.2 把 /show-me 做成“技能”,比临时加提示词更重要
这里要展开一个容易被忽略的点:为什么要把这类能力做成“技能”,而不是直接在系统提示里加一句“请你验证后再说”?
先说技能和普通提示词的区别。普通给 agent 的指令是上下文里的一段话,它可能影响这一次输出,但不一定能保证行为被稳定执行。技能更像是一套带结构、带步骤、带输出约定的“专业能力”。它定义清楚输入是什么、执行流程是什么、产物放在哪里、格式长什么样。agent 不再靠即兴发挥,而是按固定的方式组织“如何展示一个代码改动”。
如果只是临时提示 agent“跑一下再描述”,它大概率还是会以它自己最舒服的方式给你一段总结。有了 /show-me 这种固定技能之后,agent 会知道:它需要准备一个可供人类快速操作或检查的验证路径。它应该跑通一个最小例子,再考虑边界情况;它需要把输出日志或截图转成能放入 PR 的可读信息;它还要明确标注哪些行为它没有证明,哪些只适合在特定环境验证。
这种做法还有一个隐藏优点:技能本身的步骤可以被版本化和迭代。第一次实现可能只是“跑一条命令,打印结果”;下一次可以升级为“记录输入样例、执行前后的差异、异常分支的日志”。团队的审查要求可以逐渐沉淀到技能文件里,而不是散落在每次对话里叮嘱模型。
3. 把“展示型验证”落进 agent 工作流,能怎么设计
3.1 先定义清楚:一次“展示”应该包含什么
不管团队是否接入 HumanLayer 这样的平台,只要你想让 agent 写的 PR 更可审,你就得先定义“可审”的标准。我建议从一个最小集合开始。
一次合格的展示性验证,至少应该包含四个部分:变更对象、验证场景、执行证据、未验证边界。变更对象是让审查者知道这次动的是哪条链路;验证场景是要说明你跑通了哪条用户路径或哪个函数行为;执行证据是命令、日志、截图、输出文件这类能独立查看的东西;未验证边界是 agent 自己承认没有覆盖到位的部分。
实际做的时候,可以把这些内容放成一份小报告,也可以是 PR 下一篇结构化评论。重点是避免一个倾向:让 agent 把大量的原始日志直接粘进 PR。那样只会淹没有效信息。原始日志应该统一放到一个可访问的路径或 artifact 目录,PR 里只放摘要和指向证据的链接。
下面是一个常见的最小结构,可以作为团队约定参考:
变更范围:一句话说明改了哪条链路或模块 主要验证路径:对一个最小场景的执行回放 关键证据:日志片段 / 截图 / 命令输出 边界与风险:本次未能验证的服务、权限、数据条件 复现方式:为了让人工审查者在自己环境中重跑,需要执行的命令如果一个 PR 连这样的最小展示结构都没有,我就不太建议直接进入人类逐行 review。因为缺少这些信息时,review 会变成一场猜测游戏:猜测 agent 到底验证了多少、猜测某个改动会不会破坏隐藏依赖。
3.2 不同 agent 任务,展示策略应该分型
前面说的是通用结构,实际用起来还得按任务类型调整。不然 agent 为了完成“展示”这个要求,可能会用一套固定动作去套所有场景,效果反而差。
我看到很多团队走偏的地方,是让 agent 无论做什么任务都跑同一个演示脚本。比如前端改了一个按钮样式,也让它去跑接口测试;后端改了一个查询语句,却只让它输出一句“验证通过”。展示应该跟着你能观察到的行为类型走。
如果按常见任务分,我会大致这样拆分:
- 后端逻辑或接口改动:展示的核心是输入输出对、错误分支、边界条件。最好有一条命令能跑几个关键用例,并打印断言结果。
- 前端界面交互改动:展示的核心是用户看到的变化。尽量用浏览器自动化或录屏截图方式,把关键路径的点击流程记录下来。
- 数据迁移或批量任务:展示的核心是执行前后对照。要有输入样本数量、失败样本数量、变化摘要,而不是只看整体成功率。
- 依赖升级或重构:展示的核心是兼容面。跑单测还不够,至少要针对涉及到的两个版本分别查看关键调用是否一致。
这套分类不需要很复杂,只要能把“展示”这个行为从泛泛的请求变成有明确目标的动作。agent 执行时也就更容易知道自己该收集哪类证据。
4. 审查 agent 生成的 PR,建议用三级漏斗
4.1 从“跑通”到“展示”再到“人类决策”
我习惯把 agent 生成的 PR 审查拆成三级漏斗,避免一开始就进入全量代码阅读。
第一级是“执行可信”:也就是代码能编译、测试能通过、CI 没有报错。这是最低要求,说明这条改动在既定验证集下没有崩。它不能代表行为正确,只代表“机器没发现明显故障”。
第二级是“行为展示”:也就是审查者要用 /show-me 的风格去检查证据。这个改动跑过的路径是否覆盖了主要业务场景?输出结果和行为预期对不对?有没有异常分支日志?这些证据和 PR 描述之间是否一致?到这一级,审查者才真正开始确认“它做的确实是它说要做的”。
第三级是“意图决策”:这层通常只能由人类完成。改动的方向是否符合产品预期?这个抽象是否会给后续维护带来负担?是否值得引入这个复杂度?这些判断没有标准答案,也无法通过展示自动证明,它依赖业务理解和对代码演进的判断。
这个三级模型最重要的作用是:让我们不再把“测试通过”误当成“可以 review”。有了分层,团队就知道该在哪一层投入精力,也知道如果某层证据缺失,应该把 PR 打回去补,而不是自己硬读代码去猜。
4.2 一套可以日常使用的审查检查清单
基于上面的漏斗,我再给一份可以落到 PR 检查项的清单,方便你直接作为参考,不用在每次 review 时重新思考该问什么:
| 检查层 | 具体检查点 | 缺失时的处理方式 |
|---|---|---|
| 执行可信 | 是否能跑通测试;是否通过构建;是否有异常日志 | 打回 agent 重新运行,直到进入可展示状态 |
| 行为展示 | 是否有可回放的主路径;输出证据是否和描述一致;是否覆盖边界条件 | 让 agent 补跑一次并补证据,而不是靠文字补描述 |
| 边界披露 | 是否明确列出未验证项;是否说明依赖的服务或权限状态 | 标记为风险项,提交人工确认,不默认通过 |
| 意图匹配 | 改动目标和原始需求是否一致;抽象层级是否合适;长期维护成本是否可接受 | 只能由人判断,不能用 agent 的自述替代 |
在实践中可以这样用:每次拿到一个 agent 提交的 PR,先看它能不能过执行可信这一关;过了之后,再检查行为展示材料是否完整;最后才把时间花在意图决策上。这样既不会盲目信任 agent,也不会在一堆低质量信息里反复打转。
我还会建议团队为“展示缺失”设一个明确处理原则:默认不直接展开逐行 review,而是要求 agent 先补出一次可回放的验证过程。因为如果 agent 连一条最小展示路径都给不出来,说明它很可能只是完成了代码生成,而没有真正验证过行为。
5. 真正落地时,最容易出问题的其实是证据本身
5.1 展示材料本身也可能偏斜
任何工具都不是银弹, /show-me 这种思路同样有边界和坑。最大的坑不是 agent 不展示,而是它展示出来的证据本来就是偏的。
常见偏斜有两种。第一种叫“成功路径偏斜”:agent 为了完成展示,很可能选择最容易跑通的路径,或者补充了满足场景的输入,却没有覆盖真实用户的数据分布。它展示给你看的是正常结果,但真正会出问题的异常分支可能根本没被触发。
第二种叫“环境偏斜”:展示跑得很顺利,是因为它所在的执行环境里有一些隐性便利,比如特殊权限、跳过登录、固定测试数据、已经初始化的服务。当你把验证过程放到真实环境或另一个开发环境时,同一个动作可能完全无法复现。
所以在审查展示材料时,不能只看结果对不对,还要看这个结果是在什么条件下产生的。最实用的办法是问一句:把这个展示拿给另一个工程师,能不能按相同步骤复现?如果不能复现,那它只能算一份说明,而不是合格的证据。
5.2 展示问题时的排查顺序,应该从“现场重建”开始
如果审查时发现问题,不要立刻陷进代码里逐行推理。因为 agent 生成的代码通常不是你写的,你通过静态阅读寻找问题很可能既慢又不准。更好的路线是先确认展示链路本身能否复现。
我建议按这个顺序排查:
第一步,看输出条件。检查 agent 提交的日志、截图、运行记录里有没有明显异常:是不是同一分支、哪份代码版本、用了什么命令。先确认它说“跑了”的那个动作确实对应当前 PR。
第二步,重建现场。试着用你手上可用的环境重新执行一次它记录的展示命令。如果无法执行,优先排查路径、依赖、环境变量和外部服务是否一致。
第三步,再判断输入。很多问题不是代码写错,而是输入样例没有覆盖。确认它展示时的数据是不是一个真实且合理的数据分布,而不是为了方便跑通挑选的特例。
第四步,回到参数和策略。如果现场重建一致但仍不通过,再检查它的运行参数,比如并发数、超时时间、模型版本、工具版本。
这里我想特别强调一点:让 agent 展示的意义不是展示一次成功路径,而是让你能退回原路,验证失败在哪里。如果一份验证材料没办法帮你重建现场,那它就只是装饰,不是证据。
6. 给长期维护者的一句话:让“展示”沉淀成资产
6.1 展示技能不能只是“一次好用”,要能成为回归基线
很多团队在刚开始引入这类工作机制时,容易把它当成一个“PR 时的仪式”:每次跑一下、截个图、填个模板,然后 PR 合并,材料丢弃。这个思路有点浪费,因为展示性验证真正值钱的部分是它能持续复用。
如果第一次跑通时,你把输入样例、执行命令、关键输出都固定下来了,那它本质上就是一组回归基线。下一次 agent 改这个模块时,只要还能用同样的展示流程跑通,你就能快速知道它没有破坏原有行为;如果展示失败,你也会非常清楚地看到是哪一步发生了变化。
所以,我的建议是不要急着把事情弄大,只要用固定的目录或统一的命名把展示材料保存下来。一个可行的通用约定是:
artifacts/show-me/{pr编号或分支名}/{执行日期}/output.log把脚本或命令放在仓库里,把产物放到一个固定路径。下一轮查看时,你重新跑一条命令就能对比之前的结果。
6.2 agent 开发越往后走,审查者真正审的是证据质量和判断质量
再往后看, /show-me 这样的能力,不只是解决“agent 写的 PR 能不能看懂”的问题,它会慢慢改变代码审查这个角色本身的定义。
原先的代码审查,主要看代码写得好不好、设计对不对。可当代码生成由 agent 完成时,人类审查者的工作会越来越像“审计员”:确认 agent 的验证覆盖是否合理、确认展示证据是否完整、确认有哪些隐含假设没有被暴露。你不是去重新写一遍代码,也不可能把每行改动都从零理解一遍。你的价值在于判断:它展示的证据,是否足以支持这次合并决定。
这种转移其实是有利的。它把人类从“逐行阅读机器生成代码”的低效模式里解放出来,放到更需要常识、判断和长期视角的位置上。前提是,你需要真正建立“展示型验证”这个基础。没有它,agent 生成越快,代码库积累的不可验证风险就越大。
所以回到开头那句话:agent 开发的下一个晋级点,不是让它写出更多代码,而是学会为自己的代码建立足够可信的证据链。如果你的团队已经在大量使用 agent 提交 PR,下一步最值得投入的,就是定义好属于你们自己的 /show-me 流程。先跑通一次完整展示,再把它沉淀成命令和固定产物路径。你会明显感觉到,审查 agent 写的 PR 时,终于有了可以抓住的东西。