基于 Claude Code 官方 code-review plugin 改造,适配 Cursor Skill 体系,实现多模型并行代码审查。
1. 背景与动机
之前我同时试用了 obra/superpowers 的 receiving-code-review skill 和 Claude Code 的 code-review。感觉 code-review 的设计更现代化。
Claude Code 官方的 code-review plugin 在这方面做了一个值得学习的设计:用 5 个独立 Agent 从不同角度并行审查,再用置信度评分过滤误报。这个思路比单次 prompt 审查要靠谱得多。同时,多 Agent 编排本身也是一个值得学习的模式——了解 subagent 的调度机制,看看能否在日常开发中用它来节约成本。
但这个 plugin 有一个实际限制:它绑定了 Claude 的特定模型(Haiku 做轻量任务、Sonnet 做审查),不能换成其他模型。而我的需求恰恰是多模型 CR——用不同厂商的模型审查同一份代码,取长补短。之前某个功能开发结束后,Gemini Pro 就发现了 Codex 和 Opus 都没发现的问题,这说明不同模型确实有不同的审查盲区。
于是思路就很自然了:基于 Claude Code 的 code-review plugin 改造,迁移到 Cursor 的 Skill 体系,移除 Claude 特定的模型绑定,使其能在 Cursor 中配合任意模型使用。
2. 从 Plugin 到 Skill 的迁移
迁移不是简单的复制粘贴。Claude Code plugin 和 Cursor Skill 是两套不同的体系,需要逐层适配。
2.1 平台概念映射
原版 plugin 中有一些 Claude 特有的概念,需要找到 Cursor 中的对应物:
| Claude Code Plugin | Cursor Skill | 说明 |
|---|---|---|
CLAUDE.md |
AGENTS.md + .cursor/rules/ |
项目规范文件,Cursor 支持层级目录 |
| Haiku Agent | 轻量(fast)模型 Agent | 用于收集信息、打分等低成本任务 |
| Sonnet Agent | 继承(默认)模型 Agent | 用于核心审查任务 |
commands/code-review.md |
skills/cursor-code-review/SKILL.md |
入口文件,Skill 需要 YAML frontmatter |
2.2 功能裁剪
原版 plugin 面向 GitHub PR 场景,有几个功能在本地多模型 CR 中不适用,直接移除:
- PR 资格检查(Step 1):原版会先用 Haiku 检查 PR 是否为 draft、已关闭、已审查过等。本地场景不需要。
- PR 评论发布(Step 8):原版最终通过
gh pr comment把审查结果发到 GitHub。本地场景改为直接输出到会话。 - PR 评论审查 Agent(原 Agent #4):原版有一个 Agent 专门读 PR 历史评论来发现问题。本地没有这个数据源。
2.3 文件引用格式
原版生成 GitHub 风格的链接(带完整 SHA 和行号范围的 URL),在 Cursor 中无法点击跳转。改为 Cursor 代码引用块格式:
# 原版(GitHub 链接)
https://github.com/user/repo/blob/abc123/src/auth.ts#L67-L72
# 改造后(Cursor 代码引用块)
```67:72:src/auth.ts
// 对应的代码内容
这个格式在 Cursor 中可以直接点击跳转到对应文件和行号。
### 2.4 Plugin → Skill 格式转换
Claude Code plugin 使用 `plugin.json` + `commands/*.md` 的目录结构。Cursor Skill 使用单个 `SKILL.md` 文件加 YAML frontmatter:
```yaml
---
name: cursor-code-review
description: 通过多 Agent 并行审查和置信度评分...
disable-model-invocation: false
---
disable-model-invocation: false 是关键配置——它允许 Skill 在执行过程中调用模型创建 subagent,这是多 Agent 编排的前提。
3. 多 Agent CR 架构设计
整个审查流程分为 6 个步骤,核心思路是:轻量任务用 fast 模型省成本,核心审查用默认模型保质量,能并行的步骤全部并行。
3.1 整体流程
Step 1: [fast] 收集规范文件路径
Step 2: [fast] git diff 变更摘要
↓
Step 3: [默认模型 x5 并行] 独立审查
├─ Agent #1: 规范合规检查
├─ Agent #2: 规范合规检查(冗余)
├─ Agent #3: 明显 Bug 扫描
├─ Agent #4: git blame 历史分析
└─ Agent #5: 代码注释指导检查
↓
Step 4: [fast x N 并行] 每个问题独立打分
↓
Step 5: 按置信度分组
Step 6: 格式化输出
Step 1 和 Step 2 是准备阶段,用 fast 模型完成两件事:列出项目规范文件(AGENTS.md、.cursor/rules/)的路径,以及通过 git diff 生成变更摘要。这两个任务不需要强推理能力,fast 模型足够。
3.2 五路并行审查
Step 3 是核心,5 个使用默认模型的 Agent 并行执行,各自独立返回问题列表:
Agent #1 和 #2(规范合规):都做同一件事——检查变更是否符合 AGENTS.md 和 .cursor/rules/ 中的规范。独立执行相当于交叉验证,项目规范文件分散在根目录和各层级子目录,单个 Agent 可能遗漏某些规则。原版只有 1 个规范检查 Agent,空出的槽位(原 PR 评论 Agent)用来做冗余。
Agent #3(Bug 扫描):只看变更本身,不读额外上下文。这是刻意的设计——避免 Agent 被周围代码干扰,聚焦于变更引入的明显 Bug。同时也避免把已有问题标记为新问题。
Agent #4(历史分析):通过 git blame 和文件历史记录,在上下文中理解变更。比如某段代码之前被反复修改过,这次的改动可能踩到同样的坑。
Agent #5(注释指导):检查代码注释中是否有被忽略的指导。比如注释写了 // TODO: 需要处理边界情况,但变更没有处理。
4. 置信度评分的改造
置信度评分是整个流程中控制信噪比的关键环节。原版的评分体系设计得不错,但阈值和处理策略需要调整。
4.1 评分标准(沿用原版)
Step 4 中,每个问题由一个独立的 fast Agent 打分,标准如下:
| 分数 | 含义 |
|---|---|
| 0 | 完全没有信心,明显误报或已有问题 |
| 25 | 有一定信心,可能是真实问题也可能是误报,无法验证 |
| 50 | 中等信心,能验证是真实问题,但可能是细节挑剔 |
| 75 | 高度确信,复核后确认是实际会遇到的真实问题 |
| 100 | 绝对确定,证据直接证实 |
打分 Agent 会重新审视问题,对于规范相关的问题还会二次确认规范文件是否明确提及。这相当于又加了一层过滤。
4.2 阈值从 80 降到 50
原版阈值设为 80,低于 80 的问题直接丢弃。这在 Claude Code 的场景下可能合理——它用的是固定的 Claude 模型,评分行为相对可预期。
但在多模型场景下,80 太严格了。原因有两个:
- 不同模型的评分尺度不同。同一个问题,某些模型可能打 60,另一些打 85。阈值 80 在某些模型上会漏掉大量有价值的中等信心问题。
- 放宽阈值不容易漏东西。降到 50 意味着只过滤掉”大概率是误报”的问题(0 和 25 分),真正有价值的问题更不容易被遗漏。
4.3 低置信度不再丢弃
这是比调阈值更重要的改动。原版对低于阈值的问题一律丢弃,改造后改为分层展示:
- 高置信度(>=50):作为主要问题详细展示,包含问题描述、代码引用、标记原因
- 低置信度(<50):不丢弃,而是以一行摘要的形式列在末尾的”其他待关注”部分
这样做的好处是:开发者可以快速浏览低置信度问题,自行判断是否需要关注。有时候模型不确定的问题,开发者一眼就能看出来是不是真的。信息展示了但不干扰主要审查流程。
5. Cursor SubAgent 的现状与限制
这部分是踩坑最多的地方,也是对其他想在 Cursor 中做多 Agent 编排的开发者最有参考价值的部分。
5.1 模型选择的限制
Cursor 在动态创建 subagent 时,目前只支持两种模型选择:
- 继承模型:使用主会话当前选择的模型
- fast 模型:使用平台提供的轻量模型
无法在 Skill 中动态指定具体模型(比如”这个 Agent 用 GPT-4o,那个用 Gemini Pro”)。这意味着最初设想的”不同 Agent 用不同模型审查”在动态创建 subagent 的方式下无法实现。
如果需要指定具体模型,必须在 .cursor/agents/ 目录下以文件形式预定义 Agent,而不能在 Skill 执行过程中动态创建。
5.2 fast 模型创建的稳定性问题
实测发现,动态创建 fast 模型 subagent 的成功率依赖于主会话使用的基模型。目前只有在使用 Opus 4.6 时能稳定启动 fast 模型 Agent。其他模型作为主会话时,创建 fast subagent 可能失败,失败后 subagent 会静默回退为继承主会话模型——这意味着你以为在用 fast 模型省成本,实际上跑的是完整模型。
5.3 Skill 的模型理解问题
Skill 功能目前还比较新,模型对 Skill 的配置项理解不够准确。有些配置在文档中明确存在,但模型在执行时认为没有这个功能,需要手动把相关文档喂给模型才能正确执行。
这在调试阶段尤其耗时——你不确定是 Skill 写法有问题还是模型没理解对。
5.4 跨平台兼容性建议
由于各家工具和模型的实现差异较大,如果你也想做类似的多 Agent 编排 Skill,建议先针对单个工具开发和调试,确认在目标平台上稳定运行后再考虑通用化。直接写一个”通用”的编排 Skill 在多个平台上跑,大概率会在每个平台上都遇到不同的问题。
6. 实际效果与总结
6.1 多模型 CR 确实有效
在实际使用中,不同模型审查同一份代码的互补效果明显。之前某个功能开发结束后,Gemini Pro 发现了 Codex 和 Opus 都没发现的问题。这验证了最初的假设——不同模型有不同的审查盲区,多模型交叉审查能提高问题检出率。
置信度分层展示也比原版的直接丢弃更实用。低置信度部分偶尔会出现开发者一眼就能确认的真实问题,这些在原版 80 阈值下会被丢弃。
6.2 Skill 的编写思路
通过这次改造,总结出一些编写 Cursor Skill 的思路:
分层使用模型。不是所有任务都需要最强的模型。信息收集、评分这类结构化任务用 fast 模型即可,核心推理任务用默认模型。这在成本和质量之间取得了平衡。
并行优于串行。Skill 中如果有多个独立任务,应该尽量并行执行。5 个审查 Agent 并行跑和串行跑,总耗时差距很大。
给模型明确的评分标准。置信度评分之所以有效,是因为给了 Agent 非常具体的评分标准(0/25/50/75/100 各自的含义),而不是模糊地说”打个分”。这个经验适用于任何需要模型做判断的场景。
误报过滤需要多层设计。单靠 prompt 说”不要误报”效果有限。这套方案用了三层:审查 Agent 自身的误报意识(prompt 中列出 8 类误报场景)、独立的置信度评分 Agent 复核、阈值过滤 + 分层展示。
适配平台特性而非对抗。迁移过程中最顺利的部分是顺着 Cursor 的设计来(用 AGENTS.md 替代 CLAUDE.md、用代码引用块替代 GitHub 链接),最痛苦的是试图突破平台限制(动态指定模型)。
SKILL.md
---
name: cursor-code-review
description: 通过多 Agent 并行审查和置信度评分,对当前分支的代码变更进行自动化审查,检查项目规范合规性、明显 Bug、历史上下文问题和代码注释指导。适用于用户要求代码审查、review 代码变更、检查代码质量,或在提交前进行变更验证时使用。
disable-model-invocation: false
---
对当前分支的代码变更进行审查。
请严格按照以下步骤执行:
1. 使用一个轻量 Agent 提供代码库中所有相关项目规范文件的路径列表(不包括文件内容):根目录及各层级目录的 `AGENTS.md` 文件(如果存在),以及 `.cursor/rules/` 目录下的规则文件。
2. 使用一个轻量 Agent 通过 `git diff` 查看当前变更,并让该 Agent 返回变更摘要。
3. 然后,启动 5 个并行的使用默认模型的审查 Agent 独立进行代码审查。每个 Agent 应执行以下任务,然后返回问题列表及每个问题被标记的原因(例如项目规范合规性、Bug、历史 git 上下文等):
a. Agent #1:审计变更以确保它们符合项目规范(`AGENTS.md` 和 `.cursor/rules/`)。注意项目规范是 AI 编写代码时的指导,因此并非所有指令都适用于代码审查。
b. Agent #2:独立于 Agent #1,再次审计变更的项目规范合规性。与 Agent #1 采用相同的审计标准,但独立执行以提高检出率。
c. Agent #3:阅读变更的文件内容,然后进行浅层扫描以发现明显的 Bug。避免阅读变更之外的额外上下文,仅关注变更本身。聚焦于重大 Bug,避免小问题和细节挑剔。忽略可能的误报。
d. Agent #4:阅读被修改代码的 git blame 和历史记录,在历史上下文的基础上识别任何 Bug。
e. Agent #5:阅读被修改文件中的代码注释,确保变更符合注释中的任何指导。
4. 对于步骤 3 中发现的每个问题,启动一个并行的轻量 Agent,将问题描述和项目规范文件列表(来自步骤 1)传入,让其返回一个分数来表示该问题是真实问题还是误报的置信度。为此,Agent 应对每个问题按 0-100 的比例进行评分,表示其置信度。对于因项目规范而被标记的问题,Agent 应再次确认规范文件是否确实明确指出了该问题。评分标准如下(将此评分标准原样提供给 Agent):
a. 0:完全没有信心。这是一个经不起轻微审视的误报,或者是一个已有的问题。
b. 25:有一定信心。这可能是一个真实问题,但也可能是误报。Agent 无法验证它是否是真实问题。如果该问题是风格相关的,它并未在相关项目规范中被明确指出。
c. 50:中等信心。Agent 能够验证这是一个真实问题,但它可能是细节挑剔或在实践中不太会经常发生。相对于其他变更,它不是很重要。
d. 75:高度确信。Agent 复核了该问题,并验证它很可能是一个在实践中会遇到的真实问题。现有的方案不够充分。该问题非常重要且会直接影响代码功能,或者它是相关项目规范中明确提到的问题。
e. 100:绝对确定。Agent 复核了该问题,并确认它绝对是一个真实问题,在实践中会频繁发生。证据直接证实了这一点。
5. 将问题按置信度分为两组:
- 高置信度(≥50):作为主要问题详细展示
- 低置信度(<50):作为补充信息以简短摘要列在末尾
如果两组都没有问题,则直接告知用户未发现问题。
6. 将审查结果直接输出给用户。输出时请注意:
a. 保持输出简洁
b. 避免使用 emoji
c. 引用相关代码和文件路径
d. 高置信度问题详细展示,低置信度问题每条仅用一行摘要
以下是步骤 3 和 4 的误报示例:
- 已有的问题
- 看起来像 Bug 但实际不是 Bug 的代码
- 资深工程师不会指出的吹毛求疵的细节
- Linter、类型检查器或编译器会捕获的问题(例如缺少或不正确的导入、类型错误、损坏的测试、格式问题、诸如换行之类的吹毛求疵的风格问题)。无需自行运行这些构建步骤——可以安全地假设它们会作为 CI 的一部分单独运行。
- 通用的代码质量问题(例如缺少测试覆盖、一般性安全问题、文档不完善),除非在项目规范中明确要求
- 在项目规范中被指出但在代码中被明确静默的问题(例如由于 lint ignore 注释)
- 可能是有意为之的功能变更,或与更广泛的变更直接相关的变更
- 真实问题,但出现在用户未修改的行上
注意事项:
- 不要检查构建信号或尝试构建或类型检查应用。这些将单独运行,与你的代码审查无关。
- 首先制定待办事项列表
- 你必须引用每个问题对应的文件和代码位置(例如如果引用项目规范,你必须说明具体是哪个规范文件的哪条规则)
- 最终输出请遵循以下格式(以下示例假设你发现了 3 个问题):
---
### 代码审查
发现 3 个问题:
1. <问题的简要描述>(AGENTS.md 和 .cursor/rules/ 要求"<...>")
```X:Y:path/to/file.ts
<对应的代码内容,至少包含 1 行>
```
2. <问题的简要描述>(子目录下的 AGENTS.md 和 .cursor/rules/ 要求"<...>")
```X:Y:path/to/file.ts
<对应的代码内容,至少包含 1 行>
```
3. <问题的简要描述>(Bug 原因:<文件和代码片段>)
```X:Y:path/to/file.ts
<对应的代码内容,至少包含 1 行>
```
其他待关注(低置信度):
- <一句话描述>
```X:Y:path/to/file.ts
<对应的代码行,至少包含 1 行>
```
---
- 如果没有低置信度问题,则省略"其他待关注"部分。
- 如果没有高置信度问题但有低置信度问题,则省略编号列表,仅展示"其他待关注"部分。
- 如果两者都没有:
---
### 代码审查
🤖 Generated with <请在这里填写模型名称>
未发现问题。已检查 Bug 和 (AGENTS.md 和 .cursor/rules/) 项目规范合规性。
---
- 引用代码时,使用 Cursor 代码引用块格式以支持点击跳转。格式为三个反引号开头,紧跟 `起始行:结束行:文件路径`,代码块内包含实际代码:
- 使用相对于仓库根目录的路径
- 行号格式为 `起始行:结束行`(例如 `67:72:src/auth/oauth.ts`)
- 如果只涉及单行,起始行和结束行相同(例如 `23:23:src/utils.ts`)
- 代码块内必须包含至少 1 行实际代码内容
- 提供至少 1 行前后上下文,以你评论的行为中心(例如如果你评论的是第 5-6 行,应引用 `4:7:path/to/file.ts`)