关于 pr-reviewer
pr-reviewer 是只读代码审查技能,可审查本地、分支或拉取请求的差异。它按严重程度报告带文件与行号证据的问题,并支持标准、结构审查、代码清理和安全审计模式。
主要功能
- 01只读差异审查
- 02按严重程度提供文件行号证据
- 03标准、结构和代码清理模式
- 04安全审计模式
- 05引导式审查与判定流程
适用场景
- 01审查暂存或未暂存的更改
- 02合并前评估分支差异
- 03对指定子系统进行安全审计
- 04为后续修复整理审查结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mblode/ agent-skills --skill pr-reviewer安装后在 Claude Code 中输入/pr-reviewer确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlevals/evals.jsonreferences/ai-slop-patterns.mdcontext-errors.mdperformance-checklist.mdsecurity-checklist.mdseverity-rubric.mdstructural-quality-rubric.md详细介绍
本地审查
- **是:**对本地差异、分支差异或 PR 进行只读审查。按严重性等级返回问题;不更改工作树。
- **不是:**修复代码(
tidy)、创建 PR(pr-creator)、监控 CI 或审查讨论串(pr-babysitter)、前端 UX、无障碍性或渲染质量审查(ui-design的 Audit 模式)、库或 CLI 易用性(dx-audit)、架构简报(codebase-architecture)、审查计划(planning)。
只报告能够用 file:line 证据佐证的问题。
**运行时机:**审查指定的差异,即使检查失败也要审查。同一修订版本已有的检查结果可作为证据;如果有针对性检查能够确认某项发现,就运行该检查,并报告覆盖范围的限制。
**然后移交。**常规流程中接下来会运行 tidy,查找复杂性并处理发现的问题,包括本报告确认的问题。因此,请撰写供后续处理的报告:每条 Fix: 都必须是有人可以提交的修改。不要自行应用任何修改,即使只是改一个字符也不行;此技能一旦编辑文件,用户要的只读报告就不复存在。
Harness 优先级
Claude Code 内置了 /code-review(正确性和清理,支持投入程度、--fix 和 --comment)以及 /security-review(审查当前差异的安全性)。输入斜杠命令会运行内置技能,而非此技能;显式指定此技能或符合下文的模式描述时,才会运行此技能。此技能不会取代它们,而是增加 Structural 和 Deslop 模式、全仓库 Security 审计、内置命令会过滤掉的合理等级、对 REVIEW.md 的支持(本地的 /code-review 不会读取该文件),以及可在任何 harness 上运行、仅使用 git 和文件工具生成的同一份报告。未经用户要求,不要在同一处差异上同时运行两者;如果本次会话中已运行内置审查,其发现应作为候选项进入结论步骤,而不是重新推导。审查期间绝不要使用 --fix 或 tidy 来“确认”问题;这些操作会修改报告所针对的工作树。
模式分派
根据用户的措辞选择一种模式;只加载该模式的参考资料:
| 模式 | 触发语 | 加载 | 范围 |
|---|---|---|---|
| Standard(默认) | /pr-reviewer、“审查我的更改”、“代码审查” | references/severity-rubric.md | 本地或分支差异 |
| Structural | “彻底审查”、“结构审查”、“深度代码质量审计”、“严格的可维护性审查”、“代码柔道” | references/structural-quality-rubric.md 和 severity | 本地或分支差异 |
| Deslop | “清理这个”、“清理 AI 代码”、“移除冗余代码”、“审查 AI 模式” | references/ai-slop-patterns.md 和 severity | 本地或分支差异 |
| Security audit | “安全审计”、“查找漏洞”、“deepsec”、“威胁建模”、“审计安全性” | references/security-checklist.md | 指定子系统或整个仓库,与差异无关 |
条件加载:
- 如果差异由 Agent 编写,或添加、更改、删除了模块、系统边界、保护机制或回退逻辑,则加载
references/context-errors.md。该资料涵盖仅凭差异本身无法发现的两个错误:重复实现或绕过仓库中已有的功能,以及为系统永远不会产生的状态添加保护代码。 - 对于身份验证、输入处理、外部 API、上传、依赖项或锁文件更改、环境配置,加载
references/security-checklist.md。 - 对于获取数据、渲染、图像、依赖项或会影响打包内容的导入,加载
references/performance-checklist.md。 - 仅当已安装不同模型的 CLI,且你要运行下文的可选第二意见流程时,才加载
agents/openai.yaml。
工作流
Review progress:
- [ ] Discover target; record the exact range
- [ ] Dispatch mode; open its references and applicable conditional references
- [ ] Gather context: intent, instruction files, REVIEW.md, quiet baseline checks
- [ ] Review: claims, added lines, removed lines, call sites, outside the diff; shard if needed
- [ ] Verdict each candidate: confirmed, plausible, or refuted
- [ ] Report, with the range, commands, and references as evidence
-
发现审查目标。 先检查已暂存和未暂存的更改(
git diff --stat、git diff --staged --stat);如果工作区干净,则检查当前分支相对于默认分支合并基点的差异(git merge-base HEAD origin/<default>)。对于 PR,使用gh pr diff <n>,并检出该分支以获取上下文;采用相同标准和 PR 交接格式。记下你审查的范围或引用对,并将其写入报告。 -
收集上下文。 使用文件工具打开所选模式的参考资料,然后对新增行和删除行应用条件加载。对于已删除的重试保护,在追踪其写入方之前,先阅读
references/context-errors.md。技能中的文件名只是指针,不代表内容已加载。如果必需的读取失败,应报告这一覆盖缺口,而不要声称已应用审查标准。从用户的表述、提交消息和 PR 描述中了解意图。加载适用范围内的AGENTS.md/CLAUDE.md,以及存在时的根目录REVIEW.md:如果这些文件与本技能的默认设置冲突,则以它们为准,因此它们要求的模式不应作为问题报告。REVIEW.md是 Claude Code Review 用来校准严重性、跳过路径、细微问题上限和仓库专属检查的文件;此处也应同样遵循。复用针对当前修订已运行的检查。如果某个候选问题需要执行验证,应运行相关的文档化命令并保留其退出状态;在未启用pipefail的情况下管道到tail可能会掩盖失败。 -
审查。 应用已加载的标准和高信号检查项;大型差异应拆分审查。进行五轮检查,因为每一轮都能发现其他轮次在结构上无法发现的问题:
- 声明。 将描述或提交消息中的每项声明对应到一个代码块,也将每个代码块对应到一项声明。没有对应代码块的声明就是一个问题:描述声称某项更改已交付,但差异中并未包含该更改。这是 Agent 编写的 PR 中最常见的描述与代码不符情形,也是最常导致 PR 被拒绝的情况。没有对应声明的代码块本身不算问题;应在就绪情况摘要中将其列为未声明的更改,让读者自行判断。
- 新增行。 阅读每个代码块,然后阅读其所在函数。已修改函数中未更改行上的错误也属于审查范围:这次差异重新暴露了该错误。
- 删除行。 对于差异中删除或替换的每一行,指出它所保障的不变量,然后找出新代码重新建立该不变量的位置。如果找不到,这就是问题:删除了保护条件、丢弃了错误处理路径、缩小了验证范围,或删除了覆盖真实用例的测试。删除看起来像是进展,容易被草草略过;这正是这一轮值得投入成本的原因。
- 调用点。 对每个已修改函数,搜索其调用方,并检查是否引入了新的前置条件、改变了返回结构、引入了新的异常或产生了顺序依赖。然后检查其被调用方:同一差异中的其他更改是否让该函数自身的某个调用变得不安全?
- 差异之外。 上述检查轮次是以差异本身为基准进行判断,因此,如果某项更改只相对于代码库才是错误的,这些检查轮次中都不会留下痕迹。对于每个新模块、保护条件或回退逻辑,都要打开差异未涉及的内容:目录现有的导出项、同类行为的相邻实现,以及受保护值的所有写入方。重新实现已有辅助函数、在错误的系统中提交更改,以及为没有任何代码会产生的状态添加回退逻辑,看起来都像是干净的代码,除非你查看差异从未打开过的文件。
references/context-errors.md中记录了需要执行的搜索,以及每项问题所需的证据。 可选且可跳过:如果已安装其他模型的 CLI(codex exec、droid exec或等效命令),使用agents/openai.yaml中的default_prompt以只读方式运行它,征求第二意见,然后像评判自己的发现一样评判它的发现。没有此类 CLI 并不构成阻碍;没有它也能完成审查。
-
判定。 为每个候选问题给出三种判定之一。报告已确认和合理可能的问题;排除已证伪的问题。
- 已确认: 说明触发问题的输入或状态,以及由此导致的错误输出。引用对应行。
- 合理可能: 问题机制确实存在,但触发条件尚不确定(时序、环境、配置)。说明需要什么证据才能确认。
- 已证伪: 事实错误,或已有防护措施。引用能证明这一点的行。
默认判定为合理可能。不要仅因问题“属于推测”就将其证伪,只要相关状态在现实中可能出现即可:并发竞争、虽罕见但可通过某条路径触发的 nil 或 undefined(错误处理器、冷缓存、缺少可选字段)、将假值零误读为缺失、代码未排除的边界上的差一错误、重试风暴和部分失败、失去锚点的正则表达式或允许列表。只有当代码能够证明问题不存在时才将其证伪:代码行并非如此表述、类型或常量使其不可能、差异已处理该问题,或问题只是没有可观察影响的风格问题。此外,排除重复项、错误归因,以及被修改函数范围之外的既有问题。差异模式只检查修改行;安全审计只检查实际属于范围内的代码。
-
报告。 使用
references/severity-rubric.md;结构性阻碍项归入Must fix before push。将合理可能的问题明确标注出来,让读者知道需要复现后再采取行动。准备情况摘要应包含证据:审查范围、每条基线命令及其最后一行、成功读取的参考资料(每项均附上其工具结果中的简短摘录),以及声明审查中发现的任何未说明代码块。
高信号标准
值得指出的类别都列在这里。凡符合其中任一类别的问题都应提出,并由判定步骤决定是已确认、合理可能还是已证伪;此处不要预先按置信度筛选,否则筛选会执行两次,第二轮就看不到第一轮舍弃的问题。
- 编译、类型、导入或语法错误。
- 导入或调用已安装依赖版本未导出的符号:在 JavaScript 或
any下看起来真实且能通过类型检查的选项、方法或模块。不要轻信不熟悉的调用;请先查阅node_modules/<pkg>或锁文件对应版本的文档。 - 明确的运行时错误、状态错误或数据处理回归。
- 捕获的错误被丢弃:空
catch、仅记录错误后便继续执行成功路径的catch,或对失败会改变调用方后续行为的 Promise 使用.catch(() => {})。说明调用方现在看到的是什么,而不是原本的错误。若回退处理是有意且正确的,则不算问题。 - 具体的利用路径、明确指出的漏洞类别,以及受影响的
file:line。 - 可衡量的性能回归。
- 缺少必要的测试:交互行为只有渲染检查;或修复缺陷时,没有在出错边界(路由、API、集成点,而非修复过程中临时创建的辅助函数)添加失败复现测试。
- 测试设置需要追踪辅助函数才能理解断言。
- 脚手架缺少使用方或无法触达:针对不存在模块的测试、没有任何导入方的生成表面,或针对没有任何内容生成的契约的 CI 检查。请注明产物所在行,以及搜索后未找到使用方的情况;若使用方可能在构建时生成、通过框架约定触达或存在于本仓库之外,则标记为可能。
- 保护、回退、重试或新鲜度机制覆盖了部署环境不会产生的状态:每次使用时都重新验证一个启动后不会再被写入的值;为一个本就能容忍数据陈旧的使用方做失效处理;或在已有监督程序会重启的进程中进行降级处理。只有在指出写入方范围、使用方的容忍度或重启策略时才报告;缺少这些信息时应保留保护措施,因为处理此问题会将其删除。这与类型系统已能排除的检查不同;后者属于此处不报告的草率模式。
- 相较于基线新增的 lint、类型检查或测试失败。
- 违反作用域内的指令文件或
REVIEW.md,并引用具体规则。 - 重试或至少一次写入,但没有幂等键或去重屏障,导致重复投递被执行多次。
- 数据库提交后又执行外部发布(队列、Webhook、电子邮件),但没有 outbox 或事务性保障(双写):任一方都可能独立失败。
- 盲目信任外部输入(Webhook/回调):未基于原始字节验证签名,或直接用载荷覆盖状态,而未向来源确认。
- 将浮点数或其他有损类型用于金额或精度敏感值,或将金额序列化为裸 JSON 数字,而非字符串或整数最小货币单位。
- 将时间戳存储或传输为非结构化字符串:本地化格式、不带时区的裸
YYYY-MM-DD HH:MM,或手动拼接的字符串,而对应列或字段需要的是一个时间点。请指出会错误解析它的读取方,以及存在歧义的日/月顺序或与 UTC 比较的本地时间。已经采用含偏移量的 ISO 8601 格式的字符串不算问题。 - 多步骤流程包含不可逆的外部操作,而后续步骤失败时没有补偿或恢复路径。
- 敏感变更(资金、权限、配置)没有记录变更内容、操作者和原因的审计记录。
所有模式(包括不加载结构检查规范的 Standard 模式)都会触发的结构检查。references/structural-quality-rubric.md 会为 Structural 模式中的每项检查提供更深入的说明;以下是始终适用的最低要求:
- 层级错误:在某项内容所属层级之上加补丁。比如,在面向所有调用方、路由、租户或文件类型的代码中加入只针对其中一个对象的特例;在调用点添加守卫,而被调用函数本可以为所有调用方返回正确的结构;事后修补值,而不是正确地生成它。指出应该承载这项逻辑的机制。
- 在没有当前需求时加入推测性抽象或本可避免的复杂性:虽然存在调用方,但不存在相应需求。
- 文件超过约 1000 行,而新增行为有适合的本地模块、组件或辅助函数边界。项目配置的
max-lines优先于此数字。 - 在无关的共享路径中加入特定于功能的条件判断。
- 自定义辅助函数重复实现规范工具的功能。
- 手动重新实现标准库或原生平台行为,并指出被替代的行为。
- 添加新依赖,而标准库、平台或已安装的依赖已经能够满足需求。
- 逻辑放错层,而其规范归属位置很明确。
不要报告风格偏好、无关的既有问题、没有复现方式或利用路径的风险、超出差异意图的大范围重写、仅由 linter 报告的噪音,或已明确忽略的违规。
输出
每条发现都包含 file:line、一行影响说明,以及可直接提交的修复方案。对于合理但未确认的发现,另加一行 Plausible: <需要什么信息才能确认>;已确认的发现则省略此行。如果某条发现依赖差异之外的内容(现有模块、相邻变更、受守卫值的写入方),则添加一行 Context:,注明相关产物,以便读者无需重新搜索即可核实。Fix: 必须切实可提交:即 tidy 会应用的修复,不能写成“考虑重构一下”这种无人能够执行的建议。内容长度应与发现数量相称,而不是套用模板填充:差异干净时,两项都写 None.,并附上简短摘要,不要凑字数。
默认本地报告:
## Local review
### Must fix before push
- [<severity>] `path/to/file.ts:line` <short factual title>
Why: <concrete impact>
Fix: <committable fix>
### Should fix soon
- [<severity>] `path/to/file.ts:line` <short factual title>
Why: <concrete impact>
Fix: <committable fix>
### Ready for handoff
- Reviewed: <range or ref pair>, <N> files
- Baseline: `<command>` -> <last line>; `<command>` -> <last line>
- Mode: <selected mode>
- Reference evidence: `<path actually opened>` -> "<short excerpt returned by the read>"; repeat for each successful reference read
- Missing reference coverage: <required reads that failed or were unavailable, or None>
- Unstated changes: <hunks no claim covers, or None>
- <readiness verdict>
一条已确认的发现和一条合理但未确认的发现,填写示例:
- [major] `src/profile/page.tsx:42` Missing null guard before dereferencing `profile`
Why: `profile` can be `null` on the first render, so `profile.id` throws before the loading state completes.
Fix: Guard `profile` before dereferencing, or move the access into the branch that handles loaded data.
- [major] `src/sync/queue.ts:88` Retry re-sends the mutation with no idempotency key
Why: On a timeout the client retries, and the server has no way to recognise the second delivery as the same write, so the balance moves twice.
Fix: Send a stable request id and dedupe on it server-side before applying.
Plausible: reproduce by forcing a timeout after the server commits but before the response lands.
如果没有问题,在前两个层级下写 None.,并保留就绪情况部分:说明检查了什么,作为评审确实已运行的依据。
PR 交接格式,用于通过 pr-babysitter 或 gh 发布;给 minor 项添加前缀 Nit:,以便作者区分润色建议和阻塞项:
## PR handoff summary
- [<severity>] `path/to/file.ts:line` <short factual title>
Why: <concrete impact>
Fix: <committable fix>
注意事项
- 在新建分支上,
git diff @{u}会因“未配置上游”而失败;在过期的检出版本上与main比较,则会包含其他人的提交。请与git merge-base HEAD origin/<default>比较,并说明范围;审查了错误的范围,就等于自信满满地讨论无关内容。 - 根据
git diff区块头计算出的行号,写进报告时会因区块偏移而出错。请从grep -n或文件本身获取行号;审查者找不到引用的行,也会把报告的其余内容一并丢弃。 - 跳过基线检查,会把已有问题误认为回归;而完整运行
npm test会输出数百行内容,此后每轮都会重复发送。请使用静默形式运行,并引用最后一行。 - 同一个有问题的辅助函数在每个调用点各报告一次,会被当成三个问题,并分别打上三个补丁,而辅助函数本身仍然有问题。请只报告一次辅助函数问题,并在其下列出调用点。
- 另一个引擎赞同你的意见,不算佐证。两个实例读取的是同一份缺少上下文的差异内容,因此都会认可其他地方已有的辅助函数,也都会接受同一个不必要的保护条件。它的输出仅供参考;只有差异内容之外的产物才能定论。
- 如果新一轮在上一轮刚改过的代码行中又发现问题,这说明循环正在制造工作,而不是逐渐找准缺陷。请结合多轮结果判断:保护条件不断累积、严重程度却不断降低,而且每次审查都让差异内容变长,就说明下一步更有用的做法,是把更简单的方案交给系统负责人,而不是再次审查。
- 搜索没有结果,并不能证明没有任何代码会使用某个产物。动态导入、框架的文件名约定、生成代码以及其他仓库,都可能引用静态搜索找不到的代码;错误地把一个文件判定为无用,会让整份报告失去可信度。
REVIEW.md中的@path行对 Claude Code Review 来说只是字面文本,它不会在此处展开导入。请用相同方式阅读该文件;如果某条规则是通过导入才遵守的,那么 PR 审查时就不会应用该规则,导致两份报告相互矛盾,作者也不会信任任何一份。
相关技能
tidy:用于排查并解决复杂性问题。它会针对同一份差异内容,从五个角度检查重复、过度设计的代码和抽象层级错误,并将本报告中已确认的问题与其一并处理。通常先使用此技能,再使用tidy。pr-creator:审查后创建或更新 PR。pr-babysitter:监控 CI 和收到的审查评论;要以评论形式发布本报告的 PR 交接格式,请使用此技能。ui-design审计模式:用于审查面向用户的前端 PR,检查用户体验、无障碍性、布局、状态覆盖和渲染质量,包括 UI 层面的冗余;此处的去冗余模式仅涵盖代码层面的冗余。dx-audit:用于审查库、CLI 或 SDK 中面向开发者的部分;如果问题涉及导出项、命令、错误字符串或配置,而非差异内容中的缺陷,请转到此技能。codebase-architecture:用于编写前瞻性的架构简报、探索深化机会,以及制定差异审查范围之外的全仓库防护措施。planning:在实施前制定和审查计划。
仅用于维护:evals/evals.json 包含针对本技能变更的回归场景;用户任务期间不会加载该文件。