mcpField
A
aif-review

aif-review

github.com/lee-to测试与质量1.1k100 次安装今天更新
代码仓库

关于 aif-review

aif-review 是面向开发者的代码审查技能,关注正确性、安全性、性能和可维护性。它可审查暂存或未暂存改动、拉取请求及提交,并可验证不确定的发现。

主要功能

  1. 01检查正确性、安全性、性能和可维护性
  2. 02审查暂存或未暂存的改动
  3. 03按编号或 URL 审查拉取请求
  4. 04比较 Git 引用之后的提交
  5. 05通过可选验证检查发现

适用场景

  1. 01提交前审查代码改动
  2. 02评估拉取请求中的变更
  3. 03检查指定 Git 引用之后的提交

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lee-to/ai-factory --skill aif-review

安装后在 Claude Code 中输入/aif-review确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
CHECK-MODE.md
SEVERITY.md
VALIDATOR.md
tests/
check-mode-happy-path.spec.yaml
check-mode-validator-failure.spec.yaml
check-mode-validator-malformed.spec.yaml

详细介绍

代码审查助手

进行全面的代码审查,重点关注正确性、安全性、性能和可维护性。

步骤 0:加载配置

首先: 如果 .ai-factory/config.yaml 存在,请读取该文件以确定:

  • 路径: paths.description、paths.architecture、paths.rules_file、paths.roadmap 和 paths.rules
  • 语言: language.ui,用于设置审查摘要的语言
  • Git: git.base_branch,用于提供分支比较指引

如果 config.yaml 不存在,则使用默认值:

  • 路径:所有产物均使用 .ai-factory/
  • 语言:en(英语)
  • Git:base_branch: main

行为

参数标志

将参数字符串路由到以下某种模式之前,先提取表示可选行为的独立标记。从参数字符串中移除这些标记,再按正常流程路由剩余内容。

  • +check — 审查完成后运行可选的发现项验证器。完整流程(包括运行时机、失败模式、输出附加内容和门禁结果重新计算)见 references/CHECK-MODE.md。当存在此标记或审查结果中至少包含一个置信度标记时,运行验证器,详见下方“门禁前处理标记”。对于不含标记的审查,只有提供此标记才会触发验证器,因此未提供时不会运行。该标记可出现在主参数之前或之后(例如,/aif-review +check、/aif-review 123 +check、/aif-review main +check)。

如果剩余参数字符串为空,则回退到空参数模式(暂存更改审查)。未知的 + 前缀标记会作为主参数的一部分传递,不会被静默移除。

边缘情况:如果 Git 引用恰好命名为 +check,则该名称会被标记提取器移除——这是可以接受的权衡。

无参数(审查暂存更改)
  1. 运行 git diff --cached 获取暂存的更改
  2. 如果没有暂存内容,则运行 git diff 获取未暂存的更改
  3. 分析每个文件的更改
使用 PR 编号/URL
  1. 使用 gh pr view <number> --json 获取 PR 详情
  2. 使用 gh pr diff <number> 获取差异
  3. 审查 PR 中的所有更改
使用 Git 引用(提交模式)

参数路由流程:

  1. 空 → 暂存更改审查(见上文)
  2. 数字或 #N → PR 模式(见上文)
  3. 其他所有内容 → 使用 git rev-parse --verify 验证 → 进入提交模式或询问用户

验证:

git rev-parse --verify <argument> 2>/dev/null
  • 有效引用 → 进入提交模式(执行以下步骤)

  • 无效引用 → 不要静默回退到暂存更改审查。请询问用户进行确认:

    AskUserQuestion: `<argument>` is not a valid git ref. What did you mean?
    
    Options:
    1. Review staged changes instead
    2. Cancel
    

    根据选择:

    • “审查暂存更改” → 执行暂存更改审查(默认模式)
    • “取消” → 告知用户审查已取消 → 停止
    • “其他” → 用户提供更正后的引用 → 通过 rev-parse 重新验证

边缘情况:纯数字命名的分支(例如 123)会被解释为 PR 编号——这是可以接受的权衡。

步骤:

  1. 获取引用与 HEAD 之间的提交列表:

    git log --oneline --reverse <ref>..HEAD
    

    如果没有找到提交(HEAD 与 <ref> 相同或早于 <ref>),请告知用户并停止。

  2. 检查提交数量: 如果超过 20 个提交,请在继续之前询问用户:

    AskUserQuestion: Found <N> commits to review. Reviewing all of them will be slow and consume significant context. How to proceed?
    
    Options:
    1. Review all <N> commits
    2. Review only the last 20
    3. Cancel
    

    根据选择:

    • “审查全部” → 继续使用完整提交列表
    • “只审查最近的 20 个” → 将列表截短为最近的 20 个提交(保持时间顺序)
    • “取消” → 告知用户审查已取消 → 停止
  3. 审查每个提交:

    git show <commit-hash> --stat
    git show <commit-hash>
    

    对每个提交检查:

    • 提交消息是否与实际更改相符?
    • 更改是否为原子操作(每个提交包含一个逻辑单元)?
    • 该提交引入了哪些问题?
  4. 提供综合摘要,并附上每个提交的备注

上下文检查关卡(只读)

最终确定审查发现之前,运行只读上下文检查关卡:

  • 检查已解析的架构文档(如果存在),查看是否存在边界/依赖对齐问题。
  • 检查已解析的 RULES.md 文档(如果存在),查看是否违反明确的约定。
  • 检查已解析的路线图文档(如果存在),查看是否与里程碑对齐,并指出可能属于 feat/fix/perf 工作但缺少关联的情况。

人工检查关卡结果严重程度:

  • 对于非阻塞性不一致或缺少可选文件,使用 WARN。
  • 仅在用户/审查政策要求的明确阻塞条件下使用 ERROR。

如果用户希望单独进行仅规则检查,建议使用 /aif-rules-check。人工 /aif-review 检查关卡标签保持为 WARN / ERROR,然后附加标准机器可读检查关卡结果,状态使用 pass|warn|fail。

机器可读检查关卡结果

本节是 aif-gate-result 计算的唯一依据:

  • 在可读性审查内容之后,追加一个最终的 aif-gate-result JSON 代码块。
  • 使用 "gate": "review"。
  • "status": "pass|warn|fail" —— 取两个独立输入中较严重的状态(fail > warn > pass):
    • findings 输入——只要仍有任何“Critical Issues”条目,就为 fail(关键正确性、安全性、数据丢失、性能、下游回归——权威的 critical/suggestion 定义见 references/SEVERITY.md);只有“Suggestions”、缺少可选上下文或审查不确定性时为 warn;没有实质性问题时为 pass。
    • context-gate 输入——存在阻塞性(ERROR)门禁发现时为 fail;存在非阻塞性(WARN)门禁发现时为 warn;没有时为 pass。
    • 即使没有 Critical Issues,未通过的 context gate 也会使 "status" 保持为 fail——干净的 findings 列表绝不能掩盖未通过的门禁。
  • 未解决的标记不得进入门禁。 投影预期接收不带标记的 findings:(confidence: low) / (confidence: medium) 标记须在计算门禁前由验证轮次解决——见下文“在门禁前解决标记”。Schema v1 无法表示“未经验证的潜在阻塞项”,门禁也不会尝试表达这种状态(warn + command: null 并非一种状态,而是一个 bug)。
  • 未解决的标记属于验证失败,门禁会报告失败本身。 如果计算门禁时某条带标记的 finding 仍带有标记——即验证轮次已派发但未能解决:违反单项约定、单项响应格式错误或整个派发失败(references/CHECK-MODE.md,Failure modes)——则审查尚未完成。对于因试图附加标记而遭拒的 finding 也同样如此:该条目会以原始、不带标记的形式发布,因此门禁无法从文本中看出失败,必须明确告知。无论哪种情况,都必须在机器可读字段中说明,而不能只写在 WARN [+check] 行中:
    • "status": "fail","blocking": true;
    • "blockers" 中恰好新增一个合成条目 {"id": "review-validation-failed", "severity": "error", "summary": "<N> finding(s) left unvalidated: <cause>"},并与既定阻塞项并列(见下文)。<cause> 取自 WARN [+check] 行,每条失败路径都会输出该行——若失败时原因为空,说明某条路径跳过了 WARN,这是该轮次的 bug,而不是可发布的门禁结果;
    • 仍带有标记的 findings 保留在其可读性分类中,但不属于既定阻塞项,且绝不会出现在 "blockers" 中——门禁不会猜测它们是否属实。以原始不带标记形式发布的 finding 是普通的既定 finding,会照常投影;只有合成条目会记录其验证失败;
    • "suggested_next.command" 为 null,原因需说明失败及恢复方法:重新运行 /aif-review +check。该命令不在允许列表中,因此 null 是唯一如实的取值;代码块中已是 fail + blocking,所以任何编排器都不会将 null 解读为“已解除”。
  • "blocking": true|false —— 仅当 "status" 为 fail 时,值为 true。
  • "blockers" —— 仅包含已确定的合并阻塞项:每条不带置信度标记的“Critical Issues”条目(成功完成验证轮次后,每条都符合此条件)、每条阻塞性 context-gate 发现,以及验证失败时的 review-validation-failed 条目——除此之外不包含其他内容。
  • "affected_files" —— 已审查或相关的路径。
  • "suggested_next.command" 根据 "status" 设置:fail → 默认 /aif-fix;但如果所有阻塞项都来自单个 context gate,则指向该门禁对应的命令(rules gate → /aif-rules,architecture gate → /aif-architecture,roadmap gate → /aif-roadmap);warn/pass → /aif-commit。当存在 review-validation-failed 阻塞项时,无论其他阻塞项如何,命令都为 null——对不完整的阻塞项列表执行修复轮次,会使用一份审查尚未完成的报告。null 保持其原本含义——没有适用的允许命令——且不得用于表示未解决的 finding。
在门禁前处理标记

如果审查产生了至少一个 (confidence: low) / (confidence: medium) 标记,即使未提供该标志,也会自动运行 +check 验证。除此之外,该标志仍需显式启用:没有标记的审查行为与以往完全相同,不会触发任何派发。

自动派发受能力限制,而非取决于对输入的信任。只有在运行时强制执行该 Agent 的只读工具允许列表(Read、Glob、Grep — Claude Code)时,才会以 review-validator 身份运行此流程,因为其提示词会原样嵌入差异内容,而 PR 差异是不可信内容——未显式启用标志的运行绝不能扩大被审查变更可触达的工具集。如果该 Agent 不可用,或其运行时无法强制执行允许列表(Codex Agent 获得只读沙箱,但没有工具允许列表,并会继承父级的 MCP 服务),则自动运行不会派发任何内容:它会报告整个派发失败,以及由此产生的 review-validation-failed 门禁结果。只有显式启用 +check 才能在边界较弱的情况下运行,并会在 WARN 行中说明这一点(references/CHECK-MODE.md,Procedure 第 4 步)。

  • 每个带标记的发现要么被确认——验证器返回该发现时不带标记,并将其视为所属部分的普通发现(已确认的严重问题会阻止通过,并导致 fail)——要么被驳回并删除。
  • 随后根据验证后的发现计算门禁结果,因此发布的区块绝不会包含标记,也无需使用状态架构 v1 无法表达的状态。
  • 如果流程结束后仍有未解决的标记,门禁会报告验证失败(review-validation-failed,见上文“机器可读的门禁结果”),而不会发布审查未能得出的结论。该标记会保留在面向用户的部分中,WARN [+check] 行则会说明原因。
  • 只有在原本会产生这种无法表示的状态时,才会产生派发成本。由于覆盖优先策略会有意呈现不确定的发现,而不是将其隐藏,这类运行足够常见;如果把处理工作留给用户,每次都会让流水线停滞。

流程、计数器和故障处理与显式启用 +check 完全相同(references/CHECK-MODE.md);唯一的区别是触发方式。

默认情况下,/aif-review 对上下文产物为只读。除非用户明确要求,否则不要修改上下文文件。

项目上下文

阅读 .ai-factory/skill-context/aif-review/SKILL.md — 如果该文件存在,则为必需步骤。

该文件包含 /aif-evolve 根据补丁、代码库约定和技术栈分析积累的项目专属规则。这些规则针对当前项目量身定制。

如何应用 skill-context 规则:

  • 将它们视为此技能通用指令的项目级覆盖规则
  • 如果 skill-context 规则与此 SKILL.md 中的通用规则冲突,以 skill-context 规则为准(更具体的上下文优先——这与嵌套 CLAUDE.md 文件遵循的原则相同)
  • 如果没有冲突,则同时应用:SKILL.md 中的通用规则和项目规则
  • 即使 skill-context 规则看起来与此技能的默认设置相矛盾,也不要忽略它们——这些规则的存在,是因为项目经验已证明默认设置不够充分
  • 重要: skill-context 规则适用于此技能的所有输出——包括审查摘要格式和检查清单标准。如果 skill-context 规则要求“审查必须检查 X”或“摘要必须包含 Y 部分”,就必须相应扩展输出。忽略 skill-context 规则生成审查结果属于错误。

**强制要求:**生成任何输出产物后,都要根据所有 skill-context 规则进行核验。如果违反了任何规则,就在呈现给用户之前修正输出。

发现阶段:覆盖优先于筛选

在发现阶段,你的任务是全面覆盖,而非筛选。报告你发现的每个问题,包括你不确定或认为严重性较低的问题——不要因为觉得问题很小或不完全确定,就省略某项发现。筛选会在后续阶段进行(由 +check 验证器、人工审核者或关卡的「关键问题/建议」划分负责),绝不会在这里进行。

  • 不确定的发现仍须提出——根据其影响放入相应章节,并附上明确的置信度标记(见下文「发现分类与验证边界」)。绝不能放在问题中:不确定性需要标记发现,不能成为免于验证的理由。
  • 不要为了迎合「只报告高严重性问题」/「保持保守」的要求而自我审查:全面调查,然后报告你的发现,让后续阶段进行排序。
  • 如实划分关键问题与建议(关卡会因已确认的关键问题而阻止通过)——置信度应写在发现内容中,绝不能成为省略或降级的理由。

原因:Opus 4.8 比早期模型更倾向于按字面理解「只报告重要问题」——调查深度相同,但转化为输出的发现更少。优先全面覆盖的表述有助于提高召回率;排序是单独的步骤。

发现分类与验证边界

审查输出中的每一项都只能属于一个类别。类别决定该项显示的位置,以及是否由 +check 验证:

类别显示位置是否由 +check 验证
可操作的代码发现——针对审查变更的判断:缺陷、风险或改进建议,通常标注为 file:line关键问题或建议是
上下文关卡发现——架构/路线图/规则偏差上下文关卡否
提交结构发现——提交消息的准确性或原子性(commits 模式)审查中的行内内容否
不可操作的观察——指出良好的模式正面记录否
真正悬而未决的澄清问题——本身不包含任何判断问题否

重要的不变规则:可操作的代码发现绝不会显示在「关键问题」或「建议」之外,因此只要启用了 +check,它就一定会进入验证路径。其他类别不受验证约束,因为验证器无法判定其输入内容——它接收的是经过审查的差异,而不是架构/规则材料(上下文关卡),也不是逐个提交的边界(commits 模式下的差异已被压合)。这种豁免源于验证器证据的局限,并非逃避验证的后门:任何针对变更代码的判断,无论如何措辞,都属于验证路径。

判断标准:如果某项内容对审查变更作出了可能为真或为假的断言,它就是可操作的代码发现。如果草稿中的「问题」暗含了这类断言(「X 会泄露连接,这是有意的吗?」),就将其拆开:把断言作为带有置信度标记的发现提出,只有真正尚未明确的部分才能留在「问题」中。

置信度标记

置信度与严重性是相互独立的维度:

  • 严重性决定章节——根据所述行为的影响判断,假设该发现属实。潜在的合并阻断问题即使尚不确定是否真实,也应放在「关键问题」中;已有充分依据的小问题则应放在「建议」中。
  • 置信度标记写在内容中——不确定的发现须以 (confidence: low) 或 (confidence: medium) 之一结尾。高置信度是默认值,不加标记;绝不能原样输出字符串 (confidence: low|medium)。

发布到关卡前,标记绝不会保留:标记的存在会触发验证流程(见「在关卡前处理标记」),该流程要么确认发现——返回修正后且不带标记的文本,此时它会作为所属章节中的普通发现处理——要么将其删除。因此,添加标记不会影响正确性:它如实记录不确定性,并安排后续处理,而不是降低发现的级别或将其隐藏。

审查清单

正确性
  • 逻辑错误或 Bug
  • 边界情况处理
  • Null/undefined 检查
  • 错误处理是否完整
  • 类型安全(如适用)
安全性
  • SQL 注入漏洞
  • XSS 漏洞
  • 命令注入
  • 敏感数据泄露
  • 身份验证/授权问题
  • CSRF 防护
  • 输入验证
性能
  • N+1 查询问题
  • 不必要的重新渲染(React)
  • 内存泄漏
  • 算法效率低下
  • 缺少索引(数据库)
  • 负载过大
最佳实践
  • 代码重复
  • 无用代码
  • 魔法数字/字符串
  • 命名规范是否恰当
  • SOLID 原则
  • DRY 原则
测试
  • 新代码的测试覆盖率
  • 已测试边界情况
  • 模拟是否恰当

输出格式

## Code Review Summary

**Files Reviewed:** [count]
**Risk Level:** 🟢 Low / 🟡 Medium / 🔴 High

### Context Gates
[Architecture / Rules / Roadmap gate results with WARN/ERROR labels]

### Critical Issues
[Each item is a short paragraph in prose, not a labeled record. Order inside the paragraph:
1. Behavioral impact — what breaks for the user or downstream code.
2. Optional note — a code citation, a consequence, or extra context. Include only if it adds signal; skip otherwise.
3. Path — file:line of the affected location (or the closest anchor).
4. Suggested fix — concrete edit that addresses the behavior above.

Example:
> Two clients buying the last item both get a confirmation and stock goes negative — the order creation and stock reservation run in separate transactions. `src/services/order.ts:42`. Wrap `OrderService.create` and `InventoryService.reserve` in a shared transaction so the second buyer fails fast with "out of stock".
]

### Suggestions
[Same item shape as Critical Issues. The behavioral impact describes a non-blocking improvement (clarity, performance budget, missing log), not a bug.

In either findings section, an item you are not sure about ends with a `(confidence: low)` or `(confidence: medium)` marker — the section still follows impact, not certainty (see "Findings taxonomy and the validation boundary").

Example of a marked item, sitting in Critical Issues because its impact would be merge-blocking if real:
> Retries reuse the same idempotency key after a 5xx, so a duplicate charge is possible when the provider did commit the first attempt. `src/payments/retry.ts:88`. Generate a fresh key per attempt, or record the provider's response before retrying. (confidence: medium)

The marker never reaches the published gate as a finding: it is resolved by the validation pass (see "Resolving markers before the gate") — confirmed items come back without it, refuted ones are dropped, and a marker the pass failed to resolve turns the gate into a `review-validation-failed` failure.]

### Questions
[Free-form clarifications. Path optional, fix optional — these are open questions for the author, never findings (see "Findings taxonomy and the validation boundary").]

### Positive Notes
[Free-form acknowledgements of good patterns. No path/fix required.]

当 +check 重新归类某个条目时,会在条目文本后追加简短的 [+check: …] 后缀;确切措辞请参阅 references/CHECK-MODE.md。

在 Markdown 摘要后追加最终的机器可读结果:

{
  "schema_version": 1,
  "gate": "review",
  "status": "pass",
  "blocking": false,
  "blockers": [],
  "affected_files": [],
  "suggested_next": {
    "command": "/aif-commit",
    "reason": "Review found no blocking issues."
  }
}

验证流程运行时,aif-gate-result 块会在验证器筛选完成后组装——status、blockers、affected_files 和 suggested_next 会相应重新计算。如果整个分派失败,则改用未筛选的草稿作为输入:对于不含标记的评审,会复现验证前的 gate;对于含标记的评审,则会生成 review-validation-failed gate。完整流程请参阅 references/CHECK-MODE.md。

以下是仅有的一个已标记 Critical 无法通过验证时的失败块:

{
  "schema_version": 1,
  "gate": "review",
  "status": "fail",
  "blocking": true,
  "blockers": [
    {
      "id": "review-validation-failed",
      "severity": "error",
      "summary": "1 finding left unvalidated: validator response for item 1 violated the marked-item contract"
    }
  ],
  "affected_files": ["src/payments/retry.ts"],
  "suggested_next": {
    "command": null,
    "reason": "Validation of the marked finding failed, so the review is incomplete and no blocker verdict exists for it. Re-run /aif-review +check."
  }
}

评审风格

  • 提供建设性意见,而非批评
  • 说明建议背后的原因
  • 有帮助时提供代码示例
  • 肯定优秀代码
  • 按重要性排序反馈,但绝不要遗漏低严重性问题;将其作为 Suggestions 提出(参见“发现阶段:覆盖优先于过滤”)
  • 提问,而非妄加假设

示例

用户: /aif-review 评审当前仓库中已暂存的更改。

用户: /aif-review 123 使用 GitHub CLI 评审 PR #123。

用户: /aif-review https://github.com/org/repo/pull/123 评审 URL 中的 PR。

用户: /aif-review 2.x 评审当前分支相对于分支 2.x 的所有提交。

用户: /aif-review main 评审当前分支相对于 main 的所有提交(或者相对于此仓库中 git.base_branch 配置的分支)。

用户: /aif-review v1.0.0 评审当前分支相对于标签 v1.0.0 的所有提交。

用户: /aif-review +check 评审已暂存的更改,然后在渲染前对 Critical Issues 和 Suggestions 运行 +check 验证器。验证器可以删除凭空捏造的条目、改写部分正确的条目,以及在两个严重性级别之间重新归类条目(将建议提升为 critical,或将 critical 降为建议——规则请参阅 references/SEVERITY.md)。它会添加一行筛选摘要,并根据保留下来的发现重建 gate 结果;确切的行格式请参阅 references/CHECK-MODE.md。

用户: /aif-review 123 +check 评审 PR #123,并启用 +check 验证。

集成

如果已配置 GitHub MCP,可以:

  • 直接在 PR 中发布评审评论
  • 请求更改或批准
  • 根据评审结果添加标签

提示: 代码评审后会占用大量上下文。继续其他任务前,可考虑使用 /clear 或 /compact。

评论

支持 Markdown