关于 aif-review
aif-review 是面向开发者的代码审查技能,关注正确性、安全性、性能和可维护性。它可审查暂存或未暂存改动、拉取请求及提交,并可验证不确定的发现。
主要功能
- 01检查正确性、安全性、性能和可维护性
- 02审查暂存或未暂存的改动
- 03按编号或 URL 审查拉取请求
- 04比较 Git 引用之后的提交
- 05通过可选验证检查发现
适用场景
- 01提交前审查代码改动
- 02评估拉取请求中的变更
- 03检查指定 Git 引用之后的提交
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lee-to/ ai-factory --skill aif-review安装后在 Claude Code 中输入/aif-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/CHECK-MODE.mdSEVERITY.mdVALIDATOR.mdtests/check-mode-happy-path.spec.yamlcheck-mode-validator-failure.spec.yamlcheck-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,则该名称会被标记提取器移除——这是可以接受的权衡。
无参数(审查暂存更改)
- 运行
git diff --cached获取暂存的更改 - 如果没有暂存内容,则运行
git diff获取未暂存的更改 - 分析每个文件的更改
使用 PR 编号/URL
- 使用
gh pr view <number> --json获取 PR 详情 - 使用
gh pr diff <number>获取差异 - 审查 PR 中的所有更改
使用 Git 引用(提交模式)
参数路由流程:
- 空 → 暂存更改审查(见上文)
- 数字或
#N→ PR 模式(见上文) - 其他所有内容 → 使用
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 编号——这是可以接受的权衡。
步骤:
-
获取引用与 HEAD 之间的提交列表:
git log --oneline --reverse <ref>..HEAD如果没有找到提交(HEAD 与
<ref>相同或早于<ref>),请告知用户并停止。 -
检查提交数量: 如果超过 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 个提交(保持时间顺序)
- “取消” → 告知用户审查已取消 → 停止
-
审查每个提交:
git show <commit-hash> --stat git show <commit-hash>对每个提交检查:
- 提交消息是否与实际更改相符?
- 更改是否为原子操作(每个提交包含一个逻辑单元)?
- 该提交引入了哪些问题?
-
提供综合摘要,并附上每个提交的备注
上下文检查关卡(只读)
最终确定审查发现之前,运行只读上下文检查关卡:
- 检查已解析的架构文档(如果存在),查看是否存在边界/依赖对齐问题。
- 检查已解析的 RULES.md 文档(如果存在),查看是否违反明确的约定。
- 检查已解析的路线图文档(如果存在),查看是否与里程碑对齐,并指出可能属于
feat/fix/perf工作但缺少关联的情况。
人工检查关卡结果严重程度:
- 对于非阻塞性不一致或缺少可选文件,使用
WARN。 - 仅在用户/审查政策要求的明确阻塞条件下使用
ERROR。
如果用户希望单独进行仅规则检查,建议使用 /aif-rules-check。人工 /aif-review 检查关卡标签保持为 WARN / ERROR,然后附加标准机器可读检查关卡结果,状态使用 pass|warn|fail。
机器可读检查关卡结果
本节是 aif-gate-result 计算的唯一依据:
- 在可读性审查内容之后,追加一个最终的
aif-gate-resultJSON 代码块。 - 使用
"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 输入——只要仍有任何“Critical Issues”条目,就为
- 未解决的标记不得进入门禁。 投影预期接收不带标记的 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。