| name | doubt-driven-development |
| description | 在每个非平凡决策生效之前,对其进行全新上下文的对抗性审查。当正确性比速度更重要时、在不熟悉的代码中工作时、当风险很高时(生产环境、安全敏感逻辑、不可逆操作),或任何自信的输出现在验证比以后调试更便宜的时候使用。在高风险迁移或上线前,压力测试(压测)计划中隐藏的故障模式时使用。 |
怀疑驱动开发
概述
自信的答案并不等于正确的答案。长会话积累上下文,悄悄地未经任何人注意就将假设转化为"事实"。怀疑驱动开发是在任何非平凡输出生效之前,引入一个全新上下文的审查者——偏向于证伪而非批准——的纪律。
这不是 /review。/review 是对已完成产物的裁决。这是一种进行中的姿态:非平凡的决策在方向修正仍然便宜时就被交叉审查。
何时使用
一个决策是非平凡的,当以下至少一项为真时:
- 它引入或修改分支逻辑
- 它跨越模块或服务边界
- 它断言类型系统或编译器无法验证的属性(线程安全、幂等性、顺序、不变量)
- 其正确性依赖于未来读者无法看到的上下文
- 其爆炸半径是不可逆的(生产部署、数据迁移、公共 API 变更)
在以下情况下应用此技能:
- 即将在不确定性下做出架构决策
- 即将提交非平凡代码
- 即将声称一个非显而易见的事实("这是安全的"、"这可以扩展"、"这符合规格")
- 在你尚未完全理解的代码中工作
何时不使用:
- 机械操作(重命名、格式化、文件移动)
- 遵循清晰、明确的用户指令
- 阅读或总结现有代码
- 正确性显而易见的一行变更
- 纯工具操作(运行测试、列出文件)
- 用户明确要求速度优先于验证
如果你对每个按键都怀疑,你将什么都交付不了。此技能仅适用于如上定义的非平凡决策。
加载约束
此技能设计用于主会话协调器,其中步骤 3(DOUBT,详见下文)可以生成一个全新上下文的审查者。
- 不要将此技能添加到角色的
skills: 前置元数据中。 遵循步骤 3 的角色会生成另一个角色——这是 references/orchestration-patterns.md 明确禁止的协调反模式("角色不要调用其他角色")。
- 如果你发现自己在子智能体上下文中应用此技能(其中 Claude Code 阻止嵌套子智能体生成):首选路径是向用户提出怀疑驱动无法嵌套运行并由主会话处理。仅作为最后手段,一个降级的自问回退存在——将 ARTIFACT + CONTRACT 重写为一个带有与你先前推理的硬性心智分隔的新鲜自提示词,并走步骤 1-5。这不是全新上下文审查(你带着你自己的上下文),因此将结果标记为降级,并在用户可联系时优先升级。
流程
在应用技能时复制此检查清单:
怀疑循环:
- [ ] 步骤 1:CLAIM —— 写下声明 + 为什么重要
- [ ] 步骤 2:EXTRACT —— 提取孤立的产物 + 契约,剥离推理
- [ ] 步骤 3:DOUBT —— 以对抗性提示词调用全新上下文审查者
- [ ] 步骤 4:RECONCILE —— 对照产物文本对每个发现进行分类
- [ ] 步骤 5:STOP —— 满足停止条件(琐碎发现、3 个循环或用户否决)
步骤 1:CLAIM —— 提出将要生效的内容
用两到三行命名决策:
声明:"新的缓存层在规格中描述的读密集型工作负载下是线程安全的。"
为什么重要:这里的竞态条件会破坏用户数据,且
在 QA 中难以检测。
如果你不能如此紧凑地写出声明,你拥有的是一种感觉,而非一个决策。在审查它之前先将其提出。
步骤 2:EXTRACT —— 最小可审查单元
全新上下文的审查者需要产物和契约,而不是旅程。
- 代码:diff 或函数——而非整个文件
- 决策:3-5 句提案加上它必须满足的约束
- 断言:声明加上据说支持它的证据(与步骤 1 的 CLAIM 块保持区别,后者是协调者在审查下的假设)
剥离你的推理。如果你交出结论,你将收回对你结论的验证。单元必须小到审查者能一次阅读就保存在脑海中——如果是 500 行的 PR,先分解。
步骤 3:DOUBT —— 引入全新上下文的审查者
审查者的提示词必须是对抗性的。框架决定答案。
对抗性审查。找出此产物有什么问题。
假设作者过于自信。寻找:
- 未陈述的假设
- 未处理的边界情况
- 隐藏的耦合或共享状态
- 契约可能被违反的方式
- 这可能破坏的现有约定
- 意外输入下的失败模式
不要验证。不要总结。找问题,或在彻底检查后
明确声明你无法找到任何问题。
产物:<粘贴产物>
契约:<粘贴契约>
只传递 ARTIFACT + CONTRACT。不要传递 CLAIM。 将你的结论交给审查者会使其偏向同意。审查者必须独立确定产物是否满足契约。
在 Claude Code 中,agents/ 中基于角色的审查者一开始就具有隔离的上下文,并可在此处使用——参见 agents/ 了解人员名录和按领域匹配。
上述对抗性提示词优先于角色的默认响应形式。 像 code-reviewer 这样的角色被编写为产生带有优点和缺点的平衡裁决;怀疑驱动需要仅输出问题。将对抗性提示词逐字粘贴到调用中以覆盖角色的默认值。如果角色的响应形式不能被干净地覆盖,回退到使用对抗性提示词的通用子智能体。
跨模型升级
单模型审查者与原始作者共享盲点——一个更冷、不同架构的模型捕获它们。怀疑驱动已经为非平凡决策选择加入,因此在该范围内提供跨模型是技能价值的一部分,而非可选摩擦。
交互式会话:始终提供。永远不要静默跳过。
步骤 1:询问用户
在上面步骤 3 的单模型审查之后,在 RECONCILE 之前,暂停并询问:
"单模型审查完成。想要跨模型的第二意见吗?选项:Gemini CLI、Codex CLI、手动外部审查(你将其粘贴到别处),或跳过。"
这个问题在每个交互式怀疑循环中都是强制的——即使是对感觉低风险的产物。用户——而非智能体——决定成本是否值得。智能体的工作是提出这个选择。
步骤 2:如果用户选择 CLI —— 验证,然后调用
- 检查工具是否在 PATH 中(
which gemini、which codex)。
- 测试它是否能工作(
gemini --version 或等效命令),然后再传递完整提示词——过期或损坏的二进制文件可能通过 which 但在实际输入上失败。
- 与用户确认确切的调用,包括必需的标志、认证和环境变量(例如 API 密钥)。实现各不相同;永远不要假设。
- 仅传递 ARTIFACT + CONTRACT + 对抗性提示词。没有会话上下文,没有 CLAIM。
- 注意 shell 转义。如果产物包含引号、
$(...) 或反引号,优先使用 stdin(echo … | gemini)或 heredoc 而非内联 -p "…"。有疑问时,在运行之前要求用户确认调用。
- 将输出带入步骤 4(RECONCILE)。
永远不要将产物内插到 shell 引号参数中。 代码、markdown 和审查提示词经常包含反引号、$(...) 和引号字符,这些东西要么会截断提示词,要么会执行嵌入的 shell 命令。将完整提示词写入文件并通过 stdin 管道传递。
示例形式(根据你安装的工具验证标志——语法在不同实现和版本间有所不同):
codex exec --sandbox read-only -C <repo-path> - < /tmp/doubt-prompt.md
gemini --approval-mode plan -p "" < /tmp/doubt-prompt.md
只读沙箱是关键承载细节:一个怀疑产物本身可能包含指令(有意或无意的提示注入),否则跨模型 CLI 会对其工作区执行这些指令。
步骤 3:如果 CLI 不可用或失败
显式提出失败。提供:手动运行、尝试不同的工具或跳过。不要静默回退到单模型——用户应该知道跨模型没有发生。
步骤 4:如果用户跳过
在输出中确认跳过("仅继续使用单模型发现")并继续到 RECONCILE。跳过可以;静默跳过不行。
非交互式上下文(CI、/loop、自主循环、计划运行):
- 跨模型被跳过,且跳过必须被公告在输出中:"跨模型跳过:非交互式上下文。"
- 永远不要在没有明确用户授权的情况下调用外部 CLI——这是关键承载的安全属性。
跨模型增加了成本、延迟和工具脆弱性。智能体在每个循环都提出这个选择;用户决定此产物是否值得这样做。
步骤 4:RECONCILE —— 将发现折叠回来
审查者的输出是数据,不是裁决。你仍然是协调者。 在分类之前对照每个发现重新阅读产物文本——盲目接受审查者和忽略它同样是失败模式。
对每个发现,按以下优先级顺序分类(第一个匹配的类别胜出):
- 契约误读——审查者标记某事的特定原因是由于你提供的 CONTRACT 不清晰或不完整。先修复契约,在下一个循环中重新分类。
- 有效 + 可操作——真正的问题需要对产物进行更改。更改它,重新循环。
- 有效权衡——问题真实存在,但修复成本超过接受成本。显式记录权衡,以便用户看到它。
- 噪音——审查者标记了在审查者没有的上下文下实际上是正确的事情。记录它,继续,并问:将那个上下文添加到契约中是否能防止虚假标记?
一个全新的审查者可能因为缺乏上下文而出错。不要仅仅因为它"新"就屈从。
步骤 5:STOP —— 有界循环,非递归
在以下情况下停止:
- 下一次迭代只返回琐碎的或已经被考虑的发现,或
- 已完成 3 个循环(升级给用户,不要单独进行第四个),或
- 用户明确说"发布"
如果 3 个循环后审查者仍然提出实质性问题,产物可能尚未准备好。将此向用户提出——三个未解决的循环是关于产物的信息,而非继续循环的理由。
如果 3 个循环因产物太大而"明显不足":产物太大了——回到步骤 2 并分解。不要解除限制。
常见合理化借口
| 合理化借口 | 现实 |
|---|
| "我有信心,跳过怀疑步骤" | 在新问题上,信心与正确性的相关性很差。确定性的时刻恰好是盲点隐藏的地方。 |
| "生成一个审查者很贵" | 在生产中调试一个错误提交更贵。检查是有界的;缺陷不是。 |
| "审查者只会挑小毛病" | 只有在没有约束范围的情况下才会。将提示词限制为"在契约下会使其失败的问题"。 |
"我最后用 /review 做怀疑就行" | /review 是最后的门禁。怀疑驱动在早期捕获错误方向,此时方向修正还很便宜。到 PR 时间就太晚了。 |
| "如果我对每一步都怀疑,我将永远无法交付" | 技能适用于非平凡决策,而非每个按键。重新阅读"何时不使用"。 |
| "两个意见总是比一个好" | 当第二个有更少的上下文并产生噪音时并非如此。协调,不要屈从。 |
| "审查者不同意,所以我错了" | 审查者缺乏你的上下文——分歧是信息,而非裁决。重新阅读产物,分类,然后决定。 |
| "跨模型总是更好" | 跨模型捕获单模型与自身共享的盲点,但它增加了成本和工具脆弱性。在每个交互式怀疑循环中提供它——用户决定产物是否值得这样做。智能体的工作是提出选择,而非把关。 |
| "用户说了一次可以,所以我可以继续调用 CLI" | 每次调用都有其自己的授权。产物、提示词和标志在调用之间会变化——在每次运行前重新与用户确认确切的命令。 |
红旗警告
- 为一行重命名或格式变更生成全新上下文的审查者
- 将审查者输出视为权威而未重新阅读产物文本
- 在不升级给用户的情况下循环 >3 个周期
- 用"这好吗?"而不是"找问题"来提示审查者
- 在时间压力下跳过对高风险决策的怀疑
- 在未更改的产物上重新生成全新上下文(你将得到相同的发现;你在拖延)
- 怀疑表演(可检查信号):在 2 个或更多个审查者提出实质性发现的循环中,零个发现被分类为可操作。你是在验证,而非怀疑。停止并升级。
- 仅在提交之后怀疑——那是
/review,不是怀疑驱动开发
- 在未与用户确认工具存在、已配置并接受确切语法的情况下硬编码外部 CLI 调用
- 在交互式怀疑循环中静默跳过跨模型。 即使不推荐,也必须可见地提供。跳过可以;静默跳过不行。
- 在外部 CLI 出错或缺失时静默回退——提出失败并让用户重定向
- 从审查者的输入中剥离契约
- 将 CLAIM 传递给审查者(偏向同意)
与其他技能的交互
code-review-and-quality / /review:互补。/review 是事后的 PR 裁决;怀疑驱动是进行中的逐决策审查。两者都使用。
source-driven-development:SDD 对照官方文档验证关于框架的事实。怀疑驱动验证你关于产物的推理。SDD 检查 API 是否存在;怀疑驱动检查你是否在契约下正确使用了它。
test-driven-development:TDD 的 RED 步骤是具象化的怀疑——一个失败的测试是一次证伪尝试。当 TDD 适用时,那个失败的测试就是行为声明的怀疑步骤。
debugging-and-error-recovery:当审查者提出真正的失败模式时,切换到调试技能来定位和修复。
- 仓库协调规则(
references/orchestration-patterns.md):此技能从主会话协调。一个角色调用另一个角色是反模式 B——见上方加载约束。
验证
应用怀疑驱动开发后: