Claude Code 代码审查技能解析:ReportFindings 工具——代码审查结果的结构化上报通道
本文基于 system_prompts_leaks 仓库中 report-findings-tool.md 文档展开,完整解读 Claude Code 内置 /code-review 技能配套的 ReportFindings 工具:它解决什么问题、完整的 input_schema 中每个字段的语义与约束、以及与五级 effort 审查流水线的精确映射关系。读完本文,你将理解“审查结果如何从模型输出变成宿主 UI 可渲染的结构化数据”这一完整契约,并能为自己的 Agent 设计类似的类型化审查上报协议。
ReportFindings 是什么:/code-review 的第二输出通道
/code-review 是 Claude Code 的内置斜杠命令,其提示词模板被编译进 Claude Code 二进制文件,命令执行时以 user-message 块的形式注入对话。仓库中该技能目录下的文本均从二进制中抽取,并与 MITM 代理的实时 API 捕获做了字节级核对(见 README.md 对 2.1.245 捆绑包的复核说明)。
ReportFindings 是这个技能体系中的一个专用工具:它把代码审查发现(findings)以带类型的列表上报,让宿主 UI 直接渲染,而不是让模型把审查结果打印成纯文本。README.md 在文件清单中将其定位为 “the alternative output channel to the JSON array”——即与“内联 JSON 数组”并列的第二条输出通道:
| 文件 | 审查流水线 |
|---|---|
| low.md | 1 次 diff 扫描,无子代理、无验证 → ≤4 条发现 |
| medium.md | 8 个发现角度 × 6 候选,1-vote 验证(precision-tuned)→ ≤8 条 |
| high.md | 8 个发现角度 × 6 候选,1-vote 验证(recall-biased)→ ≤10 条(默认档) |
| xhigh.md | 10 个发现角度 × 8 候选,验证 + gap-sweep → ≤15 条 |
| max.md | 与 xhigh 相同,仅头部措辞不同;区别只在 API 推理 effort |
| report-findings-tool.md | ReportFindings 工具(描述 + JSON Schema),挂载在宿主 UI 渲染类型化发现的会话上 |
工具描述与调用约定
report-findings-tool.md 开头给出的工具描述(description)是模型决定何时、如何调用它的唯一依据,原文为:
Report code-review findings as a typed list so the host UI can render them. Use this only when the active code-review instructions tell you to report findings with this tool; otherwise follow whatever output format those instructions specify. When reporting a review's results, call it once with the verified findings ranked most-severe first (empty array if nothing survived verification) and do not also print the findings as text. When re-reporting after applying fixes (only if the apply instructions ask for it), set
outcomeon each finding to what actually happened.
从中可以拆出四条硬性调用约定:
- 触发条件受限:只有当当前生效的代码审查指令明确要求用本工具上报时才能调用;否则必须遵循那些指令规定的输出格式。这解释了为什么各档位默认提示词在结尾都特意声明 “Do not call the ReportFindings tool even if it is available”(参见 high.md 输出小节)——工具即使挂载在会话上,输出契约仍以内联 JSON 块为准。
- 单次调用、严重度排序:上报审查结果时只调用一次,
findings按最严重优先排序;若没有任何发现通过验证,传空数组。 - 禁止文本重复:调用工具的同时不得再把发现以文本形式打印一遍——UI 会基于工具载荷渲染,重复文本属于噪声。
- 修复后重报:仅在 apply 指令要求时,在应用修复后重新上报一次,并给每条发现设置
outcome字段,如实记录该发现的最终处置结果。
input_schema 完整解析
以下是文档中给出的完整 JSON Schema(JSON Schema draft 2020-12,两层 additionalProperties: false,即顶层与 finding 对象均不接受未声明字段):
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"level": {
"description": "Effort level the review ran at",
"type": "string",
"enum": [
"low",
"medium",
"high",
"xhigh",
"max"
]
},
"findings": {
"description": "Verified findings, most-severe first; empty if none survived",
"maxItems": 32,
"type": "array",
"items": {
"type": "object",
"properties": {
"file": {
"description": "Repo-relative path of the file the finding is in",
"type": "string"
},
"line": {
"description": "1-indexed line the finding anchors to",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"summary": {
"description": "One-sentence statement of the defect",
"type": "string"
},
"short_summary": {
"description": "Compressed label for compact UI (≤60 chars): the claim alone, no rationale or consequence clause",
"type": "string",
"maxLength": 60
},
"failure_scenario": {
"description": "Concrete inputs/state → wrong output/crash",
"type": "string"
},
"category": {
"description": "Short kebab-case slug of the finding type, e.g. \"correctness\", \"simplification\", \"efficiency\", \"test-coverage\"",
"type": "string",
"maxLength": 40
},
"verdict": {
"description": "Set when a verify pass ran; absent on inline-only reviews",
"type": "string",
"enum": [
"CONFIRMED",
"PLAUSIBLE"
]
},
"outcome": {
"description": "Set ONLY when re-reporting after applying fixes: what happened to this finding",
"type": "string",
"enum": [
"fixed",
"skipped",
"no_change_needed"
]
}
},
"required": [
"file",
"summary",
"failure_scenario"
],
"additionalProperties": false
}
}
},
"required": [
"findings"
],
"additionalProperties": false
}
顶层字段
level(可选):本次审查实际运行的 effort 档位,取值严格限定为low/medium/high/xhigh/max,与/code-review [level]的五个档位一一对应。注意独立的云端多代理模式ultra不在枚举内。该字段让 UI 能展示“这份结果是在什么强度下跑出来的”。findings(唯一必填项):通过验证的发现数组,按最严重优先排序,最多 32 条(maxItems: 32);没有发现通过验证时传空数组。
finding 对象字段
| 字段 | 必填 | 约束 | 语义 |
|---|---|---|---|
file |
是 | 字符串 | 发现所在文件的仓库相对路径,UI 据此做跳转锚定 |
summary |
是 | 字符串 | 一句话说清这个缺陷是什么(the claim) |
failure_scenario |
是 | 字符串 | 具体的“输入/状态 → 错误输出/崩溃”链路,是发现的证据核心 |
line |
否 | 整数,1-indexed | 发现锚定的行号;上下限 ±9007199254740991 即 JavaScript 的安全整数边界(±(2^53−1)),从源码结构看说明该 Schema 由 JS 运行时序列化生成 |
short_summary |
否 | ≤60 字符 | 压缩标签,供紧凑 UI 使用;只保留结论本身,不写理由或后果从句 |
category |
否 | ≤40 字符,kebab-case slug | 发现类型短标签,文档给出的示例为 correctness、simplification、efficiency、test-coverage |
verdict |
否 | 枚举 CONFIRMED / PLAUSIBLE |
仅在跑过验证阶段时设置;inline-only 审查不设置 |
outcome |
否 | 枚举 fixed / skipped / no_change_needed |
仅在应用修复后重新上报时设置,记录“这条发现最终怎么样了” |
必填字段与验证阶段的对应关系
file + summary + failure_scenario 是仅有的三个必填字段,这恰好对应各档位提示词对候选发现的最低形状要求:high.md Phase 1 要求每个候选发现提供 “file、line、one-line summary、and a concrete failure_scenario”,而工具 Schema 中 line 被降级为可选,说明锚定行号是尽力而为的增强信息,file/summary/failure_scenario 才是不可缺的语义骨架。verdict 只允许 CONFIRMED 和 PLAUSIBLE 两个值,正对应验证阶段(Phase 2)的三态投票 CONFIRMED / PLAUSIBLE / REFUTED 中被保留的两态——REFUTED 的候选在汇总前就被丢弃,因此永远不会出现在上报载荷里。
Schema 与审查流水线的映射
把 Schema 对照五级流水线的实际行为,可以读出若干设计意图:
1. maxItems: 32 为什么远大于各档上限。 各档输出上限分别为 low ≤4、medium ≤8、high ≤10、xhigh ≤15、max ≤15(见各档位文件 Output 小节),Schema 却放宽到 32。从源码结构看,这是给模型家族特化路由预留的余量:README.md 指出提示词路由由 “effort 档位 × 模型家族” 共同决定,claude-opus-5 的 medium/high 单元格各自收敛为 “≤15 findings” 的最小提示词且经由 ReportFindings 上报——若两条特化通道合并或出现更高上限的变体,32 仍可容纳。
2. category 对应发现角度而非修复动作。 各档位提示词把发现分为正确性角度(A line-by-line diff scan、B removed-behavior auditor、C cross-file tracer,xhigh/max 另加 D language-pitfall specialist、E wrapper/proxy correctness)与清理角度(Reuse、Simplification、Efficiency、Altitude、Conventions)。category 的示例值 correctness、simplification、efficiency 正是这些角度的 kebab-case 名称,UI 可据此分组或过滤。各档位提示词还规定 “正确性发现永远优先于清理/altitude/conventions 发现”,这一排序原则就是 findings 数组“最严重优先”排序的依据。
3. outcome 对应 --fix 工作流。 README.md 的 Usage 说明 --fix 会在审查后把发现应用到工作树。工具描述中 “When re-reporting after applying fixes (only if the apply instructions ask for it)” 指的就是这条路径:修复完成后模型重新调用一次 ReportFindings,每条发现携带 fixed(已修)、skipped(跳过)或 no_change_needed(无需改动)三种真实结果之一,使 UI 能呈现“审查—修复”闭环的最终状态,而不是只呈现审查时刻的快照。
4. short_summary 的 60 字符限制服务于紧凑渲染。 描述明确 “the claim alone, no rationale or consequence clause”——即只放结论、不放理由与后果,这保证在窄面板、行内徽章等紧凑 UI 中不会截断出歧义文本。
为什么默认档位明确禁止调用该工具
一个容易困惑的点:ReportFindings 明明挂载在会话中,为什么 low.md、medium.md、high.md、xhigh.md、max.md 每一档的输出小节都写着 “Do not call the ReportFindings tool even if it is available - this review's output contract is the JSON block above”?
答案在于这两条通道服务于不同的宿主形态:
- 默认通道(内联 JSON 数组):当前这五份提示词模板的固定输出契约。审查结果以代码块形式直接出现在对话流中,任何终端或聊天界面都能消费,不依赖宿主 UI 是否实现了类型化渲染。
- 工具通道(ReportFindings 调用):README.md 说明二进制中还携带了“未在此复现的兄弟变体”,其中之一就是 “an output mode that reports via a
ReportFindingstool call instead of a JSON array”,并且claude-opus-5模型家族的 medium/high 单元格本身就 “reports viaReportFindings”。也就是说,是否用工具上报不是模型自己选的,而是由路由矩阵在提示词中预先钉死——工具描述里 “Use this only when the active code-review instructions tell you to” 正是对这一机制的呼应:工具永远可用,输出契约由注入的指令决定。
工具在系统提示词中的注册位置
ReportFindings 并不只出现在技能目录里,它以“工具文档”的形式注册在多个模型的完整系统提示词中,且描述文本与 report-findings-tool.md 逐字一致:
- claude-code-sonnet-4.6.md 第 1908 行起的
## ReportFindings章节; - claude-code-opus-5.md 第 1601 行起的同名章节;
- 其余模型(opus-4.6/4.7/4.8、sonnet-5、haiku-4.5、fable-5/5.1、desktop-fable-5 等)的系统提示词中均存在同一章节。
值得注意的是版本间存在细微的 Schema 差异:claude-code-sonnet-4.6 注册版本的 finding 对象中没有 short_summary 字段,而 claude-code-opus-5 与技能目录中的 report-findings-tool.md 版本包含该字段(maxLength: 60)。这表明紧凑 UI 压缩标签是较新的增量能力,按模型家族的提示词构建逐步铺开。
此外,从 agents/Explore.md 中对 v2.1.211 二进制内置 Explore 代理的 MITM 捕获注释可见,ReportFindings 也出现在该代理的实际工具集中——从源码结构看,这是一个跨代理共享的宿主级工具,而非 code-review 技能私有。
小结:类型化上报契约的设计要点
ReportFindings 的完整定义可以浓缩为一份可复用的设计范式:用严格受限的 Schema(双层 additionalProperties: false + 枚举 + 长度上限)把“审查结果”从自由文本固化为 UI 可渲染的数据;用最少必填字段(file/summary/failure_scenario)保住语义骨架,用可选字段(line/verdict/outcome/short_summary/category)承载验证状态、修复闭环与紧凑渲染等增强信息;再用提示词而非模型自由意志来钉死“走文本还是走工具”的输出通道。对需要在宿主 UI 中呈现 Agent 审查结果的实现者来说,这份 Schema 与其配套的调用约定(单次调用、严重度排序、空数组语义、修复后重报)就是一个直接可参考的蓝本,各字段与五级 effort 流水线的对应关系上文已逐条给出,可直接对照 skills/code-review 目录下的原文档继续深挖。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00