# 代码审查

> 如果没有未提交的更改，/review 会提示并停止——不会启动任何 agent。

- 网址：https://funcoding.ai/agents/qwen-code/users/features/code-review/
- 来源：Qwen Code 官方文档原文（中文），Apache-2.0 许可，同步于 2026-10-11
- 官方原文：https://qwenlm.github.io/qwen-code-docs/zh/users/features/code-review

---
> 使用 `/review` 审查代码变更的正确性、安全性、性能和代码质量。

## 快速开始

```bash
# 审查本地未提交的更改
/review

# 审查 pull request（通过编号或 URL）
/review 123
/review https://github.com/org/repo/pull/123

# 审查并在 PR 上发布行内评论
/review 123 --comment

# 审查本地更改并将发现应用到工作树
/review --fix

# 继续同一 PR 被中断的审查，而不是重新开始
/review 123 --resume

# 审查特定文件
/review src/utils/auth.ts

# 快速未验证扫描（无 subagent）
/review --effort low
/review 123 --effort medium
```

如果没有未提交的更改，`/review` 会提示并停止——不会启动任何 agent。

## Effort 级别

`--effort low|medium|high` 在深度和速度之间权衡：

| 级别     | 运行内容                                                                                                                                                   | 发现上限            | 结论                                     | 是否发布到 PR    |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----------------------------------- | ---------------- |
| `low`    | 3-6 个针对 diff 的定向行内角度（按 diff 大小缩放）加上 gap sweep 和 under-floor re-pass——无 subagent，无构建/测试，无项目规则                             | 10（未验证）     | 无                                | 从不            |
| `medium` | high 流水线减去最昂贵的 pass：在缩减的维度集上进行并行 finder fan-out，加上构建/测试和单次验证 pass | 无上限（已验证） | Approve 上限为 Comment           | 从不            |
| `high`   | 完整流水线：最多 16 个并行 agent → 分片验证 → 迭代反向审计                                                                    | 无上限（已验证） | Approve / Request changes / Comment | 使用 `--comment` 时 |

`/review` 按以下顺序解析 effort：显式的 `--effort`、该项目上次明确输入的级别、操作员的 `review.effort` 设置，然后是内置的目标默认值（PR 审查为 **high**，本地和文件审查为 **medium**）。当记忆的级别生效时，`/review` 会在开始工作前宣布它；输入新的 `--effort` 可以替换它。有效的 `--comment` 会强制使用 high（发布的评论必须通过验证）——在非 PR 目标上 `--comment` 会被忽略并发出警告，**不会**更改 effort。Medium 保留了安全性和测试覆盖率 agent 以及构建/测试，但去掉了对手角色、语言陷阱和 wrapper/proxy 专家（Agent 1d/1e）、diff 专家 finder 和反向审计——因此只有第二次审查才能发现的微妙 Critical 可能会漏掉；对安全性敏感或发布前的审查请使用 `--effort high`。只有 `low` 是未验证的。Worktree 隔离适用于同仓库 PR 审查；跨仓库 PR 以轻量模式运行（仅 diff，无 worktree 或构建/测试）。Low pass 标记为未验证，不发出结论，也不写入增量审查缓存，因此后续的 `--effort high` 运行不会被跳过为"已审查"；medium 是已验证的，但其 Approve 上限为 Comment，因为没有对第一次 pass 遗漏的内容进行二次审查。获取 diff 的机制在每个级别都相同——PR 审查始终使用隔离的 worktree 和相同的 base 解析，因此审查永远不会针对错误的 base。一个范围差异仍然存在：增量缓存仅用于 high，因此 high 重新审查可能只覆盖新的 commit（`lastCommitSha..HEAD`），而 low/medium 始终审查完整的 PR diff。

## 工作原理

`/review` 命令运行一个多阶段流水线：

```
步骤 1：  确定范围 + effort 级别（本地 diff / PR worktree / 文件）
          将 diff 捕获到文件 + 将其分割为 chunk
步骤 2：  加载项目审查规则（medium/high）
步骤 3C：low effort：3-6 个行内角度 + gap sweep + under-floor re-pass
                                                               [0 次 subagent 调用]
步骤 3A：high，<=500 行源码且 <=3200 行总计：最多 16 个 agent  [16+ 次 LLM 调用]
           |-- Agent 0：Issue 保真度与根因归属
           |-- Agent 1a：正确性——逐行扫描
           |-- Agent 1b：正确性——已移除行为审计
           |-- Agent 1c：正确性——跨文件追踪器
           |-- Agent 1d：正确性——语言陷阱扫描
           |-- Agent 1e：正确性——wrapper/proxy 路由
           |     （仅在 diff 信号为 wrapping 类型时启用）
           |-- Agent 2：安全性
           |-- Agent 3a：复用与重复
           |-- Agent 3b：层次与抽象适配
           |-- Agent 3c：一致性与清晰度
           |-- Agent 4：性能与效率
           |-- Agent 5：测试覆盖率
           |-- Agent 6：无导向审计（3 个角色：6a/6b/6c）
           |-- Agent 8：Diff 专家 finder（0-2 个，仅在
           |     diff 领域需要时启用）
           '-- Agent 7：构建与测试（运行 shell 命令）
步骤 3B：high，>500 行源码或 >3200 行总计：territory × 维度   [N+5..7+3H 次调用]
           （N 个 chunk，5-7 个全 diff agent，每个重写较多的
            源文件 H 有 3 个不变量 agent）
           |-- 每 ~400 行 diff 1 个 chunk agent（所有维度，
           |     仅限其 territory，返回覆盖收据）
           |-- 每个大幅重写的源文件有 3 个不变量 agent
           |     （整个文件；state/timer、counter/
           |      return/error、config/early-return）
           |-- Agent 0：Issue 保真度      （整个 diff）
           |-- Agent 7：构建与测试        （整个仓库）
           |-- Agent 1b：已移除行为   （整个 diff——
           |     跨 chunk 的一半；chunk 保留本地一半）
           |-- Agent 1c：跨文件追踪器  （整个 diff）
           |-- Agent 8：专家 finder（整个 diff，0-2 个）
           '-- 测试覆盖矩阵         （整个 diff）
步骤 4：  去重 --> 分片验证（每个 <=8 个发现）
           --> 聚合                    [ceil(F/8) 次调用，F=发现数]
步骤 5：  迭代反向审计，按 chunk fan-out；
          连续 2 轮无新发现后停止（上限 10/5/3 按拓扑）
步骤 6：  展示发现 + 结论（high；low pass：仅发现）
          规范化发现 -> .qwen/tmp/...-findings.json
步骤 6B：应用发现 + 记录每个发现的结果（仅 --fix）
步骤 7：  提交 PR 审查（行内评论，如请求；仅 high）
步骤 8：  保存报告 + 增量缓存（缓存：仅 high）
步骤 9：  清理（移除 worktree + 临时文件）
```

步骤 3A/3B/4/5 是 high-effort 流水线；在 `--effort low|medium` 下，单个行内 pass（步骤 3C）替代它们。

### 审查 Agent

| Agent                             | 关注点                                                                                                                                                                                                                                                                                           |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Agent 0：Issue 保真度           | 关联 issue 证据、根因归属，以及 PR 是否解决了报告的问题                                                                                                                                                                                                     |
| Agent 1a：逐行扫描       | 遍历每个 hunk 及其所在函数：错误条件、边界差一、缺失 `await`、边界情况、竞态条件                                                                                                                                                  |
| Agent 1b：已移除行为审计  | 遍历每行被删除/替换的代码：指出其强制的不变量，并寻找新代码在哪里重新建立了它——包括被移除的 **export**，其替代通常位于另一个文件且悄悄更改了默认值。在 3B 中以整个 diff 运行（chunk agent 保留本地一半） |
| Agent 1c：跨文件追踪器       | 遍历每个已更改符号的调用方（consumer 方向）和每个新增字段的读取位置（producer 方向），以及同一 PR 内的被调用方变更                                                                                                                                                  |
| Agent 1d：语言陷阱扫描   | 携带该 diff 所用语言的经典陷阱检查清单（`==` 强制转换、falsy 值陷阱、循环变量捕获、可变默认参数、nil-map 写入、SQL 拼接、DST 算术运算），并对每个 hunk 进行模式匹配                                                          |
| Agent 1e：Wrapper/proxy 路由   | 对于 diff 中新增或修改的每个包装其他类型的类型（cache、proxy、decorator、adapter）：每个方法都通过被包装的实例路由，且 wrapper 转发了调用者使用的每个方法。仅在 diff 信号为 wrapping 类型时启用                                        |
| Agent 2：安全性                 | 注入、XSS、SSRF、认证绕过、敏感数据泄露                                                                                                                                                                                                                                      |
| Agent 3a：复用与重复     | 代码库中是否已有此功能？搜索该行为，指出应调用的现有 helper，并标记 diff 遗留的死代码                                                                                                                                              |
| Agent 3b：层次与抽象  | 修复是否在正确的深度——还是在共享基础设施上贴创可贴、为上游 bug 做下游补偿，或创建只服务一个调用点的抽象？                                                                                                                                  |
| Agent 3c：一致性与清晰度   | 兄弟一致性（一个并行族成员有而其对应成员没有的 guard）、与引用的本地示例不一致的惯例偏移、误导性名称/注释、不必要的复杂性                                                                                                            |
| Agent 4：性能与效率 | N+1 查询、内存泄漏、不必要的重渲染、包体积                                                                                                                                                                                                                                  |
| Agent 5：测试覆盖率            | diff 中未测试的代码路径、缺失的分支覆盖、薄弱的断言                                                                                                                                                                                                                       |
| Agent 6：无导向审计         | 3 个并行角色（攻击者 / 凌晨 3 点 oncall / 维护者）——捕捉跨维度问题——以及 counter-frame 审计（6d，PR 目标 high effort）：仅读取 PR 描述以**排除**其提名的主题，并在合并次日重放其动机事件 |
| `prose-exec`：Prose 执行      | 当 diff 触及指令文件（`SKILL.md`、`AGENTS.md`/`CLAUDE.md`/`QWEN.md`、agent 或命令定义、`prompts/` 文件）且审查有工作树时：在一次性副本中**执行**更改后的指令，并记录运行结果与 prose 承诺之间的差距  |
| Agent 7：构建与测试             | 运行构建和测试命令，报告失败                                                                                                                                                                                                                                                  |
| Agent 8：Diff 专家 finder | 每次审查根据 diff 集中在具有已知失败模式的领域（重连逻辑、模块加载器、调度器、编解码器）时编写 0-2 个额外 finder                                                                                                                                                                                                      |
| `prose-exec`：Prose 执行     | 当 diff 触及指令文件（`SKILL.md`、`AGENTS.md`/`CLAUDE.md`/`QWEN.md`、agent 或命令定义、`prompts/` 文件）且审查有工作树时：在一次性副本中**执行**更改后的指令，并记录运行结果与 prose 承诺之间的差距  |

三个正确性 agent 是**程序化的**：每个由其遍历 diff 的方式定义（逐行 / 已删除行 / 跨文件边），而非由 bug 分类法定义——因此它们的覆盖是互补的而非重叠的。另外两个专用角度（1d/1e）将语言陷阱检查清单和 wrapper/proxy 路由从逐行遍历中分离出来：清单模式匹配和结构性路由预期是不同的注意力模式，折叠到逐行遍历中会被其节奏稀释。同样的推理将**代码质量拆分为三个**（3a/3b/3c）：一个持有六项检查清单的 agent 完成了一项——在大幅重写的文件上衡量，一个持有八项检查清单的 agent 发现了 5 个缺陷中的 1 个，而同一模型分三路后找到了全部 5 个——因此质量清单在问题真正不同的地方被切割。所有 agent 并行运行（Agent 1 启动 3 个程序化变体和 2 个专用角度，Agent 3 启动 3 个清单切片，Agent 6 启动 3 个角色变体和 counter-frame 审计 6d 并发执行，同仓库 PR 审查共计最多 17 个并行任务——Agent 1e 仅在 diff 信号为 wrapping 类型时启用——加上 diff 领域需要时的 0-2 个 Agent 8 finder——因此实际为 16-19 个；Agent 0 在本地 diff 和文件路径审查中跳过，运行 15-17 个；跨仓库轻量模式还跳过 Agent 1c 和 7，带 PR 标识时运行 14-17 个，不带时运行 12-15 个）。

每个发现必须说明一个**失败场景**——触发它的具体输入、状态或时序，以及导致的错误结果（对于质量发现，则是具体的代价）。无法说明其场景的发现会在源头被丢弃，验证会通过真实代码重新追踪所声称的场景，而非判断发现的文字描述。

一旦 PR 的**源码**变更超过 500 行——或总 diff 行数超过 3,200 行，超过此限度后十五个全 diff 阅读器各自过于稀释而无法仔细阅读（这是一个注意力边界，而非更少调用的承诺——重写较多的文件和专家 finder 可能使 3B 花费更多）——这种维度 fan-out 会被**territory × 维度** fan-out 替代：diff 被分割为约 400 行的 chunk——边界落在 hunk 边界上，太大的 hunk 仅在顶层声明处分割，永远不会在函数内部——每个 chunk 获得自己的 agent，将每个审查维度仅应用于该 chunk。

该门控故意计算源码行数而非 diff 行数。测试代码、文档和 lockfile 占据了 diff 的大部分——在此仓库最近 40 个合并的 PR 中，中位数 diff 有 41% 是测试——因此基于原始大小的门控会将 173 行的生产代码变更分割为 territory，仅仅因为它附带了 489 行新测试，使该生产代码只有一个审查者而非十四个视角（读取 diff 的维度 agent——十六个减去 Issue 保真度和构建与测试）。无论如何分 chunk 都覆盖每一行，包括测试；门控决定的是有多少审查者以及每个审查者的任务。十四个读取 diff 的视角都走一个大 diff 会将相同的前几个 hunk 读十四遍；每个 chunk 一个 agent 意味着 diff 的每一行恰好有一个负责的审查者。每个 chunk agent 返回一个 `Covered:` 收据，没有收据的 chunk 会在运行继续前被重新审查——因此"无阻塞问题"永远不可能对无人阅读的代码报告。

一个被大幅重写的**源码**文件（300+ 行的现有文件中 40%+ 是新内容，或有 800+ 行变更）还会获得**三个全文件不变量 agent**。测试和生成的文件永远不符合条件——检查清单询问的是字段、timer 和错误分类，而重写后的测试文件没有这些。其 bug 通常不在任何单个 hunk 内部，而在_新行之间_——文件顶部附近设置的 timer 和两千行以下的 teardown 路径。每个 agent 阅读整个变更后的文件并遍历固定检查清单的两到三项：每个退出路径都清除的可变字段、每个关闭都取消的 timer（且取消不会丢弃已捕获的数据）、map 插入与删除匹配、每次入口都递增的重试计数器、实际被检查的状态返回值、穷举分类为永久性与暂时性的错误代码、每条路径都遵循的 config 字段，以及跳过必需副作用的 early return。

检查清单故意分三路。让一个 agent 对 2,400 行的文件执行全部八项检查只能做好其中一项；三个 agent 各执行两到三项检查则全部完成。Chunk agent 不能替代这一点——在 PR #6457 上，它们将这些缺陷中的每一个都包含在分配的 territory 内但没有报告任何一个。它们缺少的不是行数，而是问题。

发现以**分片批次**进行验证（每个验证 agent 最多 8 个发现，全部同时启动）。验证器只有通过引用与之矛盾的代码（或当 diff 自身的注释将被标记的行为记录为有意为之）时才能拒绝 Critical；任何不够确定的内容会被降级为低置信度而非删除——一个被静默拒绝的 Critical 对后续每个阶段都不可见，而降级后的仍然会到达人类手中。这一标准适用于每次拒绝的形式：它必须能从代码中构建——引用发现误读的行、从类型/常量/不变量证明所声称的状态不可能、引用覆盖触发条件的 diff 内 guard，或匹配无可观察效果的纯样式更改——或者匹配其他排除标准——而"过于推测"永远不是其中之一。失败场景命名了代码未排除的状态的发现默认是合理的：并发竞态、罕见但可达路径上的 nil/undefined、被视为缺失的 falsy 零或空集合、未排除边界上的边界差一、重试风暴或部分失败、丢失锚点的正则或允许列表。未构建四个依据中任何一个的拒绝会降级而非丢弃。验证后，**迭代反向审计**按 chunk 每轮一个审计员进行 fan-out 来查找遗漏，每个审计员拥有累计发现列表。循环在**连续两轮无新发现**后停止（或达到计划的轮次上限——如实报告而非报告为收敛）。该上限遵循 diff 的拓扑：小型 diff 为 **10** 轮（每轮一个审计员）；分 chunk 的 diff 为 **5** 轮（每轮每个 chunk 一个审计员）；大型 diff（≥ 3000 有效行）_当运行有截止时间_时为 **3** 轮，因为五轮约 90 分钟的轮次无法放入六小时的 CI 上限，且中途被终止的审查什么都发布不了——没有截止时间时，大型 diff 保持分 chunk 的 5 轮上限。操作员可以通过 `review.reverseAuditRounds` 设置降低每次审查适用的任一上限；它永远不能提高上限。一轮无新发现不是收敛的证据，反向审计的发现与其他发现一样经过验证。

## 严重级别

| 严重级别         | 含义                                                             | 是否作为 PR 评论发布？      |
| ---------------- | ------------------------------------------------------------------- | -------------------------- |
| **Critical**     | 合并前必须修复（bug、安全问题、数据丢失、构建失败） | 是（仅限高置信度） |
| **Suggestion**   | 建议改进                                             | 是（仅限高置信度） |
| **Nice to have** | 可选优化                                               | 否（仅终端显示）         |

低置信度的发现会显示在终端单独的"需要人工审查"部分，且永远不会作为 PR 评论发布。

## Worktree 隔离

审查 PR 时，`/review` 会创建一个临时的 git worktree（`.qwen/tmp/review-pr-<number>`），而不是切换你当前的分支。这意味着：

- 你的工作树、暂存更改和当前分支**不会被修改**
- 依赖项安装在 worktree 中（如 `npm ci`），以确保构建/测试正常工作
- 构建和测试命令在隔离环境中运行，不会污染本地构建缓存
- 如果出现任何问题，你的环境不受影响——只需删除 worktree
- 审查完成后，worktree 会自动清理
- 如果审查被中断（Ctrl+C、崩溃），下次对同一 PR 执行 `/review` 时，会在重新开始前自动清理过期的 worktree。如果被中断的会话仍留下了其租约——跳过此步骤的强制终止，或在后续 prompt 期间被中断的多 prompt 审查——`/review` 会拒绝并指出要删除的租约文件。正常停止会释放租约：已完成的审查和提前停止（空 diff、自上次审查以来无新变更）都会运行 `cleanup`，释放租约
- worktree 租约绑定到其会话：对已在审查中的 PR 执行第二次 `/review` 会拒绝启动（指出持有者），而不是拆除正在运行的审查的 worktree
- 审查报告和缓存保存在主项目目录中（而非 worktree）
- **修改**代码以进行测量的步骤——测试效力探测的变异体，以及验证器对特定发现的探测——各自在旁边的临时 worktree 中运行（`…-probe`、`…-scratch-<agent>`），因此一个 agent 的实验对其他读取共享树的 agent 不可见。作为保底，每波中的每个 agent 都会被告知哪些路径（如果有）在启动时与正在审查的 commit 不同，以及仅限于这些路径的失败不是一个发现。所有这些树在审查结束时与 worktree 一起被清理。

## 跨仓库 PR 审查

你可以通过传递完整 URL 来审查其他仓库的 PR：

```bash
/review https://github.com/other-org/other-repo/pull/456
```

这将在**轻量级模式**下运行——无 worktree，无构建/测试。审查仅基于 diff 文本（通过 GitHub API 获取）。如果你具有写权限，仍可发布 PR 评论。

| 能力                                                            | 同仓库 | 跨仓库                    |
| --------------------------------------------------------------------- | --------- | ----------------------------- |
| LLM 审查（Agent 0、1a、1b、1d、1e、2-6 + 验证 + 迭代反向审计） | ✅        | ✅                            |
| Agent 1c：跨文件追踪器                                           | ✅        | ❌（无本地代码库可供搜索） |
| Agent 7：构建与测试                                                 | ✅        | ❌（无本地代码库）         |
| Agent 8：Diff 专家 finder（0-2 个，领域需要时启用） | ✅        | ✅（仅需 diff）       |
| PR 行内评论                                                    | ✅        | ✅（如果你具有写权限） |
| 增量审查缓存                                              | ✅        | ❌                            |

## PR 行内评论

使用 `--comment` 将发现直接发布到 PR 上：

```bash
/review 123 --comment
```

或者，在运行 `/review 123` 后，输入 `post comments` 以发布发现，而无需重新运行审查。

**发布的内容：**

- 高置信度的 Critical 和 Suggestion 发现，作为特定行的行内评论，每个以 `**[Critical]**` 或 `**[Suggestion]**` 为前缀，以便区分阻塞问题和建议
- 修复为单个局部编辑时，附带一个可一键应用的 ` ```suggestion ` 代码块
- 对于 Approve/Request changes 结论：包含结论的审查摘要
- 对于 Comment 结论且所有行内评论已发布：无单独摘要（行内评论已足够）
- 每条评论底部的模型和 CLI 版本归属说明（例如，_— qwen3-coder via Qwen Code /review (v0.21.2)_）；在用户或系统 `settings.json` 中将 `review.attribution` 设为 `false` 可取消归属（工作区 `.qwen/settings.json` 中的 `review.*` 设置会被忽略）——评论和正文列表同时会失去 `**[Critical]**`/`**[Suggestion]**` 严重级别标记，并且模型会从审查的 machine-ledger 标记中被隐去，因此在全新环境中（无审查缓存）恢复的增量锚点无法通过同模型检查，重新审查会回退到全量范围

**仅在终端显示的内容：**

- Nice to have 发现
- 低置信度发现

**自己提交的 PR：** GitHub 不允许你对自己的 pull request 提交 `APPROVE` 或 `REQUEST_CHANGES` 审查——两者都会因 HTTP 422 失败。当 `/review` 检测到 PR 作者与当前认证用户匹配时，它会自动将 API 事件降级为 `COMMENT`，无论结论如何，从而确保提交成功。终端仍会显示真实的结论（"Approve" / "Request changes" / "Comment"）——只有 GitHub 端的审查事件被中和。实际发现仍会作为特定行的行内评论出现，因此实质性反馈保持不变。

**重新审查带有先前 Qwen Code 评论的 PR：** 当 `/review` 在已有先前 Qwen Code 审查评论的 PR 上运行时，它会在发布新评论前对它们进行分类。只有**同行重叠**（现有评论与新发现在相同的 `(path, line)` 上）才会提示你确认——这是你会在同一代码行上看到视觉重复的情况。来自较早提交的评论、已回复的评论（视为已解决）以及与新发现不重叠的评论会被静默跳过，并在终端输出一行日志让你知道过滤了什么。

**APPROVE 前的 CI / 构建状态检查：** 如果结论是 "Approve"，`/review` 会在提交前查询 PR 的 check-runs 和 commit statuses。如果有任何检查失败（或所有检查仍在 pending），API 事件会自动从 `APPROVE` 降级为 `COMMENT`，并在审查正文中说明原因。原因：LLM 审查是静态读取代码，无法看到运行时测试失败；在 CI 标红时批准会产生误导。行内发现仍会照常发布。如果你仍想批准（例如，已知的 CI 偶发失败），请在验证后手动提交 GitHub 批准。

## 应用发现（`--fix`）

`--fix` 是 `--comment` 的镜像。`--comment` 写入 **pull request**，因此需要一个；`--fix` 写入**工作树**，因此需要一个在审查结束后仍然存在的：

```bash
/review --fix                 # 本地未提交的更改
/review src/auth.ts --fix     # 单个文件
```

在 **PR 目标上会被忽略并发出警告**——PR 审查在临时 worktree 中运行，审查结束后即被删除，因此在那里"修复"的编辑会在几分钟后被丢弃。请改用 `--comment` 发布发现。

有效的 `--fix` **将 effort 下限设为 medium**，因为它编辑你的文件而 `low` 不进行验证：应用未验证的发现与发布未验证的发现是同样的错误，只是目标从某人的 PR 变成了你的工作树。它不会强制 `high`——medium 的发现已经过验证，而 `high` 增加的反向审计寻找的是_遗漏_的发现，这不是决定是否应用某个发现时所依赖的。

审查后，每个发现通过 `edit` 工具应用，然后**逐一记录结果**，共三种：

| 结果               | 含义                                               | 是否仍需处理？ |
| ------------------ | ----------------------------------------------------- | -------------------- |
| `fixed`            | 编辑已在你的工作树中                              | 否                   |
| `skipped`          | 真实问题，未应用——原因会一并报告  | 是                  |
| `no_change_needed` | 发现是错误的，或代码已经处理了它 | 否                   |

当发现的修复会改变预期行为、需要在审查 diff 之外进行更改，或在二次检查时被确认为误报时，该发现会被跳过。

**每个发现都会有一个结果，这是强制执行而非请求的。** 账本通过 `qwen review findings --outcomes` 进行，它拒绝不覆盖所有发现的结果集——一个修复了九个发现中的六个并报告六个的修复器并没有对任何一个撒谎，它只是静默缩短了列表，你将无法看到消失的三个。

## 恢复被中断的审查（`--resume`）

一个中途终止的长时间审查——连接断开、超时、终端被终止——会将其所有工作留在磁盘上：worktree、捕获的 diff，以及调度器对每个运行过的 agent 的记录。`--resume` 从那里继续，而不是重新开始：

```bash
/review 123 --resume
```

它仅适用于 **PR 目标**（本地审查的 diff 来自活跃的工作树，没有稳定的中断状态可以继续），在不确定时可以安全地传递：审查会判断磁盘上的状态本身——worktree 仍在获取的 commit 处且干净、捕获的 diff 逐字节未变、PR head 未移动、resume 限额未使用——并在任何内容不再匹配时静默重新开始，并告诉你哪个检查拒绝了。继续运行会重用之前尝试的已认证 agent 结果，因此报告会说明恢复了多少；这是公开的，永远不会是覆盖缺口。

两点需要注意。仅有内置目标默认值时，继续运行会保持被中断运行记录的 **effort**。显式的 `--effort`、项目记忆的级别、操作员的 `review.effort` 设置或有效的 `--comment` 提供所需级别；如果与被中断的运行不同，resume 会被拒绝并以该级别开始全新运行，因为不同的 effort 是不同的工作。如果 PR head 在审查中断期间移动了，resume 会拒绝（`head-moved`），新的运行会审查新的 commit——这正是你想要的，而且它算作本次审查的一次重启。

## 发现作为数据

已确认的发现在其他任何消费者使用之前被规范化为 `.qwen/tmp/qwen-review-<target>-findings.json`——终端报告、保存的 Markdown 报告和 PR 审查 JSON 都读取这一个产物，而非重新输入列表。每个发现携带唯一的 `id`（结果和 resolved 锚点的连接依据）、`severity`、`confidence`、`source`、`summary`、限制在 60 个字符以内用于列表渲染的 `shortSummary`、`failureScenario`，以及一个或多个 `locations`——按模式聚合的发现为**每次出现保留一个 location**，因此每个仍然获得自己的行内评论。

**首先，审查会确认它在运行你的代码。** 每个 `qwen review …` 步骤运行的是打包后的 bundle，而非工作树，因此自上次构建以来编辑过的审查命令不会生效，运行衡量的是旧行为。构建会记录它所打包的审查源码的摘要；`parse-args` 重新推导并进行比较，`drive` 也会再次检查，因为 verifier 简报直接将 agent 发送到那里而跳过了步骤 1。不匹配时会在 stderr 上说明 bundle 不是从这些源码构建的，以及如何重新构建。此检查在 CLI 解析为打包后的 `dist/cli.js`（`qwen` 二进制文件，或 `node dist/cli.js`）时运行；运行未打包输出的启动器（如 `npm start` 和 `npm run dev`）会跳过它。两种无法比较的情况会被区别对待：构建早于摘要记录的 checkout 会被告知检查无法运行及原因，而已安装的包——没有可比较的源码——则静默跳过。摘要覆盖审查命令、注册这些命令的文件、它们从目录外部导入的审查专用 lease，以及打包的审查 skill；它不跟踪这些文件导入的共享 helper，因此检查通过意味着审查代码与 bundle 匹配，而非整棵树都匹配。

**基础树已经失败的 Critical 会被搁置，而非归档。** 当测试命令失败且 merge base 可以构建时，`test-delta` 会记录哪些失败文件在没有 pull request 的情况下也会失败。规范化会读回该测量结果（`qwen review findings --test-delta`，与 `--outcomes` 并列）：一个自身文本提到了这些文件之一的 Critical 会被降级为 Suggestion，保留其证据，获得降级它的测量结果和 `heldByMeasurement` 字段，并宣布降级。已经标红的测试不是这个 pull request 导致标红的测试——如果它现在因_新_原因失败，说明是哪个测试，引用双方，并重新以 Critical 归档：已经携带该测量结果但仍被提升的发现会保持你放置的位置。

该命令在写入时进行验证：重复的 id、没有失败场景的发现、空的 locations 数组或未知的 severity 都是错误，而非被静默损坏的条目。

## PR 评论中的证据图片

GitHub 的 API 无法将图片附加到审查评论，因此 `/review` 可以将证据图片（TUI 屏幕截图、渲染输出比较）托管到你指定的仓库，并在评论中以 commit-pinned URL 引用它们。

```bash
export QWEN_REVIEW_ASSETS_REPO=your-org/your-repo   # 你可以推送的仓库
/review 123 --comment
```

将其指向你可以推送的仓库——推荐使用专用的图片托管仓库；fork 或临时仓库也可以。避免使用被审查的仓库本身：推送到那里的图片分支会成为每个克隆都会获取的可达对象。图片会落在 `pr-assets/<pr>-review` 分支上，使用内容哈希命名，评论通过 **commit-pinned** URL 引用它们——即使分支后续移动也是不可变的，且在 GitHub Enterprise 上同样有效。

对于 GitHub 触发的审查（PR 审查工作流），相同的变量通过同名的**仓库变量**进行配置，工作流仅允许专用的外部宿主：未设置变量，或将其设置为被审查的仓库（在去除空白和大小写规范化后比较，因此同一仓库的填充或大小写变体也被视为自引用），工作流传递空值，发布会被拒绝——不会有任何变化，审查将其证据保留为文本和本地产物路径。在仓库的 Actions 变量中将 `QWEN_REVIEW_ASSETS_REPO` 设置为单独的图片托管仓库的维护者可以启用审查评论嵌入捕获的 PNG。外部目标自行管理保留策略；visuals 清理工作流仅清理以前的 Git 后端发布者在此仓库中留下的历史 `pr-assets/*` 分支。

发布与评论发布受到完全相同的限制：没有指定仓库则不发布，未授权的运行（无有效的 `--comment`）与 `submit` 一样被拒绝。仅接受图片类型（SVG 被故意排除），有大小限制，每个文件的字节必须与其扩展名声称的格式匹配——错误标记或无法识别的内容会被拒绝。manifest 记录每个推送的文件。没有指定目标时，发现在终端和保存的报告中将证据保留为本地文件路径——不会出错，评论只是保持纯文本。

## 后续操作

审查后，上下文感知的提示会以 ghost text 形式出现。按 Tab 键接受：

| 审查后的状态                 | 提示                | 发生的情况                            |
| ---------------------------------- | ------------------ | --------------------------------------- |
| 本地审查，未传递 `--fix` | `fix these issues` | LLM 交互式修复每个发现    |
| 包含发现的 PR 审查            | `post comments`    | 发布 PR 行内评论（不重新审查） |
| PR 审查，无发现           | `post comments`    | 在 GitHub 上批准 PR（LGTM）        |
| 本地审查，全部通过            | `commit`           | 提交你的更改                    |

注意：`fix these issues` 仅适用于本地审查，原因与 `--fix` 相同——对于 PR 审查，worktree 会在审查后清理，因此不支持审查后的交互式修复——请使用 `--comment` 或 `post comments` 来发布发现。当传递了 `--fix` 时，发现已经携带结果，不会提供修复提示。

## 项目审查规则

你可以为每个项目自定义审查标准。`/review` 按以下顺序从这些文件中读取规则：

1. `.qwen/review-rules.md`（Qwen Code 原生）
2. `.github/copilot-instructions.md`（首选）或 `copilot-instructions.md`（回退——仅加载其中一个，不会同时加载）
3. `AGENTS.md` — `## Code Review` 部分
4. `QWEN.md` — `## Code Review` 部分

规则会作为附加标准注入到 LLM 审查 agent（0-6）中。对于 PR 审查，规则从**基础分支**读取，以防止恶意 PR 注入绕过规则。

## 仓库上下文

仓库可以通过将严格的 JSON manifest 提交到 `.qwen/review-context.json`，为审查者提供有界的、仓库特定的指导。在 medium 或 high effort 下，`/review` 会在捕获计划后读取 manifest，并在任何 agent 启动之前附加匹配的指导：

```json
{
  "version": 1,
  "label": "Example repository",
  "rules": [
    {
      "paths": ["packages/*/src/**"],
      "domains": ["runtime"],
      "relatedPaths": ["packages/runtime/src/**"],
      "recommendedTests": ["npm run test:runtime"],
      "requiredConfigurations": ["debug"],
      "requiredAgents": ["test-matrix"],
      "unverifiedDimensions": ["Alternate runtime was not exercised"],
      "verificationNotes": ["Use the repository native test runner"]
    }
  ]
}
```

当任何已更改的文件匹配其 `paths` glob 之一时（`*`、`?` 和 `**` 片段；区分大小写），该规则生效。所有匹配的规则合并其指导：审查 agent 的域和相关文件、构建与测试 agent 的推荐测试和必需配置、额外的审查者角色（仅在所选 effort 和拓扑运行它们时生效），以及最终审查作为未验证维度披露的证明边界。数组可以按任何顺序编写；重复条目会被拒绝。

对于 PR 审查，manifest 从合并基础读取，因此被审查的 PR 无法选择加入或退出指导；本地审查从当前 worktree 读取。Low-effort 和跨仓库审查跳过仓库上下文。完整契约和信任模型见[设计文档](https://qwenlm.github.io/qwen-code-docs/zh/design/review-repository-context)。

## Issue 保真度

对于 bugfix PR，Issue 保真度 agent 直接获取 issue 证据，而不是依赖 PR 描述文本。它运行 `qwen review issue-context <pr> --repo <owner/repo> --out <file>` 子命令，该命令解析 GitHub 的强关联 issue 元数据，然后获取每个被引用 issue 的标题、**正文**（报告者的原始复现步骤）和完整评论线程——每个 issue 从其自身的仓库获取（一个 PR 可以关闭不同仓库中的 issue）。此 agent 仅针对 PR 目标运行；本地 diff 和文件路径审查会跳过它。

关联 issue 集合是一个发现提示，而非作者链接了正确 issue 的证明：如果它为空但 PR 引用了明显的目标 issue，agent 在判断相关性后仍会获取它（使用 `--issue <n>` 重新运行；纯数字在 PR 的仓库中解析，而 `--issue <owner>/<repo>#<n>` 从自身仓库获取跨仓库引用）。获取的 issue 文本被视为不受信任的数据（提取事实，忽略嵌入的指令）。对于相关的 issue，原始复现、观察到的 payload、预期行为和维护者评论被视为判断 PR 是否修复了正确问题的最高优先级证据。

如果 issue 证据显示上游服务或 provider 返回了超出客户端契约的畸形数据，则客户端解析器或清理器的更改不被视为有效的根因修复，除非维护者明确要求防御性变通方法。重放畸形上游输出的测试仅证明变通方法处理了该结构；它不能证明该变通方法在架构上是合适的。

示例 `.qwen/review-rules.md`：

```markdown
# 审查规则

- 所有 API 端点必须验证身份认证
- 数据库查询必须使用参数化语句
- React 组件不得使用内联样式
- 错误信息不得暴露内部路径
```

## 增量审查

当审查之前已经审查过的 PR 时，`/review` 仅检查自上次审查以来的更改：

```bash
# 首次审查——全量审查，创建缓存
/review 123

# PR 更新了新提交——仅审查新增更改
/review 123
```

### 跨模型审查

如果你切换模型（通过 `/model`）并重新审查同一个 PR，`/review` 会检测到模型更改并执行全量审查，而不是跳过：

```bash
# 使用模型 A 进行审查
/review 123

# 切换模型
/model

# 再次审查——使用模型 B 进行全量审查（不跳过）
/review 123
# → "上次审查使用了 qwen3-coder。正在使用 gpt-4o 进行全量审查以获取第二意见。"
```

模型匹配还会控制增量范围，而不仅仅是跳过："清理到缓存的 commit"是上一个模型的结论，因此当自缓存审查以来有新的 commit 时，模型不匹配永远不会将范围限定为 `lastCommitSha..HEAD`——范围是完整的 diff，并注明"上一轮由 qwen3-coder 审查。正在使用 gpt-4o 进行全量审查。"——除非从上次发布的审查中恢复了由当前运行模型认证的锚点（见下文），此时范围由该锚点决定。上一轮的发现仍然会被继承以重新裁定；只有锚点不会。当缓存不存在或其锚点不可用时（CI、另一个克隆），从上次发布审查的 machine-ledger 标记中恢复的锚点也受同样的门控：只有当当前运行的模型认证了它时，它才会限定增量范围——由不同模型认证的标记，或不携带模型的标记（在 `review.attribution` 关闭时发布的审查，或在该字段之前的审查），会回退到完整 diff。

未正常关闭的轮次会发布不带锚点的标记（它无法认证一个范围），但当该轮次的工作列表完整保留时，这种丢失不会持续：恢复会从你的账户发布的最近一个带有锚点的较早标记中将锚点向前嫁接，因此单次非正常关闭的轮次不再迫使后续每个轮次重新读取完整 diff——下一个轮次的范围为 `anchor..HEAD`，重新覆盖了非正常关闭轮次无法认证的范围。大小受限轮次的嫁接会被拒绝（被丢弃的发现会落在嫁接范围之外并静默退役），因此后续轮次会持续重新读取完整 diff，直到一个完整的标记落地。

缓存存储在 `.qwen/review-cache/` 中，并同时跟踪 commit SHA 和 model ID。请确保将此目录加入 `.gitignore`（使用更宽泛的规则如 `.qwen/*` 也可以）。在 GitHub 上，如果缓存的 commit 被 rebase 或 force-push 移除，系统将回退到全量审查；Aone 对缓存锚点的规则不同——见其下方段落。只有 high-effort 审查会查阅或写入缓存——`--effort low|medium` 的快速 pass 永远不会被视为"已审查"。

## 审查报告

对于同仓库审查，结果会作为 Markdown 文件保存在项目的 `.qwen/reviews/` 目录中（跨仓库轻量级审查会跳过报告持久化）：

```
.qwen/reviews/2026-04-06-143022-pr-123.md
.qwen/reviews/2026-04-06-150510-local.md
```

报告包含：时间戳、diff 统计、构建/测试结果、所有发现及其验证状态，以及最终结论。章节标题和描述性文本遵循输出语言偏好；技术标识符（SHA、文件路径、门控名称、发现 id）保持原样。

Medium 和 high-effort 审查还会保存一个具有相同文件名但扩展名为 `.json` 的结构化 JSON 伴随文件（例如 `2026-04-06-143022-pr-123.json`），包含规范化发现和组合结论作为数据。Qwen Code 的 Web Shell 将该文档渲染为可筛选发现的交互式审查视图；Markdown 报告则保持为人类可读的存档。

流水线的确定性部分——参数解析（`qwen review parse-args`）和事件/正文决策（`qwen review compose-review`）——是经过测试的子命令而非提示文本，因此 `--effort` 语法、`--comment` 强制、结论上限和降级行为由单元测试固定，不会随模型漂移。

**GitHub Enterprise：** 在非 `github.com` 主机上审查 PR URL 时，该主机的每个 GitHub 调用都会被路由——审查子命令（`match-remote`、`meta`、`fetch-pr`、`pr-context`、`comment-status`、`issue-context`、`fetch-diff`、`comment-body`、`plan-diff`、`test-plan`、`presubmit`、`compose-review`、`submit`、`publish-assets`）接受 `--host` 并在代码中设置，因此遗忘的 host 不会静默将审查重定向到 `github.com`。

**Aone Code：** 对于 origin 在 `gitlab.alibaba-inc.com` 上的克隆，从该克隆内部运行 `/review`——平台从 remote 检测，子命令正常工作，由 `a1` CLI 支持（至少 0.1.90——较旧的安装在认证时会被拒绝并提示升级）——目标编号是全局 MR id。`fetch-pr` 获取 `refs/merge-requests/<id>/head` 并构建 worktree + diff，因此 agent 对 worktree 的审查不变，`test-plan` 也可以工作——它通过同一个 reader 读取 MR 描述。`pr-context` 也有支持：它读取 MR 的元数据、讨论线程和之前发布的 qwen 摘要（machine ledger 从中恢复），因此 Aone 运行看到 MR 的现有讨论，正如 GitHub 运行看到 PR 的一样。`comment-status` 和 `presubmit` 也由 a1 支持（presubmit 完全支持：自我 PR 检测、head 漂移、merge-gate CI，以及现有评论去重），因此重复的 `--comment` 轮次会对 MR 的现有评论进行去重，而不是重新发布它们（平台标记为过时的线程——其行在修改后不再映射——仍可重新发布），自我 PR 检测也可以工作。`publish-assets` 的写入被跳过。`--comment` 通过 `a1` CLI **发布**审查：每个行内发现一条评论，然后是摘要评论。Aone 没有原生的 request-changes 状态——在该结论下，摘要评论携带一个阻塞头，实际发布的行内 Critical 通过讨论门阻塞合并，同时其讨论保持未解决状态（当没有发布行内 Critical 时，该头是建议性的，不会在机械上阻塞合并）。发布的评论不携带 AI 评论标记——`a1` 无法设置——因此仓库专用的 `ai_comment` 合并门不会追踪它们。原生的 `a1 repo mr approve` 在 Approve 结论且运行读取了 MR 的上下文时触发（与 GitHub 相同的门控；context-unavailable 的运行上限为 Comment）。增量重新审查遵循 AGit-Flow 更新模型：更新会就地 AMEND 单个 CR commit，使上一轮审查的 head 成为孤儿——因此缓存锚点在判断时**不考虑**祖先关系（anchor-behind-head 测试会在每次更新时失败），重新审查将 PR 自身的 diff 限定为更新所涉及的文件，而不是回退到全量审查；如果更新同时 rebase 到了更新的 master，则仅当 rebase 的漂移保持在 CR 文件内时保留该范围——触及任何其他文件的漂移会回退到全量审查，且无论如何没有漂移字节进入发布的范围。参见 `docs/design/2026-08-15-review-aone-provider.md`。

每次运行以一行机器可读的行结束（`Review complete: <target> — <disposition>`），因此脚本和 CI 包装器可以通过单个 `^Review complete: ` 匹配来检测完成和结果。

## 无头运行（`qwen review run`）

`/review` 是交互式的。当脚本或 CI 作业需要运行审查并根据其结果采取行动时，请使用无头包装器：

```bash
qwen review run [target] [--json] [--fail-on request-changes] [--comment] [--resume] [--quiet]
```

`target` 是 PR 编号、PR URL 或文件路径；省略则审查本地工作树。该命令以非交互方式运行当前构建的 CLI（stdin 关闭，因此斜杠命令检测仍然有效），将子进程的进度流式输出到 **stderr**，并将结论打印到 **stdout**——或使用 `--json` 输出完整的结果对象。结论从 `compose-review` 写入的产物中读取（与 skill 视为结论权威的 JSON 相同），而非从模型的文本中解析。

退出代码是门控应读取的契约：

| 退出码 | 含义                                                                                           |
| ---- | ------------------------------------------------------------------------------------------------- |
| `0`  | 审查已完成（无论其决定如何）                                                        |
| `1`  | 未达到结论——子进程失败、超时或未留下组合产物            |
| `3`  | 已完成且结论为 `REQUEST_CHANGES`，**并且**设置了 `--fail-on request-changes`（可选阻塞） |

`3`（而非 `2`）让门控区分"审查在阻塞"和"工具出错"——yargs 已将 `1` 用于使用错误——无需解析任何输出。`--timeout-minutes`（默认 120，下限为 1）终止挂起的审查并退出 `1`，取消命令（Ctrl+C / SIGTERM）会终止审查的进程组而非使其成为孤儿。

`--resume` 继续同一 PR 被中断的审查，而不是重新开始——当长时间的本地运行中途终止时（连接断开、超时、终端被终止），重试否则会重新获取、重新分 chunk 并重新启动那些工作已在磁盘上的 agent。在重试时无条件传递是安全的：`fetch-pr` 会判断磁盘上的状态本身（worktree 仍在获取的 SHA 处且干净、diff 字节未变、PR head 未移动、resume 限额未使用），并在任何内容不再匹配时静默回退到全新审查，因此该标志永远不会失败一个可以重新开始的运行。仅有内置目标默认值时，继续运行被固定在被中断运行记录的 effort。显式的 `--effort`、项目记忆的级别、操作员的 `review.effort` 设置或有效的 `--comment` 提供所需级别；不匹配时拒绝 resume 并以该级别全新运行。仅适用于 PR 目标（本地审查的 diff 从活跃工作树捕获，没有稳定的中断状态可以继续）。Resume 是一个**本地便利功能**：仓库自身的 CI 审查工作流**不会** resume——每次重试都会全新运行，因为 CI 尝试运行 no-sandbox，其 worktree 在退出时被删除，没有中断状态可以继续。

有时间预算的运行还可以导出**软**截止时间，以便审查在仍有时间进行验证、组合和发布时停止其开放式反向审计循环：`QWEN_REVIEW_DEADLINE_EPOCH` 是运行将被终止的 Unix 秒时刻，`QWEN_REVIEW_DEADLINE_RESERVE_SECONDS`（默认 3600；`0` 仅保留轮次估计）是为最后一轮的验证、`compose-review` 和提交保留的尾部时间。当剩余预算不足以容纳另一轮加上该尾部时，轮次构建器将拒绝构建，组合结论会披露截断的审计（否则为 Approve 的结论被上限为 Comment）。缺失或格式错误的截止时间会使审查不受门控——外部超时仍然限制运行。

在该保留时间内嵌套了一个更小的**组合下限**，`QWEN_REVIEW_DEADLINE_COMPOSE_FLOOR_SECONDS`（默认 1200；`0` 完全禁用此门控，在每个时间点包括超过截止时间后均生效）。保留时间是一个数字，涵盖"验证最后一轮 **加** 组合 **加** 提交"，这适合常规的逐发现重新追踪，但不适合安全性审查——后者的验证会无限制地重新运行真实的文件系统/git 工作负载。因此验证器——而非轮次构建器——受此下限门控：一旦剩余时间等于或低于下限，`agent-prompt --role verify` 会拒绝构建（一行 `VERIFY BUDGET:`，退出码 **4**），手头的发现保留其未验证标签（这会上限结论），然后 `compose-review` 和提交运行。下限严格低于保留时间，因此正常的运行会先触发反向审计门控而永远不会到达它；它是保留时间无法约束的那段时间的保障。

## 跨文件影响分析

专用的跨文件追踪器（Agent 1c）端到端负责此遍历。当代码更改修改了导出的函数、类或接口时，它会搜索所有调用方并检查兼容性：

- 参数数量/类型更改
- 返回类型更改
- 移除或重命名公共方法
- 破坏性 API 更改

它还遍历 **producer 方向**：diff 添加的每个字段、选项或可选参数都被追踪到其读取位置——包括 diff 从未涉及的文件。一个活跃的代码路径读取了没有任何东西填充的字段，意味着它门控的功能静默地什么都不做，这会在读取位置被标记为 Critical。

对于大型 diff（>10 个修改的符号），consumer 方向分析优先处理签名发生更改的函数；producer 方向永远不受预算限制，因为未更改的签名正是其要点。

## 审查预算

流水线中在 diff 大小上具有弹性的部分根据其进行缩放，缩放被写入 diff 计划，因此每个阶段读取一个数字而非各自独立决定：

| 预算字段    | 作用范围                      | 缩放方式                                                      |
| --------------- | ----------------------------------- | ------------------------------------------------------------------ |
| `inlineAngles`  | `low` 运行多少个角度（步骤 3C） | 3 个，加上每 60 行源码 1 个，上限为存在的 6 个角度 |
| `candidateFloor` | `low` 何时需要进行一次确定性召回复查 | `min(changed files, 4)`                                            |
| `sweep`         | `low` 的 gap sweep 是否运行      | 低于 25 行源码时关闭                                          |
| `specialistCap` | Agent 8 的上限                 | 低于 80 行源码时为 0，否则为 2                               |
| `verifyShard`   | 每个验证 agent 的发现数     | 固定为 8——是验证器的属性，而非 diff 的属性            |

它故意不做两件事。它**永远不会将某个维度缩放到零**：审查需要哪些 agent 由名册决定，名册读取 effort 级别，因此小 diff 仍然获得安全性 pass 和测试覆盖率 pass。它读取的是**源码**行数，而非 diff 行数——一个 40 行的生产代码变更附带 900 行新测试是一个小变更，同样的推理已经支配了 territory-fan-out 门控。

下限设置的原因：在九行的拼写错误修复上，六个行内遍历中有五个是对无物的遍历，而 sweep——一个新读者寻找第一次 pass 未覆盖的内容——在第一次 pass 已覆盖所有内容时没有什么可寻找的。Agent 8 的下限是实质性考量："一个领域主导 diff"是一个判断，对四十行做出的判断每次都会找到一个主导领域，因为四十行通常就是一件事。

## Token 效率

High-effort 流水线限制每个阶段（分片大小、审计轮次），但总调用数随发现数缩放——`ceil(F/8)` 个验证分片——以及在 3B 下随 chunk 数缩放（反向审计按 chunk 按轮次运行）。典型的 3A 概况：

| 阶段                            | LLM 调用次数                      | 说明                                                                                                          |
| -------------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| 审查 agent（步骤 3）           | 17 (+0-2)                       | 并行运行；Agent 1e 仅在 diff 信号为 wrapping 类型时启用（无 1e 时为 16）；跨仓库跳过 Agent 1c 和 7（带 PR 标识时 15，不带时 13——Agent 0 和 6d 同时跳过）；本地/文件跳过 Agent 0 和 counter-frame 审计 6d（15）；diff 触及指令文件时多一个（`prose-exec`），且审查有工作树                                          |
| 分片验证（步骤 4）    | ceil(F/8)                      | F = 发现数；每个验证 agent 最多 8 个，同时启动                                              |
| 迭代反向审计（步骤 5） | 2-10 (3A)；轮次 × chunk (3B) | 连续 2 轮无新发现后停止；上限按拓扑——小 diff 为 10，分 chunk 的 diff 为 5，大型 diff 在运行有截止时间时为 3。3B 按 chunk 按轮次 fan-out 一个审计员                        |
| **总计**                        | **~20-31 (~16-29)**             | 3A 同仓库：~20-31（典型 ~20-22）；跨仓库或本地/文件：~16-29（下限为不带标识的跨仓库名册 13）；Agent 1e 未启用时少一个，`prose-exec` 需要时多一个；3B 随 chunk 缩放（参见 DESIGN.md）                                             |

大多数 PR 收敛到范围的下限；上限防止在极端情况下成本失控。在 `--effort low` 下，审查完全在行内运行——**0 次 subagent 调用**——每个角度遍历 diff 一次而非总共一次。

## 不会标记的内容

审查会刻意排除以下内容：

- 未更改代码中预先存在的问题（仅关注 diff）
- 格式化程序会自动规范的样式或格式，或符合代码库约定的命名——但 linter 或类型检查器会标记的实质性问题（如未使用的变量、不可达代码、类型错误）除外，这些仍在审查范围内
- 没有实际问题的主观"建议考虑做 X"
- 未修复 bug 或风险的微小重构
- 缺失的文档，除非逻辑确实令人困惑
- 现有 PR 评论中已讨论过的问题（避免重复人工反馈）

## 设计理念

> **沉默胜于噪音。** 每条评论都应值得读者花时间阅读。

- 如果不确定某个问题是否真的是问题 → 不要报告
- 每个发现都说明一个具体的失败场景（触发 → 错误结果）或具体的代价——无法说明的发现会在到达你之前被丢弃
- 跨 N 个文件的相同模式 → 聚合为一个发现
- PR 评论仅包含高置信度内容（且仅来自 high-effort、已验证的审查）
- 排除符合代码库约定的表面样式/格式问题
