跳转到内容

对抗式审查方法论

对抗式审查方法论

学习目标

  • 理解 Doubt-Driven Development 与事后审查(/review)的本质区别
  • 掌握 CLAIM → EXTRACT → DOUBT → RECONCILE → STOP 五步循环的每步关键约束
  • 理解为什么 DOUBT 步骤中不能传递 CLAIM
  • 学会识别”Doubt Theater”反模式

前置知识

本章涉及对抗式审查的通用原理,建议先阅读:

下文直接聚焦 agent-skills 的具体实现。

项目实践

飞行中审查 vs 事后审查

agent-skills 项目将审查分为两种截然不同的模式:

维度Doubt-Driven(飞行中)/review(事后)
时机决策做出后、成本高之前工件完成后、合并前
对象单个非平凡决策完整的变更集
审查者新上下文的独立审查者有完整上下文的评审者
目标在方向还可便宜修正时发现问题判断是否批准合并
成本每决策一次循环每 PR 一次审查

关键洞察:Doubt-Driven 不是 /review 的替代品,而是其补充。两者结合使用的效果最佳——Doubt-Driven 在飞行中捕获方向性错误,/review 做最终的质量判断。

DOUBT 步骤的关键约束

DOUBT 步骤中有一个最关键也最容易违反的约束:

只传递 ARTIFACT + CONTRACT,不要传递 CLAIM。

✅ 正确:
ARTIFACT: <缓存层代码>
CONTRACT: <规格中关于线程安全的要求>
→ 审查者独立判断代码是否满足规格
❌ 错误:
CLAIM: "这个缓存层是线程安全的"
ARTIFACT: <缓存层代码>
CONTRACT: <规格要求>
→ 审查者被 CLAIM 偏向同意

原因:心理学中的”锚定效应”——当你告诉审查者”作者认为这是安全的”时,审查者会更难找到问题。审查者需要独立判断工件是否满足契约,而不是验证作者的结论是否正确。

RECONCILE 的优先级分类

审查者的发现按以下优先级顺序分类(第一个匹配的类别胜出):

优先级类别处理
1合同误读修复合同,下一轮重新分类
2有效 + 可行动修改工件,重新循环
3有效权衡显式记录,让用户看到
4噪声记录并继续,思考是否该把上下文加入合同

关键原则:重新阅读工件文本再分类——橡皮图章式接受审查者的发现和直接忽略它一样是失败模式。

Doubt Theater 反模式

可检查的信号:在 2 轮或更多轮循环中,审查者发现了实质性问题,但零个被分类为可行动的。

你在做验证,不是在做质疑。停止并升级。

为什么这是一个独立的反模式:它看起来像是在做正确的事(运行审查循环),但实质上是在寻找确认而非证伪。这比直接跳过 Doubt 步骤更危险,因为它有正确的外壳但没有正确的实质。

跨模型升级的交互约束

agent-skills 对跨模型升级有严格的交互约束:

  • 交互式会话:始终提供选项,禁止静默跳过
  • 即使工件看起来风险很低,也必须提供选项
  • 用户决定——不是 Agent——是否值得这个成本
  • 每次调用都是独立的授权,不能因为用户上次同意就自动再次调用

问题与规避

陷阱表现对策
传递 CLAIM 给审查者审查偏向同意,找不到问题严格只传递 ARTIFACT + CONTRACT
审查者提示不够对抗”这样好吗?” → 平衡报告使用”找出问题”的对抗性提示
超过 3 轮循环无限递归,浪费 token3 轮后必须停止并报告用户
Doubt Theater看起来在做审查,实际在验证检查 actionable 分类比例,<20% 时停止
静默跳过跨模型用户不知道错过了什么在输出中显式宣布跳过

设计取舍

为什么设置 3 轮上限而不是持续循环直到”满意”?

没有上限的循环会无限消耗 token 和时间。3 轮是经过验证的平衡点——足够捕获大多数问题,又不会陷入无意义的细枝末节。如果 3 轮后仍有实质性问题,说明工件可能不适合审查流程(太大了,需要分解),而不是需要更多轮审查。

为什么不在非交互式上下文中自动调用跨模型?

自动调用外部 CLI 有两个风险:(1) 用户可能没有安装或配置该工具,导致错误;(2) 工件可能包含恶意的提示注入内容,外部 CLI 可能执行它。因此必须用户授权。

参考来源

  • 源码验证: skills/doubt-driven-development/SKILL.md — 完整的五步循环和反合理化表
  • 源码验证: references/orchestration-patterns.md — 编排模式目录