用途
PR Polish 的目标是让一个 Pull Request 真正达到可合并(merge-ready)状态。它不满足于单次审查通过,而是通过循环编排,持续发现并解决问题,直到满足一组严格的收敛条件。
主要能力
该技能的核心是交替调用两个子技能:/pr-review 负责审查并发布发现(行内评论或顶层审查),/pr-address 负责解决所有未解决线程与 CI 失败。循环持续进行,直到以下条件全部成立:
- 最近一次 /pr-review 产生零个新发现(无新行内评论、无新的非空顶层审查)。
- 通过 GraphQL 可访问的每个行内审查线程均报告 isResolved: true。
- 每个非机器人、非作者的顶层审查都已被回应(回复)或通过其产生的线程解决。
- 每个非机器人、非作者的 issue 评论都已被回应。
- 每个 CI 检查的结论为 success 或 skipped / neutral,没有 failure 或仍在等待的检查。
- 连续两次 CI 后轮询(间隔至少 60 秒)保持干净——没有新线程、没有新的非空审查、没有新的 issue 评论。
该技能不设定固定轮数。如果第 N 轮引入了新评论,则必须进行第 N+1 轮。安全上限为 _MAX_ROUNDS = 10,但实际通常为 2 至 5 轮。
使用方式
技能接受一个 PR 编号或 PR URL 作为参数。若参数为 URL,会先规范化为数字 ID;若未提供参数,则尝试通过当前分支查找对应的 PR。
在开始前,技能会写入两个待办事项以展示循环进度:当前轮次的 /pr-review + /pr-address,以及最终轮询阶段(连续两次干净轮询、CI 绿色、零未解决)。
每轮开始时更新轮次计数器,仅在该轮的 address 步骤完成(所有新线程已处理并解决)后才标记完成。
状态快照与差异比对
在每次 /pr-review 之前,技能会捕获基线状态,包括:行内线程总数及每个线程的最新 databaseId、顶层审查的数量及每个非空审查的最新 id、issue 评论的数量及每个非机器人非作者评论的最新 id。审查后,若以下任一桶非空,则视为出现新发现,需要再次进入 address 轮:
- 基线中不存在的新行内线程 id。
- 现有线程的最新评论 databaseId 高于基线(旧线程上的新回复)。
- 新的非空顶层审查 id。
- 来自非机器人、非作者用户的新 issue 评论 id。
最终轮询
当 /pr-review 产生零新发现后,技能不会立即退出。由于机器人(coderabbitai、sentry、autogpt-reviewer)常在 CI 稳定后 30 至 90 秒才延迟发布审查,技能会以 60 秒间隔轮询,要求连续两次干净轮询。轮询期间会检查三类门禁:CI 门禁(任何终态非成功结论都会触发 /pr-address 并重置轮询计数)、评论/线程门禁(存在未解决线程或新评论/审查则触发 /pr-address 并重置)、可合并性门禁(冲突则解决冲突,未知则继续等待)。只有 clean_polls == 2 后才报告完成。
CI 检查获取
技能强调使用 --json 而非默认文本输出获取 CI 状态,因为作业名称可能包含空格和括号(如 test (3.11)、Analyze (python)),文本解析会出错。使用 gh pr checks 的 bucket 字段(pass | fail | pending | cancel | skipping)进行判断。
适用场景
当用户表达以下意图时使用:
- “polish this PR”
- “keep reviewing and addressing until it's mergeable”
- “loop /pr-review + /pr-address until done”
- “make sure the PR is actually merge-ready”
限制与注意事项
- 不适用于仅需一次审查(应使用 /pr-review)、仅需处理已发布评论而不进一步自审(应使用 /pr-address),或用户明确要求固定轮数(如“做 3 轮”)的情况。
- 必须在前台对话中运行,不能放入后台代理。后台代理不继承父级的斜杠命令注册表,无法调用子技能,容易在首次网络或速率限制问题处停滞。
- 每轮都必须实际调用 Skill(pr-review),即使机器人审查已存在。跳过会导致循环收敛到“机器人干净”而非“代理审查干净”。
- 子技能返回控制权时,不应总结并停止,也不应等待用户确认,而应在同一响应中立即执行下一步循环。
- 若用户需要批准风险操作(如强制推送或破坏性 git 操作),应暂停;但常规的“第 N 轮完成、需要第 N+1 轮”边界不应暂停。
- GitHub 速率限制:该技能会发出大量 GraphQL 调用。当剩余配额低于约 200 时,应回退到 REST 读取、排队线程解决操作、并在批量写入之间 sleep 5。
- 安全阀:_MAX_ROUNDS = 10,超过则停止并向用户升级。每次提交后需按目标代码库约定运行格式化与 lint 检查。
- 报告:完成时输出紧凑摘要(轮数、开启并解决的行内线程数、修复的 CI 失败数、推送的新提交数、最终状态);若因达到 _MAX_ROUNDS 退出,则明确标记未达可合并状态并列出仍未解决的线程与 CI 状态,需要人工审查。