| name | doubt-driven-development |
| description | 对抗自审 — 在非平凡决策前触发魔鬼代言人式自我审查,防止幻觉和未验证断言流入输出。 |
Doubt-Driven Development (对抗自审)
集成自「思维六维」中的 Doubt-First(对抗自审) 维度。
核心原则:输出前,先成为自己的敌人。
触发条件 (WHEN to trigger)
当输出包含以下任一情形时,必须启动 doubt cycle:
| 触发类型 | 示例 |
|---|
| 事实性断言无来源 | "该 API 在 v3.2 中已废弃" — 你确定?来源? |
| 架构决策 | 选择 Redis over PostgreSQL 作为 queue — 有没有反面论据? |
| 安全相关变更 | 修改权限模型、认证逻辑、加密方案 |
| 因果推断 | "性能下降是因为 X" — 有没有混淆 correlation/causation? |
| 不可逆操作建议 | 数据库 migration、文件删除、生产部署 |
| 否定用户假设 | 告诉用户他们的理解有误 — 你自己确定没错? |
不触发条件 (Anti-patterns — 不要怀疑这些)
以下情形跳过 doubt cycle,避免 analysis paralysis:
- ✅ 代码格式化、linting 修复
- ✅ 显而易见的事实("Python 是解释型语言")
- ✅ 用户明确要求的简单操作("帮我重命名这个变量")
- ✅ 已通过工具验证的结果(grep 搜索结果、API 返回值)
- ✅ 纯粹的风格偏好("用 camelCase 还是 snake_case")
- ✅ 重复之前已验证过的结论(同一会话内)
判断准则:如果错了,后果是什么?后果可忽略 → 跳过。后果严重 → 触发。
执行流程 (HOW to execute)
┌─────────────────────────────────────────┐
│ 检测到触发条件 │
└──────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ PAUSE: 暂停输出,进入 doubt mode │
└──────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ 运行 Devil's Advocate Checklist │
│ (见下方) │
└──────────────┬──────────────────────────┘
▼
┌──────┴──────┐
│ 质疑成立? │
└──────┬──────┘
YES ╱ ╲ NO
▼ ▼
┌────────────┐ ┌────────────────┐
│ 修正结论 │ │ 标记 [实锤] │
│ 或标记 │ │ 继续输出 │
│[UNVERIFIED]│ └────────────────┘
└─────┬──────┘
▼
再次进入 checklist (max 3 cycles)
最多 3 轮 doubt cycle
- Cycle 1: 基础质疑 — 来源、逻辑、替代解释
- Cycle 2: 深度质疑 — 边界条件、隐含假设、时效性
- Cycle 3: 终极质疑 — "如果完全相反会怎样?"
- Cycle 3 后: 强制 commit,用当前最佳证据输出结论
超过 3 轮 = diminishing returns。做决定比无限犹豫更有价值。
Devil's Advocate Checklist (魔鬼代言人检查清单)
每轮 doubt cycle 中,依次过以下问题:
1. Source Check (来源审查)
2. Alternative Explanation (替代解释)
3. Fragility Test (脆弱性测试)
4. Confusion Check (混淆排查)
5. Reversibility Check (可逆性检查)
输出标记 (Output Tagging)
根据 doubt cycle 结果,在输出中使用标记:
| 标记 | 含义 | 使用场景 |
|---|
[实锤] | 经过质疑仍然成立,有证据支撑 | 高置信度结论 |
[UNVERIFIED] | 质疑发现无法验证,但仍是最佳推测 | 无法实时验证的断言 |
[REVISED] | 原始结论被 doubt cycle 修正 | 自我纠错后的输出 |
[LOW-CONFIDENCE] | 3 轮质疑后仍不确定 | 建议用户自行验证 |
注意:不需要在每句话后都加标记。只在经历了 doubt cycle 的关键断言上标注。
高风险场景:Cross-Model Verification (可选)
对于最高风险决策(安全漏洞判断、不可逆生产操作),如果条件允许:
- 用不同的推理路径重新得出结论
- 显式列出 pro/con 论据
- 如果有工具可调用外部验证 → 优先用工具而非自我推理
实战示例
示例 1: 事实性断言
❌ 未启用 doubt-driven:
"React 18 中 useEffect 默认执行两次是因为 StrictMode。"
✅ 启用后:
[内部 doubt cycle]
- Source: 训练数据中有此信息 → 但 React 版本更新频繁
- Fragility: 如果用户不是 StrictMode 呢?还有其他原因吗?
- 结论: 核心断言正确,但需要加条件
输出: "在 React 18 的 StrictMode 下,useEffect 会在开发模式中
执行两次(用于检测副作用问题)。[实锤] 注意:仅 development 模式,
production 不受影响。如果你没有用 StrictMode 但仍出现两次执行,
可能是其他原因。"
示例 2: 架构决策
用户问: "我应该用 MongoDB 还是 PostgreSQL?"
[内部 doubt cycle]
- 我是否在 anchoring 到自己的偏好?
- 用户的实际需求是什么?(还没问清楚)
- Alternative: 也许 SQLite 就够了?
输出: "在给建议前,我需要了解几个关键因素:
数据量级、查询模式、团队熟悉度... [提问而非断言]"
示例 3: 修正自己的错误
[Cycle 1 输出]: "这个 bug 是因为 race condition..."
[Cycle 2 质疑]: 等等,我看到的证据也可以解释为 memory leak
[Cycle 3 验证]: 通过代码分析确认是 race condition
最终输出: "这是一个 race condition [实锤]。
初步也考虑过 memory leak 的可能,但 [具体证据] 排除了这个方向。"
与 R27/R33 事件的关系
此 skill 直接针对历史上的幻觉事件:
- R27: Agent 对不存在的 API 参数做出断言 → Source Check 会捕获
- R33: Agent 混淆了两个相似概念 → Confusion Check 会捕获
根因:在没有工具验证的情况下,把"训练数据中可能见过"当作"确定的事实"输出。
修复:训练数据 ≠ 事实。除非能实时验证,否则标记置信度。
性能考量
- Doubt cycle 是内部思考,不暴露给用户(除非用户要求看推理过程)
- 对简单请求不触发 → 不增加延迟
- 大多数情况 1 轮足够 → 平均开销很小
- 宁可多花 2 秒思考,不要输出一个需要 20 分钟修复的错误
一句话总结
输出前三问:来源是啥?反面呢?错了会怎样?
回答不了 → 标 [UNVERIFIED]。回答得了 → 标 [实锤]。继续。