# ADR-0001: Reverse-Thinking Gate — Engine-Level Enforcement vs Hook-Layer Opt-In - **Status**: Accepted (缩水方案 Option 2-Plus 落地) - **Date**: 2026-04-25 - **Deciders**: PM (产品经理) + Flyto Agent core team - **Related code**: `core/pkg/counterfactual/`, `core/pkg/skills/reverse_think/`, `core/pkg/tools/tool.go` (RequiresReverseThinking field), `platform/common/safetychain/reverse_thinking_hook.go` - **Related TODO**: `core/TODO.md` L569 (登记 2026-04-16, 缩水落地 2026-04-25) - **Commit chain**: `248253e` (C1) → `0385efd` (C2) → `c4b755f` (C3) → `4618b79` (C4) → `40aae31` (C5) → C6 (本 ADR) --- ## 1. 背景 / Context CLAUDE.md 宪法原则 1-5 规定 AI Agent 在做非平凡设计决策前应走五步: 读早期方案代码 → 标 CLEVER/UGLY → 升华思考 (CLI/SDK/API/跨行业) → 反向思考 → 等待确认. 当前实现: - 软性 skill: `~/.claude/skills/reverse-think/SKILL.md` 使用 MiniMax-M2.7-highspeed 跑反向思维, JSON 输出 (`hidden_assumptions` / `failure_scenarios` / `verdict` / `verdict_reason`) - 强制确认协议 ⛔: `CLAUDE.md` 顶段, 写 `.go` / 启动 Agent 子进程 / `git commit` 前必须 "⏸️ 等待确认" - 现有引擎级 gate: `core/pkg/hooks/PreToolUse` (12 hook 类型) + `core/pkg/permission/` (32 文件 AI classifier + 规则) + `core/pkg/validator/` (可插拔审批契约) + `core/pkg/circuitbreaker/` + `core/pkg/staging/` + `tools.Metadata.RequiresCheckpoint` + `engine.CheckpointHandlerFn` **核心问题**: 上述五步**靠人/Agent 自觉遵守, 一致性差**. TODO L569 提议升级为引擎级强制 gate, 引入 8 个新模块 (~1500-2500 行 Go). --- ## 2. 决策 / Decision **采纳 Option 2-Plus 缩水方案** (4 件套 + reference hook + ADR), **拒绝原方案 A 完整版** (引擎级 8 模块). ### 实施范围 (Option 2-Plus) | 件 | 内容 | 路径 | 行数 | |---|---|---|---| | 1 | Deliverable schema | `core/pkg/counterfactual/` | ~440 | | 2 | MiniMax Go client | `core/pkg/skills/reverse_think/` | ~790 | | 3 | Tool metadata flag | `core/pkg/tools/tool.go` (新字段) | ~100 | | 4 | Evolve sink adapter | `core/pkg/counterfactual/replay_event.go` | ~270 | | 5 | Reference hook | `platform/common/safetychain/reverse_thinking_hook.go` | ~530 | 总计 ~2,131 行 (含双语 godoc + 测试). ### 拒绝范围 (方案 A 完整版) | 模块 | 拒绝理由 | |---|---| | (a) `engine.ReverseThinkingGate` 接口 | 与 `hooks.PreToolUse` 同时机同语义重叠 | | (e) `engine.TriggerClassifier` | 与 `permission.Classifier` 同语义; 业界惯例消费层自决白名单, 不在 engine | | (f) `engine.DiscussPhaseGuard` + `ImplementPhaseExecutor` + `ConfirmationGate` | 与 `RequiresCheckpoint` + `permission.Handler` 同语义已实装 | | (g) `engine.AlternativePreserver` | 在 runtime 层无合理语义; 源代码层是 git diff + CONTRIBUTING.md 注释规范 (0 行 Go); 业界零先例 | | (h) `CrossDomainExtensions` | YAGNI, 零消费者 (rule of two: 没有第二个消费者前不抽象) | --- ## 3. 评估流程 / Evaluation Process 3-agent 并行 review (memory `feedback_agent_teams_review_mode.md` 模式), 三方独立产出报告后主线程 reconcile, PM 拍板. ### 调研 agent (业界先例) 调研 8 个主流 Agent 框架的"决策前 gate"机制: | 框架 | 有无前置 gate | 触发粒度 | 形式 | 持久化结构 | 强制 vs 可选 | |---|---|---|---|---|---| | Claude Agent SDK | 是 | per-tool (matcher) | `PreToolUse` hook callback | tool_input + session_id 输入, decision/reason 输出 | callback 由开发者注册 | | OpenAI Responses API | 否 | per-message | `reasoning_effort` + reasoning items | 跨 function call 持久化但不可拦截 | engine 自管 | | Vertex AI ADK | 是 | per-tool / per-model-call | `before_tool_callback` + `before_model_callback` | callback 接 agent state | engine 提供 hook, 策略由开发者写 | | LangGraph | 是 (interrupt) | per-node | `interrupt()` + `Command` resume; Agent Inbox UX | 富 payload + checkpoint 持久化 | 完全 developer-defined | | AutoGen | 是 (HITL) | per-message | `UserProxyAgent.human_input_mode` | 仅 human input string | mode 配置 | | CrewAI | 弱 | per-task | hierarchical process; verbose log | log only | 进程模式选择 | | Semantic Kernel | 是 | per-function-invocation | Filter 链式 next() 中间件 | 可读 args + override result | engine 装载, filter 由开发者写 | | Cline | 是 (Plan/Act) | per-session-mode | system prompt + READ_ONLY_TOOLS 白名单切换 | plan 自由文本 | mode 切换 + YOLO bypass | **业界共识**: engine 提供 hook primitive, 策略由开发者写. 零框架在引擎里 hardcode "决策前必须填五步 deliverable 才能调 tool" 的强制规则. **业界没做的反向论证**: 1. 吞吐量与 autonomous use case 冲突 (batch / 后台 agent / scheduled run / CI/CD 集成必须高吞吐) 2. 反思质量是 prompt 工程问题不是 enforcement 问题 (Reflexion 2023 论文 91% 的提升来自模型主动反思, 非 framework 强制结构) 3. 范畴错位: engine 不知道哪些工具值得反思 — 把判断推给开发者是把 domain knowledge 留在 domain 层的工程惯性 ### 质疑 agent (5 道硬质疑) 1. **范畴错位指控成立**: CLAUDE.md 五步是给写代码的 dev 设的协议, runtime 工具调用没有"早期方案代码可读" / "改动后注释" 的对应物. 类比: 把 "TDD 红绿重构" enforce 到生产服务请求路径上, 显然荒谬. 2. **吞吐数学不成立**: logistics wave-decision 1000/s × 即使 TriggerClassifier 收敛到 10% 触发 → 100 reverse-think/s × 5-15s 延迟串行 → 需 500 并发 LLM call 在飞才能维持稳态; MiniMax token plan call 数 (calls/5h) 被打爆. 3. **`RequiresCheckpoint` 已实装** (主线程 anchor 漏掉的关键): `core/pkg/tools/tool.go:142-157` 已有 `RequiresCheckpoint bool` 字段 + `engine.CheckpointHandlerFn` 完整实装 (`engine/checkpoint_test.go:11-69` 全分支测试). 这就是方案 A (d)+(f) 的已有版, 名字叫 RequiresCheckpoint. L569 增量价值 ≤ "改名 + 调 reverse-think skill 而非 generic handler" — 5 行 wiring 不是 1500-2500 行新模块. 4. **prompt-level 已是业界共识**: 所有主流框架靠 system prompt + tool description 引导 reasoning. 0 行 Go / 0 维护 / 0 延迟 / 跨 provider 一致. 5. **9 天前登记后 4 个新子包已消化**: validator (4-23) + staging (4-24) + shadowdb (4-25) + reflector (4-24) 四个子包覆盖了 L569 当时担忧的 95% 价值. L569 是过期需求, 不重新评估就执行 = 沉没成本陷阱. ### 设计 agent (4 备选) | 方案 | 范围 | 行数 | 优点 | 代价 | |---|---|---|---|---| | A 完整版 | 全 8 模块上引擎级 (TODO 原方案) | 1500-2500 | 北极星完整兑现 | 与 5 套现有 gate 重叠, 5-15s/tool call 延迟, 违反 CLAUDE.md 原则 10 "叠加而非替换" | | B 缩水接口版 | (a)+(b)+(d), TriggerClassifier 走消费层 | ~600 | core schema-agnostic, "rule of two" 满足 | 接口空挂短期没消费者 | | C 软性化 | 仅把 skill Go 化, 不动 engine / Tool metadata | ~300 | 0 延迟侵蚀, 0 引擎耦合, 1 commit | 没 CHANGELOG 突出特性, 跨行业扩展点缺失 | | D hook 路径 | 走现成 PreToolUse, 0 新 gate 概念 | ~400 | 0 引擎核心改动, CLAUDE.md 原则 10 满分 | hook ergonomics 跨场景一致性靠 "约定俗成" | 设计 agent 推荐 **D > C > B > A**. 但 D + C 的组合 (skill Go 化作 hook backend) 是更完整的形态. ### PM 反问与最终拍板 PM 提两次精准反问: 1. **"反向模式作为可选字段, 激活后按设计方案生效, 这个不算侵袭业务层吧?"** - 答: 运行时不侵袭确实成立 (默认关 = 0 延迟). 但 codebase 维护负担 + 与现有 5 套 gate 语义重叠 + (g)/(h) 范畴错位三件 opt-in 解决不了. 砍到 (b)+(c)+(d) 是合理形态. 2. **"听上去确实应该消费层做, 甚至消费层使用者自己写 skill / 提示词. 但这样进化能力不存在, 进化结果停在哪里?"** - 答: 触发可以各行业自决, **格式和学习池要在 core 统一**. 类比: 连锁医院各家自己决定哪些病人问诊 (触发), 但电子病历格式 + 病例学习数据库总部一份 (格式 + 学习). 加 1 件 evolve 接线 (Deliverable.AsReplayEvent → evolve.LogReplayer) 解决. PM 最终拍板 **Option 2-Plus = 4 件套 + ADR**: 1. Tool 自描述标签 `RequiresReverseThinking` (core 共享 opt-in) 2. Deliverable 五步结构 (core 共享格式) 3. reverse_think Go 函数 (core 共享 backend) 4. **AsReplayEvent 接进 evolve 学习池 (core 共享进化沉淀)** 5. platform reference hook (Go 行业一行启用入口) --- ## 4. 后果 / Consequences ### 正面 - 与业界 8 框架共识对齐 (hook 路径 + tool metadata + 开发者自填策略) - 0 延迟侵蚀业务路径 (默认关闭, opt-in 才触发) - 0 引擎核心改动 (没在 `core/pkg/engine/` 加新接口或字段) - 跨行业灵活性最大 (各行业自定义 PromptBuilder + Sink + 触发策略) - 进化沉淀路径完整 (各行业产出经 AsReplayEvent 汇总到 core 的 evolve.LogReplayer) - CLAUDE.md 原则 10 "叠加而非替换" 满分 (复用 hooks.PreToolUse 不引入新 gate 概念) ### 负面 - 没有 CHANGELOG 突出可见特性 (4 个新包 / 字段 / adapter, 不是一个大模块) - 强制语义靠现有 RequiresCheckpoint + 强制确认协议 + permission Handler 组合, 不是单一引擎 gate - 行业 platform 写自己的 hook backend 时可能走捷径 (传 `validator.AlwaysApprove{}` 同形态 bypass), 但这是产品决策不是设计缺陷 ### 中性 - 反向思维**质量**仍取决于 LLM (MiniMax) 输出质量, 任何方案 (含 A) 都改善不了模型主动反思的水平 - 跨行业一致性靠 `MetadataKey = "flyto.counterfactual.deliverable"` 字符串字面量 + Deliverable schema 锁定; 升级时跨包协调 --- ## 5. 替代方案保留 / Alternatives Preserved (CLAUDE.md 原则 5) ### 方案 A 完整版 (TODO L569 原方案) 如果未来 logistics platform 上量后, 反向思维数据驱动证明 "engine-level 强制 gate 真有 10x 决策质量提升", 可以从 Option 2-Plus 升级到方案 A. 升级路径: 1. `core/pkg/counterfactual/Deliverable` 已是方案 A (b) `CounterfactualDeliverable` 的实装, 直接复用 2. `core/pkg/skills/reverse_think/` 已是方案 A (c) `core/pkg/skills/reverse_think/` 的实装, 直接复用 3. `tools.Metadata.RequiresReverseThinking` 已是方案 A (d) 同名字段的实装, 直接复用 4. 新增方案 A (a) `engine.ReverseThinkingGate` 接口 + (e) `TriggerClassifier` + (f) `DiscussPhaseGuard` 三件, 在 `core/pkg/engine/` 落 ~800-1000 行 5. 方案 A (g) `AlternativePreserver` 与 (h) `CrossDomainExtensions` 仍建议不上 (范畴错位 + YAGNI) 预期升级成本: ~1000 行 Go (从 Option 2-Plus 基础上). 触发条件: 数据证明 + 至少 2 个行业明确要求 (rule of two 满足). ### 方案 B 缩水接口版 Option 2-Plus 已部分包含 B 的接口形态 (counterfactual 子包 + Tool metadata). 与 B 的差异: B 想把 ReverseThinkingGate 做成接口空挂等消费者, Option 2-Plus 直接走 hooks.PreToolUse 不另起接口. ### 方案 C 完全软性化 Option 2-Plus 包含 C 的 skill Go 化部分 (`core/pkg/skills/reverse_think/`), 但比 C 多 4 件 (Deliverable + Metadata flag + AsReplayEvent + reference hook). 如果 PM 后续认为 4 件中任一过度设计, 可逐件拆除回退到 C. ### 方案 D hook 路径 (单纯版) Option 2-Plus 包含 D 的 hook 路径 (ReverseThinkingHook 走 hooks.PreToolUse), 但比 D 多 3 件 (Deliverable + Metadata flag + AsReplayEvent). 这 3 件提供了 D 单纯版没有的"跨行业 schema 统一 + 进化沉淀"价值. --- ## 6. 触发重新评估的条件 未来出现以下任一情况, 应重新评估 ADR-0001 的决定: 1. **数据驱动证据**: logistics / finance / decision platform 任一上量后, 出现反向思维 hook 漏触发 (RequiresReverseThinking 标签覆盖率不足) 导致 5+ 真实事故, 且 prompt-level 增强补不上 2. **业界先例改变**: Anthropic / OpenAI / Google 任一在自家 Agent 框架引入 engine-level 强制 reasoning gate 并公开背书 (不是实验功能) 3. **吞吐量假设破产**: logistics batch decision 实测延迟容忍度 ≥ 30s (如 platform 决定走 nightly batch 而非实时 wave decision), 方案 A 的吞吐代价不再 disqualifying 4. **第二个消费方需求**: 至少 2 个行业 platform 明确写出 "需要 engine-level 强制反向思维, 不是 hook opt-in" 的需求文档 (rule of two) 满足任一即可重新走 3-agent review 评估升级到方案 A. --- ## 7. 参考链接 ### 业界 Agent 框架文档 - [Claude Agent SDK Hooks](https://code.claude.com/docs/en/agent-sdk/hooks) - [Anthropic Extended Thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) - [LangGraph Interrupts](https://docs.langchain.com/oss/python/langgraph/interrupts) - [Semantic Kernel Filters](https://learn.microsoft.com/en-us/semantic-kernel/concepts/enterprise-readiness/filters) - [Vertex AI ADK Safety](https://adk.dev/safety/) - [Cline Plan/Act Modes](https://deepwiki.com/cline/cline/3.4-plan-and-act-modes) - [Reflexion Paper (Shinn 2023)](https://arxiv.org/abs/2303.11366) ### 项目内部参考 - `~/.claude/skills/reverse-think/SKILL.md` — 软性 markdown skill (MiniMax 调用模板) - `core/CLAUDE.md` — "强制确认协议 ⛔" 段 + 我的工作原则段 (五步) - `core/TODO.md` L569 — 原方案登记 - `core/pkg/tools/tool.go:142-157` — `RequiresCheckpoint` 同源字段范本 - `core/pkg/hooks/types.go` + `handler.go` — hooks.PreToolUse + HookHandler 接口 - `core/pkg/evolve/interfaces.go` — `Reflector` + `ReplayEvent` + `LogEntry` 进化循环接口 - `core/pkg/staging/record.go` — `Record.Metadata` 字段 (Deliverable 落点) --- ## 8. 修订记录 | 日期 | 版本 | 变更 | |---|---|---| | 2026-04-25 | v1.0 | 初稿. 缩水方案 4 件套 + reference hook 落地 6 commit, ADR 起草 |