首页
/ LobeHub deep-review 技能中的独立评审子代理提示模板:四维占位符、校准规则与严格 JSON 契约的设计解析

LobeHub deep-review 技能中的独立评审子代理提示模板:四维占位符、校准规则与严格 JSON 契约的设计解析

2026-09-06 17:13:52作者:韦蓉瑛

本篇解析 LobeHub 仓库 .agents/skills/deep-review/ 技能中的评审子代理提示模板 review-prompt.md。读完你能掌握该模板的四个占位符实例化规则、校准(calibration)与 introduced/exposed_legacy 两条硬规则、严格 JSON 返回契约的逐字段语义,以及它与 validate-output.ts 校验器、verify-prompt.md 三方验证流程如何拼成一条"防幻觉"的多代理评审流水线。

1. 模板定位:一条多代理评审流水线中的"发现阶段"契约

review-prompt.md 是 deep-review 技能(其入口文档为 SKILL.md)deep 模式的核心模板。SKILL.md 开头定义了该技能的全部设计原则:

Multi-dimensional code review built on independent reviewers. Review breadth comes from parallel dimension coverage; precision comes from adversarial verification and global duplicate consolidation before findings reach the report.

其中两条原则直接决定了 review-prompt.md 的形态:

  1. 防幻觉(Anti-hallucination)——只看到 diff 片段的评审者会"发明"bug,因此候选发现必须由独立的 verify 子代理逐条证伪,返回三方判定(confirmed / false_positive / need_more_context);
  2. 规则优于模型(Rules over model)——评审质量来自细粒度、可执行的维度规则文件,而非更强的模型。子代理跑在 balanced/fast 档位上,每个维度文件告诉它"怎么查、什么算违规、什么不算"。

整条流水线的阶段划分为:

阶段 载体 职责
0. 定范围 scoping.md 产出 {changes}(内联 diff 或取数命令)与 ≤ 200 词的 {scope_summary}
1–2. 选维度、并发派生评审者 claude-code/main.md Step 1–2 按剪枝表裁剪维度,为每个维度实例化 review-prompt.md 并并发派发
3. 校验与验证 validate-output.ts + verify-prompt.md JSON 契约校验 → 独立证伪
4–5. 去重与报告 consolidate-prompt.md + report-template.md 同根因合并、结构化报告

review-prompt.md 服务的正是"阶段 2":它是所有维度评审子代理的统一提示模板。文件开头(第 3 行)说明它同时适配两种运行环境:"One template for all review subagents in both environments. The {dimensions} placeholder makes it work for a single dimension (Claude Code spawns one subagent per dimension) or a composite group (Codex packs several dimensions into one subagent)"——即 Claude Code 环境每个维度一个子代理,Codex 环境(见 codex/main.md)则可能把多个维度打包进一个子代理,{dimensions} 占位符同时兼容两种粒度。

2. 实例化方法:四个占位符及替换规则

模板正文(位于文件内一个 ```text 围栏中)含四个占位符。文档开头给出的实例化规则如下(此处逐条完整继承原文):

  1. {dimensions} → 分配的维度 id,例如 code-style,或复合组 performance, security, compatibility
  2. {dimension_files} → 分配的维度规则文件路径,如存在扩展包对应文件则一并包含(例如 .agents/skills/deep-review/references/dimensions/security.md + .agents/skills/deep-review-cloud/dimensions/security.md);
  3. {scope_summary} → 第 0 步产出的 ≤ 200 词范围摘要;
  4. {changes} → 小 diff 的完整 diff 文本(包裹在 ```diff 围栏中),或大 diff 的取数命令;
  5. 替换后的文本作为子代理的完整提示传入——子代理与主代理不共享任何上下文,提示必须自包含(self-contained)。

几个占位符的取值细节由上游文件约束:

  • {changes} 的"diff 或命令"二态:来自 scoping.md 的尺寸判定——diff ≤ 200 行且 ≤ 5 个文件视为小 diff,此时把完整 diff 文本内联进提示;否则只把(带 exclude 过滤的)取数命令写入 {changes},由子代理自己执行。未跟踪文件在小 diff 路径下以"每文件一个围栏块、路径作标题"的方式追加进 {changes}
  • {scope_summary} 的内容scoping.md 第 6 步要求把"变更文件清单 + 需求/验收标准"压缩到 ≤ 200 词,它是子代理判断"改动是否违背需求"的首要标尺。
  • {dimension_files} 与扩展包SKILL.md 的 "Extension packs" 一节规定,包装仓库(如把本仓库作为 submodule 引入的私有部署)可通过 deep-review-* 命名的兄弟技能目录扩展规则集——同名维度文件扩展内置维度(两个都加载),新名字新增维度。模板第 8 行要求 {dimension_files} 必须包含这些扩展包对应文件,正是为这一机制服务的。

3. 模板正文逐段解析

模板正文(约第 15–143 行的 ```text 围栏内容)可拆为七个逻辑段,下面按原文顺序逐一展开。

3.1 身份与边界:第三方评审人,只报本维度的发现

正文开篇(第 16 行):

You are an independent third-party code reviewer. Review the following git changes strictly within your assigned dimension(s): {dimensions}. Other dimensions are covered by other reviewers — do not report findings outside your assignment, even if you notice them.

这句对应 SKILL.md 的"反自我批准"原则——刚写完代码的代理给自己的作业打分必然放水,因此评审必须由持第三方立场的独立代理执行。"即使你注意到了其他维度的问题也不要报告"是一条去重边界:deep 模式下每个维度有专属评审者,跨维度报告会与别的评审者的发现重复,徒增后续验证与合并的成本。

3.2 Changes 块的二态解析规则

{changes} 注入处(第 22–28 行)自带解析规则,教子代理判别拿到的是文本还是命令:

  • Starts with ```diff / diff --git → it is the diff, use it directly
  • Shell command(s) (git diff ... / gh pr diff ... / git -C <submodule> diff ...) → run them all yourself and combine the outputs

After you have the diff, read whatever surrounding files you need for context.

注意第三句放权:拿到 diff 后可以自由读取周边文件补上下文——这与后文"Effort budget"的收敛要求并不矛盾,因为 budget 约束的是"为强化单条发现而无限扩大证据收集",而不是禁止补上下文。

3.3 强制准备:规则文件读全,路由引用按需读全

"Mandatory preparation" 段(第 30–39 行)规定了评审前的强制阅读:

Read every dimension file listed below IN FULL. Follow each file's routing table: read every routed reference required by the touched surface IN FULL, and skip unrelated routed references. Then read only the relevant sections of the external rule sources it lists (skills, docs). These files define how to check, what counts as a violation, and — equally important — what does NOT count:

{dimension_files}

Priority: repo-specific rules in those files > general experience. Use general experience only for angles the files don't cover.

对照 light-review-prompt.md 的对应段落("Read ONLY the Quick checklist section ... Skip How to check, Violations, Not violations"),可以清楚看到 deep 与 light 的分界:deep 评审者通读整个维度文件(含 How to check / Violations / Not violations / Rule sources),light 评审者只读 Quick checklist。这是"deep 模式更重"的第一处来源。

dimensions/security.md 为例,其 frontmatter 声明 verify: truecalibration_exempt: true,正文按 Quick checklist → Rule sources → How to check → Violations → Not violations 组织,与模板中"这些文件定义了怎么查、什么算违规、什么不算违规"的表述一一对应。

"repo 规则优先于通用经验"的优先级声明落实了 SKILL.md 的"规则优于模型"原则:模型只提供规则文件未覆盖视角的补充判断。

3.4 校准(Calibration):对代码库现状校准,也对生命周期校准

"Calibration (hard rule)" 段(第 41–47 行)是模板中信息密度最高的部分,包含三层规则:

第一层:对代码库现状校准,而非对理想标准校准。

Hold the diff to the standard this codebase already meets, not an idealized one. Before reporting a style/design-level finding, ask: is this pattern already widespread in the existing code, and does this diff make it worse? Widespread + not-worse → do not report.

即:先问"这个模式在既有代码里是否已经普遍存在,且本 diff 没有使其恶化";普遍存在且未恶化 → 不报。这条规则直接针对 LLM 评审最典型的误报模式——用理想化的风格标准苛责现实代码库。

第二层:豁免机制。

Dimension files may declare themselves exempt (calibration_exempt: true, e.g. security) — for those, report regardless of precedent.

维度文件可用 frontmatter 自我豁免。仓库中 dimensions/security.md 第 5 行确实声明了 calibration_exempt: true,其正文也说明"漏洞即使在其他地方同样存在也是发现,严重性不因先例降级"——同一弱点在别处存在不构成安全问题的豁免理由。

第三层:对生命周期(lifespan)校准。

Calibrate to lifespan as well: when the scope summary, PR/issue, or code comments declare the code short-lived (a time-boxed campaign, an experiment, a one-off script), judge it against its lifespan, not permanent-code standards. Hardcoded dates/copy/thresholds and low-extensibility designs are the intended trade-off for shipping fast — do not demand configurability, extension points, or expiry automation; "delete the code and redeploy when it expires" is a legitimate expiry mechanism. Two things stay reportable in temporary code: calibration_exempt dimensions (security), and damage that outlives the window (wrong billing/credit/data writes that persist after the code is removed).

短期代码(限时活动、实验、一次性脚本)按其生命周期评判:硬编码日期/文案/阈值、低扩展性设计是"快速交付"的预期取舍,"到期删码重部署"是合法的过期机制;不得要求可配置性、扩展点或过期自动化。但两类问题仍然可报:安全维度,以及会活得比窗口更久的损害(代码删除后仍持续的错误计费/额度/数据写入)。

段落末尾(第 47 行)是"聚焦优先于完备":发现必须服务于本次改动及其需求;不审计无关遗留代码,不建议超出改动范围的改写。

3.5 Review scope 硬规则:introduced 与 exposed_legacy 的三分法

"Review scope (hard rules)" 段(第 49–57 行)定义了发现的位置与"性质"标签:

  • 发现位置默认必须落在 diff 的 + 行上;
  • 遗留代码分两种处理,两者都是 nature: "exposed_legacy",由 exposure 字段区分:
    • 本 diff 触发、暴露或依赖的遗留问题 → 正常报告,位置指向相关旧代码,exposure: "triggered"scenario 说明本次改动如何使其可触发。判别测试:"没有这个 diff 时问题不可达、惰性或无害;有了它,问题可以被触发";
    • 只是顺路撞见的老问题(与本次改动无关)→ 不调查、不返回;唯一例外是明显的 p0 级生产 bug,报 exposure: "bystander" 并在 scenario 中注明这是顺路发现;
    • 其余(位置在 + 行)→ nature: "introduced",省略 exposure

紧接着第 57 行解释了这条区分的实际意义:

This distinction is not cosmetic: it decides whether the finding blocks this PR or gets handed to the code's owner as a separate task. Do not label a bystander find triggered to make it sound more urgent — an inflated exposure drags an unrelated fix into this PR and blows up its scope.

triggered 的发现会阻塞本 PR,bystander 的发现则作为独立任务移交给代码属主(对应 claude-code/main.md Step 8 的 "Offer legacy hand-off issues")。把顺路发现虚标为 triggered 会把不相关的修复拖进本 PR、放大其范围——模板明确禁止这种"制造紧迫感"。这条标签后来会被验证阶段复核:verify-prompt.md 要求对 exposed_legacy 发现强制要求具体的 before/after 触发链,拿不出就把 exposure 覆盖为 bystander,且 bystander 发现只有是明显 P0 才存活,否则判 false_positive 并在 reason 前缀 out-of-scope legacy:

3.6 Effort budget:评审者是"发现者",不是"终审者"

"Effort budget" 段(第 59–66 行):

Evidence gathering is bounded — you are a finder, not the final judge:

  • Once a finding has concrete file:line evidence, stop expanding; do not keep browsing to make it stronger.
  • Deep falsification belongs to the independent verify pass, not to you: when settling a suspicion would take more than a handful of targeted file reads, report it with your best evidence instead of running a multi-file proof campaign.
  • Read external rule sources selectively — the sections relevant to the touched surfaces — not cover to cover. Routed deep-review references selected above are still read in full.

三条收敛规则:有具体 file:line 证据即停止扩大;深度证伪交给独立的 verify 阶段,若坐实一条怀疑需要远超"少量定向文件读取",就用现有最佳证据报告而不是发起多文件证明战役;外部规则源按触达面选择性阅读(但上一段路由选定的 deep-review 引用仍须读全)。这一段与 verify-prompt.md 形成职责切分:发现便宜而宽,证伪集中而严——这正是 SKILL.md 原则 5"速度是特性(Speed is a feature)"在评审者侧的落地。

3.7 返回格式:严格 JSON 契约与逐字段语义

"Return format (strict JSON)" 段(第 68 行起)是全模板最硬的契约,也是它与 validate-output.ts 机器校验直接对接的部分。

传输格式要求(第 70 行):

Output exactly ONE JSON object inside a ```json fence (the main agent extracts and JSON.parses it). Valid JSON only: escape quotes/backslashes, no comments, no trailing commas, no single quotes.

主代理从围栏中提取并 JSON.parse——"恰好一个 JSON 围栏"由校验器的 extractJsonPayload 强制:出现多个 ```json 围栏直接抛 Multiple JSON fences found,围栏未闭合抛 JSON fence is not closed(见 validate-output.ts 第 171–185 行)。

必选字段(第 72–74 行):每个 issue 必须有 iddimensionissue_typenatureseveritylikelihoodlocationsummarycore_problemfix_cost、至少一条 fix_optionsneed_test

条件字段(第 76–81 行):

  • natureexposed_legacy 时必须有 exposurescenario
  • likelihoodlow 时必须有 scenario
  • reuse-architecture 的去重发现必须有 existing_implementations
  • 风格或约定类发现必须有 rule_source

模板给出的完整示例(第 83–103 行):

{
  "issues": [
    {
      "id": "logic-1",
      "dimension": "logic",
      "issue_type": "empty input",
      "nature": "introduced",
      "severity": "p1",
      "likelihood": "high",
      "location": "src/api/user.ts:87",
      "summary": "Batch delete accepts an empty id list and builds invalid SQL.",
      "core_problem": "Because empty input is not rejected, submitting an empty selection returns a server error.",
      "scenario": "The bulk-action UI submits after the final selected row is deselected.",
      "fix_cost": "low",
      "fix_options": ["Require at least one id in the input schema"],
      "need_test": true
    }
  ]
}

顶层可选字段(第 105–109 行):

  • missing_sources:读不到的字符串路径(读不到的维度/规则文件不静默跳过,而是显式上报);
  • release_checks:仅 release-risk 维度产出;每条必须含 itemwhyblocks_deploy
  • workflow_feedback:每条必须含 suggestionwhy,用于向技能自身反馈规则缺口(SKILL.md 的 "Keeping this skill sharp" 一节即靠这条通道把观察反馈回维度文件)。

release_checks 的定位(第 111–115 行):它是部署前确认项而非缺陷——"代码没问题,但安全上线取决于仓库里读不到的东西"(生产数据形状、某配置值是否按环境设置、队列里当前有什么)。这些条目跳过验证阶段、直接进报告作为 checklist。同时模板划了防滥用边界:不要把它当弱发现的停车场——问题在代码里就应是带证据的 issues 条目;只有当你必须猜测生产状态才能称之为 bug 时,它才是一个 check。

severity 定义(第 117–124 行):severity 只表示影响——触发时有多糟。是否阻断发布稍后由 blocks_release(在验证阶段判定)决定,绝不因为存在验收标准就抬高 severity:

  • p0:触发即生产事故(数据损坏 / 资金损失 / 鉴权绕过 / 服务不可用);
  • p1:真实 bug 或需求偏差,应在本次改动中修复;
  • p2:真实但可延期,记账(bookkeeping)级别。

likelihood 定义(第 126–134 行):severity 回答"发生了多糟",likelihood 回答"发生的频率",两者独立——只能通过手工构造请求触达的数据损坏 bug 可以是 p0 + low。判定基于真实生产路径而非理论路径:谁能触达这段代码、是否需要特殊状态或时序、上游是否通常已阻止:

  • high:正常用户路径或例行调用即触发——无需特殊布置,多数用户或请求命中;
  • medium:需要特定但现实存在的组合(较少见的选项、特定数据形状、重试、本系统里真实发生的并发请求);
  • low:需要罕见边缘——手工构造输入、产品当前无法产生的状态、需要不可信时序的竞态、不发布的环境、或依赖上游已保证不会失败的东西。

lowscenario 字段必须写明完整的前置条件链;写不出具体链条说明你在猜触发条件——要么降级发现,要么在 scenario 里明说。模板强调:不要用抬高 likelihood 来保护发现免于被降优先级,"对一个真实 bug 诚实地标 low 是好结果"。

core_problem 文风(第 136–137 行):一口气说完——"Because 〈代码/设计缺少什么〉, when 〈用户或调用方做 X〉, 〈后果〉";只有连起来读着别扭时才拆成两句(影响 + 原因)。宁可平实不要晦涩;API 名与错误字符串留在 summary 里。

issue_type 文风(第 139–140 行):精确优于宽泛("rename missed import" 而非 "code style");短优于长(动宾结构或复合名词);每条发现一个主类型,绝不斜杠并列。

无发现的返回(第 142–143 行):返回 {"issues": []}。不沉默、不寒暄。

4. 契约的另一半:validate-output.ts 把提示词规则变成机器闸门

模板的 prose 规则与 scripts/validate-output.ts 中的 zod schema 是"同一契约的两种表述"。校验侧的关键实现:

  • ReviewIssueSchema(第 12–60 行)用 .strict() 拒绝一切未声明字段,severity/likelihood/fix_cost/nature/exposure 均为受限枚举,fix_options 至少一条;
  • .superRefine(第 32–59 行)逐条实现模板的条件字段规则:exposed_legacyexposure/scenario 报错、introducedexposure 报错、lowscenario 报错、reuse-architectureexisting_implementations 报错;
  • ReviewOutputSchema(第 62–85 行)校验顶层三可选字段并做 id 唯一性检查;
  • CLI 用法为 validate-output.ts <review|verify|consolidate> [input-file],输出 Valid <kind> output,校验失败打印 zod issues 并以退出码 1 结束(第 197–220 行)。

claude-code/main.md 的 Step 3 中,这条契约被接入编排循环:每次评审者返回后用 bun run .agents/skills/deep-review/scripts/validate-output.ts review 校验围栏载荷,校验失败 → 拒绝该响应并携同一提示重新派生评审者verify: false 维度的发现直接进 reportPool,可验证发现则即时实例化 verify 提示("do not wait for other reviewers",逐维度流水线而非全局屏障)。也就是说,review-prompt.md 第 70 行"主代理提取并 JSON.parse"不是修辞,而是一条带失败重试的流水线闸门——提示词写得再严,最终由 schema 兜底。

5. 三方判定:发现进入 verify 阶段后的命运

verify-prompt.md 规定验证"独立证伪候选发现,评审与验证绝不能共用一个代理"。对每条发现,验证者须:打开位置读足周边上下文;追调用方、类型、校验与测试;先找反例(上游保证、提前返回、框架行为、既有校验);校验 natureexposure 标注(可用 exposure_override 纠正);用 git log -L/git blame 归因确认的遗留代码;对 likelihood 与 severity 施加覆盖(likelihood_override/severity_override);最后套用代码库与生命周期校准——"普遍且未恶化"或对声明短期代码套用永久代码标准的,判 false_positive 且 reason 以 over-scrutiny: 开头。

每条输入 id 必须恰好出现一次,且只能用所选判定对应的字段:

  • confirmedidverdictevidencecan_auto_fixblocks_releasecan_auto_fix 为 false 时必须附 auto_fix_reason;可选覆盖字段 severity_override/nature_override/exposure_override/likelihood_override/fix_options_override
  • false_positiveidverdictreason
  • need_more_contextidverdictmissing

这套三方判定正是 SKILL.md 防幻觉原则中"三方判定优于置信度百分比:听起来经过校准的分数作为硬过滤器不可靠"的落地——review-prompt.md 产出的是候选,只有 survived falsification 的发现才进入报告。can_auto_fix 也有硬边界(低修复成本、唯一显然的修法、无需外部资源或产品决策、触及文件少于 3 个且不涉及架构层/数据库 schema/外部契约/用户可见行为/路由/热键/文案/权限边界),release-riskexposed_legacy 发现永远不是自动修复候选;blocks_release 则要求 P0 必阻断、P2 必不阻断、低 likelihood 仅在影响灾难性且不可逆时阻断。

6. 与 light 模式提示的对照:同骨架、不同深度

light-review-prompt.md 与 review-prompt.md 共享大量骨架:同样的四占位符实例化、同样的 Changes 二态解析、同样的校准三层规则与"聚焦优先于完备"。差异恰是两种模式的分界:

方面 review-prompt.md(deep) light-review-prompt.md(light)
准备阶段 通读全部维度文件 + 触达面要求的路由引用 + 外部规则源相关章节 只读 Quick checklist 段(含嵌套示例小节),其余段落只在清单条目含糊时查
范围规则 introduced/exposed_legacy + triggered/bystander 结构化标签 散文式:"问题在未改代码中时不当作本次修复项",可用 git blame/git log -L 点名引入者
标签 nature/exposure/severity(p0–p2)/likelihood 进 JSON Severity、Introduced-or-pre-existing、Likelihood 写进 Markdown 正文
输出 严格 JSON(供验证/合并/报告流水线消费) 普通 Markdown 评审,"not JSON and not a structured deep-review report"
后续 独立 verify 阶段逐条证伪 无 verify 阶段;主代理不得丢弃、降级或重验发现
Effort budget 有(发现者定位) 只有"有 file:line 证据即停"一条

从两文件的对照可以看出 deep 模式的"重"并非多审一遍,而是把评审结果结构化为可被机器消费(校验、去重、合并、统计)的中间产物。

7. 在编排手册中的实际调用位置

claude-code/main.md 给出 deep 模式的端到端步骤,review-prompt.md 在其中的位置:

  • Step 0:按 scoping.md 产出 {changes}、≤ 200 词范围摘要与 PR 元数据;
  • Step 1:应用 SKILL.md 的剪枝表(每个被跳过的维度记一句原因),检测 deep-review-* 扩展包,收集内置 + 扩展路径;
  • Step 2:在同一个响应里并发启动全部选中维度,每维度一个 Task——"Instantiate ../review-prompt.md with {dimensions}, {dimension_files}, {scope_summary}, and {changes}. Use description: review: <dimension> and subagent_type: general-purpose";
  • Step 3–8:校验/验证 → 同根因合并(≥ 2 条 confirmed 才触发)→ 按 report-template.md 渲染报告 → 提供安全批量修复 → 逐条决策 → 遗留问题移交。

Codex 环境走 codex/main.md,同一模板以"每子代理打包多个维度"的方式实例化。SKILL.md 同时规定了预算纪律:同一逻辑需求内 deep 模式默认至多运行一次,修复后复核、rebase、上下文压缩后恢复会话都走 light 模式。

8. 设计要点总结

review-prompt.md 全文与配套实现可以提炼出五条可复用的多代理评审设计决策:

  1. 提示必须自包含——子代理不继承任何会话上下文,范围摘要、diff、规则文件路径全部注入提示;这是"反幻觉"的第一道防线(只看到 diff 片段的评审者会发明 bug);
  2. 校准是硬规则而非建议——对代码库现状校准、对生命周期校准、安全维度豁免,三者共同压制 LLM 评审的高误报模式(理想化标准苛责现实代码、要求短期代码具备永久代码的扩展性);
  3. 结构化性质标签防止 PR 范围蔓延——introduced/exposed_legacytriggered/bystander 决定发现是阻塞本 PR 还是移交代码属主,模板明言禁止虚标 exposure 制造紧迫感;
  4. 发现与证伪分离——评审者是"发现者不是终审者",effort budget 有界,深度证伪集中在独立 verify 阶段的三方判定中完成;
  5. 提示词契约 + schema 闸门双保险——严格 JSON 返回格式既写在提示里(第 68 行起),又由 validate-output.ts.strict() schema 与条件校验强制执行,失败即重派生;条件字段规则(exposed_legacy 必带 exposure+scenariolow 必带 scenario 等)在两侧逐条对齐。

9. 延伸阅读(仓库内)

登录后查看全文
热门项目推荐
相关项目推荐