RTK 的 /pr-review 技能解析:一个带人工验证闸门的 PR 批量评审四阶段工作流
【免费下载链接】rtkCLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies项目地址: https://gitcode.com/GitHub_Trending/rtk4/rtk
本篇围绕 RTK 仓库中的 Claude Code 技能定义 SKILL.md 展开,完整拆解其"按复杂度递增批量评审 PR"的四阶段工作流:前置检查、PR 列表构建与分级、逐条评审与合并验证、阻塞 PR 的规范化评论与场次总结。读完你可以掌握一套可复制的"AI 代理评审 + 人工逐条确认"的开源仓库 PR 处理流水线,并理解 RTK 自身gh命令过滤层如何为这类工作流省下大量上下文 token。
一、技能定位与元信息
/pr-review是 RTK 仓库维护者为 Claude Code 定义的一个本地技能(skill),其原始定义位于 .claude/skills/pr-review/SKILL.md。它解决的具体问题是:当仓库的 PR 积压增长时,如何由 AI 代理按"从最简单到最复杂"的顺序逐条评审,并在每次合并前取得维护者的显式批准。
技能的 YAML frontmatter 声明了以下元信息:
- description:按复杂度递增(XS → S → M → L)批量评审 RTK 的 PR。对每个 PR:检查状态(冲突、CLA、review 结论),阅读完整 diff,在上下文环境中分析代码,呈现"链接 + 体积 + 建议"的摘要;在任何 merge 之前等待显式验证;对处于阻塞状态(冲突、CLA 缺失、CHANGES_REQUESTED)的 PR 发布 boldguy 风格的适配评论。
- Args:
triage参数在评审前先触发一次完整 triage;from:<num>参数从指定 PR 号开始恢复进度。 - allowed-tools:
Bash、Read、Grep、Glob、Write、AskUserQuestion。其中Bash承担全部gh/git交互,Read用于在 diff 触及复杂逻辑时读取源文件上下文,AskUserQuestion是"合并前必须人工确认"这一核心规则的落点。
二、何时使用
技能文档明确给出三个触发场景:
- 在
/rtk-triage(对应 rtk-triage 技能)之后,对其产出的结果采取行动; - 周期性执行,用于持续消化 PR 积压("degraisser le backlog");
- 在 release 之前,清空 quick wins 队列。
这与仓库中另一个发布流程技能 ship 技能 形成衔接:/pr-review负责把队列清空,/ship负责版本 bump 与发布。
三、Phase 0 — 前置条件
技能要求在执行任何评审前先运行三条命令确认环境:
git rev-parse --is-inside-work-tree gh auth status date +%Y-%m-%d- 第一条确认当前目录是 git 工作树;
- 第二条确认 GitHub CLI 已登录且 token 有效(后续所有
gh pr/gh api调用都依赖它); - 第三条获取当前日期,用于 Phase 4 场次总结的标题。
如果启动时传入了triage参数,技能会先执行一次/rtk-triage,并直接采用 triage 产出的 quick wins 列表作为本次评审序列,跳过 Phase 1 自行构建列表的步骤。否则进入 Phase 1。
四、Phase 1 — 构建 PR 列表
在无 triage 输入时,技能用一条gh pr list拉取全部 open PR 的元数据,并用jq按变更规模升序排序:
gh pr list --state open --limit 200 \ --json number,title,author,additions,deletions,changedFiles,mergeable,mergeStateStatus,isDraft,statusCheckRollup,reviewDecision,body \ | jq 'sort_by(.additions + .deletions)'这里请求了 11 个 JSON 字段:additions/deletions/changedFiles用于定级,mergeable/mergeStateStatus用于预判冲突,isDraft用于过滤草稿,statusCheckRollup用于看 CI,reviewDecision用于识别 CHANGES_REQUESTED,body用于后续交叉引用 issue。
4.1 尺寸分级表
技能对 PR 的分级标准(注意这是 pr-review 自己的口径,比 pr-triage 技能 中基于 additions 的 50/200/500 分级更严格,因为它同时约束文件数与"逻辑非平凡性"):
| 尺寸 | 判定标准 | 处理顺序 |
|---|---|---|
| XS | < 30 行,1 个文件 | 最先处理 |
| S | 30–100 行,1–3 个文件 | 其次 |
| M | 100–200 行,逻辑非平凡 | 再次 |
| L | > 200 行 | 最后处理,或跳过 |
| XL | > 500 行 | 跳过(另开专项 session) |
4.2 列表过滤规则
构建列表时立即排除三类 PR:
- 排除所有 draft PR;
- 排除"我们自己的 PR"(维护者团队内部的 PR 走不同的 review 流程);
- 若传入
from:<num>参数,则从该 PR 号开始处理(用于中断后恢复)。
五、Phase 2 — 逐条评审(核心循环)
这是技能的核心:一次只处理一个 PR,严格按升序推进。每个 PR 走 A→E 五步。
5.1 步骤 A — 先验状态,再读 diff
技能刻意把状态检查放在读 diff之前,目的是避免在注定无法合并的 PR 上浪费 diff 读取成本。状态检查分三个gh调用:
# 1. 合并可行性 + CLA gh pr view <num> --json mergeable,mergeStateStatus,statusCheckRollup,reviewDecision # 2. 已有 review(是否 CHANGES_REQUESTED?) gh api repos/rtk-ai/rtk/pulls/<num>/reviews \ --jq '.[] | {author: .user.login, state: .state, body: .body}' # 3. 行内评论(仅当存在 CHANGES_REQUESTED 时) gh api repos/rtk-ai/rtk/pulls/<num>/comments \ --jq '.[] | {author: .user.login, body: .body, path: .path, line: .line}'依据状态做"快速裁决",跳过不必要的深度阅读:
| 状态 | 动作 |
|---|---|
| MERGEABLE + CLA 正常 + 无 CHANGES_REQUESTED | → 进入读 diff |
| CONFLICTING | → 准备 rebase 评论,跳过 diff |
| CLA 未签 | → 准备 CLA 评论,跳过 diff |
| 某 maintainer 已 CHANGES_REQUESTED | → 跳过(不 override),仅记录 |
| Draft | → 静默跳过 |
5.2 步骤 B — 阅读完整 diff
gh pr diff <num>技能特别强调:如果 diff 触及复杂逻辑(filter functions、正则、路由分发),必须用Read工具打开对应源文件在上下文中阅读,理解实际影响面,而不是只看 diff 文本。这一条正好对应 RTK 仓库中高频变更的文件(见第八节的"高冲突文件清单")。
值得一提的是,由于代理运行在 RTK 之上时命令会被 RTK 拦截,gh pr diff的输出会先经过 RTK 的压缩。从 gh_cmd.rs 的实现看,pr_diff把原始 unified diff 交给 compact_diff:每个文件单独统计+N -M增量、每个 hunk 最多保留 100 行并附带截断计数、整体上限 500 行,且支持--no-compact逃生口还原完整 diff。这解释了技能敢于"读完整 diff"而不爆上下文的底层原因——RTK 在命令层已经做过一轮保真压缩,而代理仍可随时用Read取回完整源文件。
5.3 步骤 C — 按强制格式呈现给维护者
技能规定了每个 PR 必须使用的呈现模板(原文要求包含可点击的 PR 链接,此处以PR 链接占位表示):
**PR #<num>** — PR 链接 **Author**: <login> | **Size**: <XS/S/M/L> (+<add> -<del>, <N> 个文件) | **CLA**: <ok/未签> | **Mergeable**: <clean/冲突> **它做了什么** — [2–4 句话:解决的问题、触及的文件、修改的逻辑、新增的测试] **diff 质量**:[诚实分析:干净 / 需要核实 / 已发现问题] 是否 merge #<num> ?配套的四条呈现规则:
- 必须附带 PR 链接;
- 必须说明是否有测试覆盖该变更;
- 若触及复杂函数,必须解释影响;
- 不许美化——diff 平庸就直说平庸;
- 分析语言使用法语(技能定义语言),与 GitHub 评论的英语形成分工。
5.4 步骤 D — 等待显式验证(人工闸门)
技能用大写强调"NE JAMAIS MERGER SANS RÉPONSE EXPLICITE"(绝不因无显式回答而合并)。维护者回复与代理动作的映射表:
| 维护者回复 | 代理动作 |
|---|---|
| "ok" / "go" / "merge" | 执行合并gh pr merge --merge |
| "skip" / "next" | 不合并,跳到下一个 PR |
| "comment" | 发布评论(未提供文本时先索要文本) |
| "close" | 关闭该 PR |
| 附带指令的回复 | 先执行指令,再重新请求确认 |
文档还特别警告:"它看起来不错"不等于 ok——模糊的正面评价不构成合并授权。
5.5 步骤 E — 合并与合并后检查
获得验证后执行合并(技能文档给出的命令为gh pr merge <num> --merge --squash,其中--squash表示把分支上的多个提交压成单个提交):
gh pr merge <num> --merge --squash合并后立即确认:Merged #<num>. ✓,然后回头检查下一个 PR 是否因本次合并而变成 CONFLICTING——尤其当两个 PR 触及rules.rs、registry.rs、main.rs或CHANGELOG.md这类热点文件时。
从 RTK 源码看,代理执行gh pr merge时输出会原样透传:gh_cmd.rs 的pr_merge函数注释明确写了"gh pr merge 是破坏性操作——透传真实输出,让用户(或 AI 代理)确切看到发生了什么"。这个设计意图与技能步骤 E"立即确认合并结果"的要求是同一套安全哲学:对不可逆操作不做任何压缩改写。
六、Phase 3 — 阻塞 PR 的 boldguy-adapt 评论
对因冲突、CLA 缺失或需要 rebase 而阻塞的 PR,代理在 PR 上发布一条英语评论(面向国际社区),遵循一组写作规则:
- 只用英语;
- 开头真诚地感谢贡献(具体到这条 PR 带来了什么,而非套话);
- 明确说出阻塞点,最多 1–2 条;
- 给出解锁的确切步骤;
- 不用 em dash、不用电报式短句、句长要有变化;
- 不能听起来像 bot。
技能内置了三套模板,可原样套用:
冲突 + CLA 缺失(双阻塞):
Hey @<author>, thanks for the contribution! [mention spécifique de ce que la PR apporte] Two things before we can merge: 1. The branch needs a rebase on `develop` — there's a conflict on [fichier]. A `git rebase origin/develop` should do it. 2. The CLA hasn't been signed yet. The CLAassistant bot left instructions in the PR — just follow the link, takes about a minute. Once both are sorted, this will move quickly.仅冲突:
Hey @<author>, good fix on [description spécifique]. One thing to address before merge: the branch has a conflict on [fichier] after recent changes to develop. A `git rebase origin/develop` should resolve it cleanly.仅 CLA 缺失:
Hey @<author>, thanks for [description spécifique]. The only thing blocking merge is the CLA signature — the CLAassistant bot left the link in the PR. Once that's done, we're good to go.三套模板的共同结构是"具体致谢 → 编号列出阻塞点 → 给出可复制的解锁命令 → 轻量收尾",把"要求对方改代码/签协议"这一容易显得生硬的动作包装成清晰的行动清单。
七、Phase 4 — 场次总结
处理完全部 PR(或维护者主动要求时)输出场次总结,格式固定为表格 + 计数:
## Session recap — YYYY-MM-DD | PR | Titre | Action | Raison | |----|-------|--------|--------| | #N | titre | Mergé ✓ | — | | #N | titre | Skip | CHANGES_REQUESTED (KuSh) | | #N | titre | Commenté | Conflit + CLA | | #N | titre | Fermé | Doublon avec #M | Mergées : N | Skippées : N | Commentées : N"Raison" 列要求写明跳过/评论的具体原因(冲突、CLA、被某位 maintainer 要求修改、与某 PR 重复),使每次评审会话在事后完全可追溯。
八、贯穿全流程的六条硬规则
技能在末尾用加粗列出不可违反的规则,它们定义了 AI 代理与人类维护者之间的权限边界:
- 一次只呈现一个 PR——不允许多个 PR 同时挂起等待验证;
- 没有显式 "ok" 绝不合并——"看起来不错"不算 ok;
- 不 override maintainer 的 CHANGES_REQUESTED——除非维护者给出明确指令;
- 合并后主动检查下一个 PR 的冲突状态(两者触及同一文件时);
- 语言分工:面向维护者的分析用法语,面向 GitHub 社区的评论用英语;
- boldguy 语气:事实化、直接、友善,且明确禁止 AI 痕迹(em dash、staccato 短句、过于完美的收尾金句)。
九、高冲突文件清单(从源码结构看)
技能末尾维护了一份需要重点监视的冲突高发文件清单,与当前仓库实际结构逐一吻合:
- CHANGELOG.md —— 所有 PR 都会触及(release-please 自动生成的变更日志);
- src/discover/rules.rs —— 规则频繁新增;
- src/discover/registry.rs —— classify/rewrite 测试的集中地;
- src/main.rs —— 命令路由分发,每个新命令接入都会改它;
- src/hooks/rewrite_cmd.rs —— hooks 重写逻辑。
这份清单的实战价值在于:它把步骤 E 的"合并后冲突检查"从泛泛的"留意同文件"落到了具体路径上,使代理在连续合并两个 PR 时能精确判断是否需要重新核对mergeable状态。
十、源码级支撑:RTK 如何为这条流水线省 token
/pr-review本身只是流程定义,它真正高效的另一半来自 RTK 对gh命令输出的过滤层 src/cmds/git/gh_cmd.rs。几个与本技能直接相关的实现细节:
--json显式透传:has_json_flag 检测到用户/代理显式传入--json时直接透传原始 JSON——Phase 1 那条 11 字段的gh pr list --json ... | jq sort_by(...)正是依赖这条透传通道拿到完整元数据,jq 排序在 RTK 之外完成;- 状态字段默认压缩:不带
--json时,gh pr view走 view_pr,只拉取number,title,state,author,body,url,mergeable,reviews,statusCheckRollup并渲染成带[ok]/[x]/?图标的紧凑状态行;PR body 再经 filter_markdown_body 去掉 HTML 注释、badge 行、纯图片行、水平线并折叠空行(代码块内容原样保留)。这正对应步骤 A 中反复查询mergeable/reviewDecision的高频小查询场景; gh api一律透传:run_api 注释说明gh api是显式高级命令,"把 JSON 压成 schema 会毁掉全部值并迫使代理重新抓取",因此原样透传——步骤 A 的两条gh api .../reviews、.../comments调用依赖这一行为拿到完整的 review 记录;- diff 保真压缩:
gh pr diff默认走 500 行上限的compact_diff(见第五节 5.2),被截断时会附带[full diff: ... --no-compact]提示,保证代理既省 token 又知道如何取回全量。
十一、适用前提与限制
- 运行环境:仓库 git 工作树内、
ghCLI 已认证;技能通过 Claude Code 的 skill 机制加载,AskUserQuestion工具是人工验证闸门的载体,换成不具备交互式提问能力的宿主时,步骤 D 的语义需由宿主自行保证; - 仓库特定假设:评论模板与状态检查默认目标仓库为
rtk-ai/rtk(gh api路径写死),迁移到其他仓库需替换 owner/repo;技能还假设目标仓库启用 CLAassistant 机器人,无 CLA 流程的项目应删去相应分支; - 分页限制:
gh pr list --limit 200意味着超过 200 个 open PR 时该命令不能一次取全,与 rtk-triage 技能 中"超过 200 条需分页并提示用户"的处理相呼应; - 尺寸口径差异:pr-review 的 XS/S/M/L 按"行 + 文件数"分级,而 pr-triage 按 additions 单维分级,两个技能并行使用时应以各自文档的表格为准,不要混用阈值。
十二、小结
/pr-review的价值不在任何单条命令,而在它把"批量处理 PR"拆成了一条可审计的流水线:triage 产出序列 → 状态先行裁决 → 完整 diff 加上下文源码阅读 → 强制格式呈现 → 显式人工批准 → 合并后回查冲突 → 阻塞 PR 走模板化英语评论 → 场次总结留痕。配合 RTK 在gh命令层的保真压缩(透传与压缩的边界在 gh_cmd.rs 中逐命令显式声明),这条流水线同时满足了两个通常互相矛盾的目标:代理侧的 token 效率,与人类侧对每一次不可逆合并的完全控制。
【免费下载链接】rtkCLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies项目地址: https://gitcode.com/GitHub_Trending/rtk4/rtk
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考