Fresh Eyes Review(换个脑子审一遍)
这个 skill 解决什么
刚写完的东西,自己再读一遍基本没用 —— 因为自审用的还是同一个脑子里的同一套想当然,第一遍没看出来的地方,第二遍照样看不出来。实测数据支持这一点:把同一处错误分别以"外部注入"和"模型自己产生"两种身份给模型,14 个模型呈现 64.5% 的自我纠错盲区(能力在,但"自己错的时候"不被激活)。
所以本 skill 做三件事:
- 用 DSH 原生的
subagent(spawn)起一个空对话的审查者 —— 它没有你的上下文,被迫从产物本身重新理解; - 强制它交出可复现的证据,而不是"建议考虑"这类判断;
- 修完用反向验证收口:把 bug 装回去,测试必须变红。
边界(很重要,别对外夸大):这不是"多一个 AI 更安全"。对照实验(29 名专家、50+ 小时)显示,多一个 LLM 审查者并不会提高高危缺陷的捕获率,还会带来锚定效应。价值全在三处:审查者能真的跑命令 + 强制它交证据 + 收口动作能变红。市面上没有任何 AI 审查产品要求"复现命令 + 实测输出",这三条才是差别。
什么时候用 / 不用
用:
- 改动会碰数据、凭据、权限,或者不可逆(删库、发版、迁移、改配置)
- 跑在无人值守的地方(定时任务、看门狗、同步脚本、自动清理)
- 你已经答不出"我怎么知道它真的在跑"
- 用户明确要求审查、复核、找 bug
不用:
- 一次性的小脚本、临时排查(跑一次就扔,错了当场就看见)
- UI 微调、文案、肉眼一看就知道对错的改动
- 需求还没定清楚 —— 先对齐再互查,否则两边一起跑偏
流程
第一步:收集材料
子 agent 是空对话,你脑子里的事情它一概不知道。所以先把这几样列出来(缺的写"未提供"):
- 工作目录的绝对路径
- 改动范围:
git diff --stat/ 文件清单 / commit 范围 - 想达成什么:一句话验收标准
- 能跑什么:测试、构建、复现入口
- 证据文件写到哪:指定一个目录(如
<仓库>/.review-evidence/),让它把每条复现命令的原始输出落盘、首行写[exit code: N],报告里只写路径 - 临时产物写到哪:指定一个仓库外或明确被忽略的目录(如
<仓库>/.tmp-review/或系统临时目录),并要求它设PYTHONDONTWRITEBYTECODE=1、不要在 skill 目录或仓库里留下__pycache__、样例文件、临时脚本
不要写进"我为什么这么写"。那会把你的假设一起传染给它,等于把独立性抵消掉。
但要写「哪些已经定死了」。 这两件事容易被混为一谈,区别很重要:
| 该藏起来的 | 该给它的 |
|---|---|
| 你的推理过程("我认为这样是对的,因为…") | 范围、验收标准、环境约束 |
| 具体某处代码的自我辩护 | 有出处的决策记录(谁定的、在哪儿定的) |
想把后者写清楚、又不越界变成「封口」,用 references/handoff-template.md 落成 <工作目录>/.review-handoff.md。它在首轮其实就有用(避免审查者在已知取舍上白费力气),在第四步的模式 C 里则是必需——第二轮必须知道第一轮说了什么才能去怼它。
第二步:委派一个空对话的审查者
用 subagent,它默认 provider 就是 spawn:
subagent(
description = "独立审查 <模块名>",
prompt = "<references/reviewer-prompt.md 填满后的全文>",
run_in_background = false
)
五条硬性注意:
- 必须是空上下文的子 agent:DSH 里就是
subagent(spawn);不要用subagent_fork—— 它以父级已完成轮次作初始内容,你的对话历史会被送过去,独立性当场归零。 ⚠️ 术语陷阱:Claude Code 的context: fork意思是"派生一个隔离上下文",与 DSH 的subagent_fork(继承父级对话)含义正好相反。移植到别的平台时,先确认那里的 "fork" 是隔离还是继承。 - 父级只收到它的最终输出。 它跑命令的中间过程不会回传,所以证据必须落盘成文件并在报告里写明路径 —— 这正是模板里那四个字段存在的原因。
- 审查者只读,不改文件。 修是编排者(你)的事;审查者一旦动手改,它就从"独立审查"变成了"又一个人"。
- 提示词必须自足。 用
references/reviewer-prompt.md,把<...>全部填掉再发。 - 想进一步拉开独立性:调用时带
provider/model/reasoning_effort换一个模型。同一模型的另一个上下文已经能拿到大部分收益(盲区来自"身份"而非权重),换模型是加分项,不是必需,也不是不装的借口。
它会继承你的工作目录和工具,所以它能自己去读文件、自己跑测试 —— 让它跑,别替它跑。
关于"退回补证据"怎么落地:前台(run_in_background = false)起的 subagent 结束后不会留下可寻址的 agent id,send_message 无处可发 —— 不要设计成"叫同一个审查者补证据"。两种可行做法:
- 推荐:重开一个空上下文的审查者,把原报告一起给它,明确"只许补证据、不许重报、不许改结论"。这样既拿得到补充材料,又不破坏独立性(把原报告给它带来的锚定,比你直接把结论喂回去小得多)。
- 或者后台起(保留 id 以便追问),但要接受它已经看过你的上下文之外的东西、且会话还在,独立性略降。
不论哪种,都要在最终记录里注明哪几条是原证据、哪几条是后补的 —— 补出来的证据强度不如当场跑出来的。
第三步:过滤 + 收口
1. 先过格式门禁。 把它的报告存成文件,然后:
python "<skill-dir>/scripts/check_review_report.py" <report.md> # 默认:查格式与证据文件可用性
python "<skill-dir>/scripts/check_review_report.py" --pre-fix <report.md> # 改之前跑:重跑「反向前置」,必须仍然失败
python "<skill-dir>/scripts/check_review_report.py" --replay <report.md> # 改之后跑:重跑复现命令并与证据文件 diff
# 模式 C(对抗性复审)——第二轮:
python "<skill-dir>/scripts/check_review_report.py" --falsify --handoff .review-handoff.md <round2.md>
退出码:0 每条都带齐证据 / 1 有条目不合格 / 2 报告读不了(缺文件、未知参数、编码解不开;--pre-fix 与 --replay 同时出现也退 2)。
三档的区别是关键:默认档只查"写了没有"(含证据文件在不在、首行是不是 [exit code: N]、位置真不真);--pre-fix 档在动手修之前跑,重跑每条的「反向前置」命令并要求它仍然失败;--replay 档在修完之后跑,重跑复现命令并与落盘证据逐行比对。
- 默认档 0 分不代表内容为真 —— 你可以编一段输出,它照样放行。
--pre-fix0 分才叫"缺陷真的被观察到失败":修之前先跑一次,跑不红就别修。--replay0 分才叫"这条证据是真的跑出来的",而且现在还能跑出同样的结果。
两条命令、两个时刻,别搞混:--pre-fix 是改之前(要求失败),--replay 是改之后(要求一致)。同一个报告先过前者、修完再过后者,这条发现才算走完——先红后绿。
可选参数:--workdir DIR(默认报告所在目录)、--timeout SEC(默认 120)、--strict(缺严重度、位置没行号、位置指向不存在的文件、缺少反向前置这类提醒也计为不合格)。
门禁还会顺手核实「位置」是不是真的。 它从位置里解析出 路径:行号,检查文件在 --workdir 下存在、且行号不超过文件总行数(只对代码类后缀做这件事,文档类审查不会被误伤)。默认档只提醒,--strict 才算不合格——因为报告可以合法地引用 --workdir 之外的路径。
为什么值得加这一条:重放只能证明「命令能跑、输出和证据文件一致」,完全无法证明「被指控的文件和行号真的存在」。 实测过一种攻击:位置写成 src/does_not_exist.py:9999,命令和证据全部合规,重放档照样给绿——而幻觉路径恰恰是 LLM 的典型失败模式。这类机械可查的东西不该推给人。
「反向前置」是治「命令没有证明力」的那味药。 门禁验不了"这条命令是否真的触及被指控的代码",但它能验一件更硬的事:你声称有缺陷,那就得给出一个在有缺陷的代码上会失败的命令,而且退出码必须非零。
它堵住了哪一半、没堵住哪一半(都是实测过的):
- ✅ 证据文件记成
[exit code: 0]的恒真证据,四个档位全部拦下。 记成 0 等于自认「命令在缺陷代码上通过了」=缺陷不成立,这是硬失败。 - ✅
--replay会重跑反向前置命令并要求它已经通过(先红后绿的绿半边)。所以「修完之后前置命令仍然失败」会被抓住——修复没完成,或那条命令与缺陷无关。 - ❌ 把前置证据的退出码伪造成
[exit code: 1]、命令本身却是恒真的,只有--pre-fix抓得住(因为只有它会在改之前真的重跑)。默认档、--strict、--replay都会放行。
这条决定了工作流:
--pre-fix不是可选项。任何一条发现,都要在动手改之前先跑一次--pre-fix;只跑--replay就相当于放弃了红半边,上面那个伪造缺口就一直开着。
四种攻击姿态 × 四个档位的实测防线(✅ 拦下 / ⚠️ 放行):
| 攻击姿态 | 默认 | --strict |
--replay |
--pre-fix |
|---|---|---|---|---|
| 位置指向不存在的文件/行号 | ⚠️ | ✅ | ✅ | ⚠️ |
| 跑一条与发现无关的命令(前置也是无关的失败) | ⚠️ | ⚠️ | ✅ | ⚠️ |
| 证据只留输出的一行(选择性摘录) | ⚠️ | ⚠️ | ✅ | ⚠️ |
| 恒真命令 + 证据记成 exit 0 | ✅ | ✅ | ✅ | ✅ |
| 恒真命令 + 把前置证据伪造成 exit 1 | ⚠️ | ⚠️ | ⚠️ | ✅ |
注意 --replay 之所以能拦下「位置不存在」和「无关命令」,靠的是它的两个附加校验(位置可核实性 + 前置命令必须已转绿),不是靠重放本身。
别误读这张表:--pre-fix 不是万能的,它只回答"你给的前置命令现在失败吗"。「碰巧失败的无关命令」仍然能骗过它 —— 那条命令在改前改后都失败,四个档位里只有 --replay 会因为「前置没转绿」而拦下它,而当作者真的把缺陷修好、只是命令选得无关时,就只剩人判断了。要问的还是那句:这条命令跑在「有问题」和「没问题」两种代码上,输出会不一样吗?
门禁接受模板里的所有自然写法:- 位置:…、- **位置**:…、location: …,值可以写在标签同一行,也可以写在下面几行(多行命令、围栏里的真实输出都算)。
报告读不了(exit 2)时先修编码:GBK / UTF-16 会被自动识别并提示转存 UTF-8;真正解不开的文件会明确报错,不会静默给一个错判。
⚠️
--replay不是沙箱。 它会在你指定的目录里执行报告里写的命令,只有一层"防手滑"拒绝表和超时。只在你自己读过、且愿意让那些命令碰过的报告上开。
2. 分流与退回话术见 references/anti-patterns.md。三要素不齐的条目,退回(按第二步说的重开一个审查者)或直接丢弃,绝不凭它改代码。重放不一致的条目升级给人判断 —— 可能是环境差异,不要直接当造假。
3. 由你来修,每修一条补一个断言。 断言写进项目既有的测试文件(照该项目已有的约定与命令);项目没有测试约定时,先建一个最小测试文件,并在交付说明里写清它的路径和运行命令 —— 不要往 skill 目录或 node_modules 里塞测试。
4. 然后反向验证。这一步不是可选项,是收口动作本身。 把 bug 故意装回去,测试必须变红。
- 红不了 → 说明断言没咬住,继续改断言,不是继续改代码;没演示过变红,就不算修完。
- 这一步是整套流程里最值得优先做的那一条:它把"有人看过"变成"机器以后一直看着"。
- 它专门补掉门禁的一个洞:门禁能验「证据真的跑出来了」,但验不了「这条命令对结论有没有证明力」——跑一条恒真命令(
assert True)配上合规的证据文件,门禁会放行。断言能不能变红,是唯一能拦住这种情况的东西。 - 收尾核对一遍工作目录:没有留下临时脚本、样例文件或
__pycache__。
5. 最后你自己只看两件事:证据能不能重现、这条要不要接受。这就是人类仲裁,本来就该你做。
第四步(可选,价值最高的一轮):对抗性复审
⚠️ 这一轮默认不跑,而且要人点头
默认只跑首轮。 对抗性复审要多花一个子代理的时间(实测量级:3–6 分钟),该不该花是人的决定,不是你的。
你(执行者)不得自行升级到多轮。 只有人在对话里明确说过(「开第二轮」「再复审一下」「我不放心这个改动」),你才能进这一步。
门禁会拦这件事:交接文档必须声明审查模式(
审查模式:首轮/审查模式:首轮 + 对抗性复审(用户已确认))。声明为「首轮」却跑--falsify,直接退 2。所以「偷偷升级到多轮」在机械上是做不到的。
前提:第一轮走了、而且你有理由认为它可能报错。代价:再一轮的时间与 token。什么时候值得:改动碰数据/凭据/权限/不可逆操作,或者夜里无人值守跑。
这一轮问的问题和首轮完全不同:不是「这段代码有什么问题」,而是「上一轮那份报告,哪一条是错的」。理由:一次自信的错误发现,下游代价最大 —— 它会让人去改本来没错的代码。而首轮的审查者自己不会知道自己报错了,只有第二个审查者能把它按下去。
流程:
- 先写交接文档
<工作目录>/.review-handoff.md,用references/handoff-template.md。它是写给审查者的简报:范围、环境约束、已定取舍(每条必须带出处)、以及上一轮已驳回的发现及其理由。- 为什么必须有它:审查者是空上下文的,它不知道哪些是已经定死的取舍,会把它们当缺陷报上来、还认真复现一遍 —— 那是真金白银。
- 为什么它危险:写它的人正是被审的人。所以每条取舍必须带出处(
HumanDecision/RecordedDecision/OrchestratorClaim),且必须写成「影响边界 + 请只报哪类」而不是「别管」。门禁会逐条检查出处。
- 委派第二个空上下文审查者,用
references/adversarial-reviewer-prompt.md。给它:上一轮报告、交接文档、工作目录,并要求它动手重跑上一轮的命令。换一个模型更好(同族模型共享盲区)。 - 过门禁:
--falsify --handoff .review-handoff.md。它会检查第二轮报告是否分齐三段(确认成立 / 驳倒 / 未决)、每条是否带判定标注,以及交接文档的取舍是否都有出处。
第二轮报告不走发现块那套格式 —— 它判的是报告,不是代码,所以不该被逼着为每条都造一个新证据。但它必须说清:每条旧发现是确认、驳倒还是未决。
铁律
- 没有复现命令和证据的条目 = 意见,不是发现 → 丢弃。
- 跑不了就说跑不了。编造输出比不报更糟 —— 而且现在会被
--replay抓住。 - 只报问题,不报夸奖。
- 收口永远是"装回去必须变红",而且要当场演示。没演示过变红,就不算修完。
- 用空上下文(spawn),不用继承上下文(DSH 的
subagent_fork)。注意别的平台 "fork" 可能含义相反。 - 审查者只读,不改文件;修和补断言都是编排者的事。
- 收尾不留临时产物。
- 重放一致只证明"证据是真的",不证明结论正确;重放不一致要升级给人,不是自动定罪。
- 位置必须真实存在。 门禁会核实(
--strict下算不合格)——被指控的文件都找不到,后面的证据再漂亮也是空的。 - 每条发现都要有「反向前置」:一个在有缺陷的代码上会失败的命令,退出码非零。 门禁会查这条证据的退出码(记成 0 直接判不合格,等于自认命令通过了)。先跑
--pre-fix看它红不红,再动手修 —— 跑不红就别修,先怀疑这条发现。 - 「这条命令凭什么能证明这个结论」永远要人判断。 门禁能验「命令失败了、而且失败得可复现」,验不了「它的失败指向那条结论」。跑一条碰巧失败的无关命令,仍然能骗过它。
更省的一档(连审查者都不开)
只保留第三步里的两件事:每处改动配一个能变红的断言,外加问自己一句"我怎么知道它真的在跑?"
有实证支持这一档:抬高上限的是可执行的判据,第二个模型主要是帮你找到"该加哪条判据"。所以在预算紧张或者任务很小的时候,退到这一档是完全合理的,不用有负担。
Resources
scripts/check_review_report.py
审查报告的门禁,四档:
- 默认档:查格式。每条发现是否带齐「位置 / 复现 / 证据(内联实测或证据文件)」与「反向前置」,证据文件在不在、首行是不是
[exit code: N],反向前置证据的退出码是否非零,以及**「位置」指向的文件是否真的存在、行号是否在文件范围内**(后两项之外,位置与缺失反向前置只提醒,--strict下才算不合格;反向前置证据记成 0 是硬失败)。 --pre-fix档(改之前跑):重跑每条「反向前置」命令,要求它现在仍然失败。跑绿了就说明缺陷复现不了 —— 先别修,回去看这条发现是不是真的。--replay档(改之后跑):重跑每条复现命令,把真实输出与落盘证据归一化后逐行比对(时间戳、耗时、uuid、临时路径、pid、地址会被折叠);同时重跑反向前置命令并要求它已经通过,补上「先红后绿」的绿半边。退出码一致、输出一致且前置已转绿才算过。--falsify档(模式 C,必须配--handoff):校验对抗性复审报告——三段(我确认成立的 / 我驳倒的 / 未决)是否齐、每段是否至少点名了一条上一轮发现、判定条目是否带标注;同时校验交接文档——## 范围与## 已定取舍两个小节是否各自都在、取舍条目是否每条都带出处(出处必须紧跟在依据:之后)。第二轮判的是报告不是代码,所以它不走发现块那套格式。--falsify与--pre-fix/--replay同给会退 2 —— 它不走证据重放,静默忽略等于报了一个「验过了」的假信号。
退出码:0 全合格 / 1 有不合格 / 2 报告或交接文档读不了、用法错误。可以直接当 CI 门禁用 —— 它自带回归套件(见下),所以"退出码语义"是被断言钉住的,不是口头约定。报告格式由 references/reviewer-prompt.md 规定,两者是配套的,改格式要同时改这几处(SKILL.md、模板、门禁),并跑一遍回归。
改门禁的规则,必须配定向变异:把新规则删掉,确认套件真的变红。因为「校验器会打印提醒」和「校验器会让它不合格」是两件事 —— 这个项目里已经栽过两次(--strict 漏计数、--falsify 整套规则没被任何断言覆盖,前者靠人读代码发现,后者靠独立审查者做定向变异发现)。
--pre-fix与--replay都不是沙箱:它们执行报告里写的命令,只有拒绝表与超时。只在你读过、且愿意让那些命令碰过的报告上开。重放一致 ≠ 结论正确;重放不一致 ≠ 造假(可能是环境差异)——升级给人判断。
python "<skill-dir>/scripts/check_review_report.py" <report.md>
python "<skill-dir>/scripts/check_review_report.py" --pre-fix [--workdir DIR] [--timeout SEC] <report.md>
python "<skill-dir>/scripts/check_review_report.py" --replay [--workdir DIR] [--timeout SEC] <report.md>
python "<skill-dir>/scripts/check_review_report.py" --falsify --handoff FILE <round2.md>
python "<skill-dir>/scripts/check_review_report.py" --strict <report.md> # 提醒也算不合格
scripts/test_check_review_report.py
门禁的回归套件:70 条断言,覆盖这条流水线上真实踩过的坑(末条发现被尾部小节补齐、散文报告靠"无问题"子串蒙混、GBK/UTF-16 误杀、加粗标签被误判、多行证据被判为空、填充词当证据、未能执行 的原因阈值、悬空证据文件、证据文件缺退出码首行、位置指向不存在的文件、位置行号超出范围、含空格路径、非代码后缀写在前面导致的整体绕过、URL 不被当成文件、无目录的代码文件名、反向前置证据记成 0、缺反向前置证据、缺反向前置字段、反向前置写「未能执行」、--pre-fix 下缺陷复现不了、--pre-fix 与 --replay 互斥、反向前置命令同样受拒绝表约束、--replay 下前置命令必须已转绿、交接文档缺出处 / 缺取舍条目 / 文件不存在、--falsify 缺三段 / 缺判定标注 / 必须配 --handoff、重放不一致/退出码不一致/命中拒绝表/超时、易变内容归一化……)。夹具现造,不依赖任何外部文件。
改完门禁必须跑它,且必须全绿;全绿代表"门禁行为与文档一致",不代表某份具体报告合格。要加新规则,先在这里加一条会红的断言。
python "<skill-dir>/scripts/test_check_review_report.py"
python "<skill-dir>/scripts/test_check_review_report.py" --only <用例名> --skip-harness # 秒级
--only <名字> 可重复,配合 mutation_check.py --quick 用来把「跑一次」从 11 秒压到 1 秒以内。
references/reviewer-prompt.md
首轮要给子 agent 的完整提示词模板,含强制输出格式(六个字段,含反向前置及其证据 + 证据文件的 [exit code: N] 约定)与八条规矩。每次委派前读它、填掉 <...>。
references/handoff-template.md
交接文档模板(模式 C 的前提)。它是执行者写给审查者的简报:范围、环境约束、已定取舍(每条带出处)、上一轮已驳回的发现及其理由。三条硬规矩写在里面 —— 尤其「取舍必须写成可证伪 + 有边界,不能写成别管」,因为写这份文档的人正是被审的人。
references/adversarial-reviewer-prompt.md
**模式 C(对抗性复审)**的提示词。它问的问题和首轮完全不同:不是「这段代码有什么问题」,而是「上一轮那份报告哪一条是错的」。配套的三段式输出格式(确认成立 / 驳倒 / 未决)与规矩都在里面。
scripts/mutation_check.py
定向变异测试:把门禁的每条规则逐条删掉/改坏,确认回归套件真的变红。
为什么它是必需品:「校验器会打印提醒」和「校验器会让它不合格」是两件事。 这个项目栽过两次 —— --strict 漏计数(规则形同虚设),以及 --falsify 整簇规则没有任何断言覆盖(删掉照样全绿)。两次都是变异测试发现的。
python "<skill-dir>/scripts/mutation_check.py" --quick # 约 4 秒:只跑受影响的用例
python "<skill-dir>/scripts/mutation_check.py" # 全量套件,提交前跑
改了门禁规则就在这里补一条变异。 加进来的变异如果存活,说明那条规则没被钉住。
references/anti-patterns.md
收到无效发现时的分流表、六种最常见的噪声、可直接照抄的退回话术、退出码与 --replay 边界怎么读,以及"别指望多一个 AI 提高高危捕获率"的实证依据。
这套东西的来历(被问到时的说法)
它不发明零件。 独立审查者、强制证据、变异收口、程序化门禁这四件事,单独都有人做过,而且有些做得更深:
momomuchu/make-no-mistakes——context: fork+ 禁写工具做结构性独立;scripts/mutate.py真做单点变异写回源文件重跑,存活率过高直接 FAIL;10 级门禁阶梯。QwenLM/qwen-code的 autofix —— reproduce-before-fix、修复前测试必须本来就是红的(REJECTS the round if none of them fails there)、提交前 mutation probe。andrewstellman/quality-playbook—— 强制BUG-NNN.red.log/.green.log落盘,且有"重跑同一条命令与落盘文件 diff"的防伪造机制;那层机制是因为真发生过模型把自己编造的期望输出写进证据文件的事故才加的。Kappaemme-git/codex-bug-reproducer——Never claim a bug from code inspection alone,复现输出落盘 JSON 并比对修复前后。- DSH 生态的
PerryLink/dsh-doublecheck(四阶段交付门禁、退出码 0/1/2、red/green 证据门)与joekytc/dsh-swarm(validateReviewEvidence;它自己在 Known limitations 里写了 "Review evidence is existence-checked, not replay-proven")。 - 官方
anthropics/claude-code的code-review—— 独立 agent 结构正规,但靠 0–100 置信度阈值过滤误报,并明文写着不要跑 linter 去验证。
本 skill 只 claim 那个窄口子:对一份审查报告本体跑校验器,并按条目重放它的证据。我没有找到同时做到这一点的实现;如果你知道有,请开 issue 告诉我。
机制上的祖先是 N-version programming / design diversity(Avizienis 1985)与 IV&V(IEEE 1012);LLM 时代的工程结论来自 Anthropic 的多智能体工程博客(多智能体约 15× 聊天 token)与 Cognition 的《Multi-Agents: What's Actually Working》(审查者事先不共享上下文时效果最好;有效形状是"写入单线程、其他 agent 只贡献判断力")。
两条必须一起说的反证:
- Knight & Leveson 1986(DOI
10.1109/TSE.1986.6312924)证明"独立开发"的软件版本仍会共同失效 —— 隔离不等于错误不相关。要真正的独立性得换来源(模型族、上下文、提示词框架),不能只换数量。 - 多一个 LLM 审查者不会自动提高高危缺陷的捕获率(29 名专家 / 50+ 小时对照实验,arXiv
2411.11401,还带锚定效应)。真正抬高上限的是"能跑命令 + 强制可重放证据 + 反向验证收口"。