PMFlow/docs/superpowers/specs/2026-04-19-interaction-boun...

649 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Interaction Boundary 与四挡合同设计
## 目的
这份设计要解决的不是“模型再聪明一点”,而是把 PMFlow 当前问答/建议/草稿/执行之间的边界收干净:
- `status`
- `recommendation`
- `draft`
- `execute`
当前问题不是系统不会回答,而是系统没有一个正式的“本轮允许做到哪一挡、明确禁止升到哪一挡”的运行时合同,导致 recommendation ask 会误滑到 `signal_source.onboard -> draft_pending_confirm`。
本设计的目标是:
1. 四挡独立,不能偷偷升级。
2. 每一挡都支持澄清、纠错、再次思考。
3. recommendation 必须能独立停住,不再被写链路抢走。
4. 用户可见回复必须自然业务化,不像架构师,也不能泄漏 packet / contract 术语。
5. 今天与昨天暴露出来的失败场景,必须转成自动化反例。
## 这次不做什么
- 不重写 `requirement_plan` / action card 主链。
- 不重构 `SignalSourceOrchestrationService` 业务编排本体。
- 不把前台所有文风都做一轮大翻修。
- 不引入新的中文关键词仓或正则仓去拍板 `query vs draft vs execute`。
## 当前已暴露的问题
### 1. recommendation ask 被错升成 onboard / draft
真实用户输入:
```text
我看这个项目现在还没有成型的信号源。你先别出草稿,只按当前项目情况,帮我推荐几个最值得接的外部信号源,并说清楚各自的价值。
```
真实结果:
- `intent = signal_source.onboard`
- `state = draft_pending_confirm`
- 先发 `⏳ 已完成入库,当前进入待确认队列。`
这说明:
- recommendation 与 draft 没有分层
- 负向边界 `先别出草稿` 没生效
- executor 链被过早放行
### 2. recommendation ask 被答成现状核查
用户明明在问“推荐几个外部信号”,系统却回:
- 当前没有信号源
- 当前项目没有记录
- 当前盘面怎样
这说明:
- `status` 与 `recommendation` 没分开
### 3. recommendation ask 被答成保守拒答
用户问:
```text
如果只考虑外部信号源,你会优先推荐哪 3 类?
```
系统回:
- 当前不能直接推荐
- 当前证据不足
这说明:
- recommendation 被误当成 freshness / fact verification
### 4. 稀疏项目只会打太极
例如 `自动开票系统` 只有一句描述时,系统长期只会回:
- 还缺业务步骤
- 还缺信号源
- 先别硬判
这类话术不算真正分析,只是保守拒答。
### 5. 客户可见回复泄漏内部术语
已经出现过:
- `分析包里明确写了`
- `missing_mapping`
- `focus_objects`
- `analysis_packet`
这说明:
- packet / presenter 边界没有守住
### 6. 新项目 / 新业务切换被旧线程污染
例如上一轮在聊 `测试产能警告`,下一轮问 `AI客服这个项目...`,却继续沿旧 subject / old scope 改写。
这说明:
- scope 连续性虽然已经补了治理,但还没有成为正式验收基线
## 设计原则
### 1. 先定边界,再决定动作
系统不能只理解“用户想干什么”,还必须理解“用户明确不要我干什么”。
### 2. 不追求一次答对,追求可纠错
系统要做到:
- 不越权
- 可停住
- 可被纠正
- 纠正后能原地重算
### 3. 结构化边界优先于运行时猜测
决策权不应该在:
- `if "先别出草稿" in text`
- `if "不要执行" in text`
而应该在:
- 统一语义规划层结构化产出的边界合同
- gatekeeper 对结构合同的执行
### 4. recommendation 是独立主链,不是 query 的弱版也不是 draft 的前奏
只要用户要的是建议,就应该允许系统:
- 给候选
- 给排序
- 给理由
但不能:
- 冒充已验证事实
- 顺手起草
- 顺手执行
### 5. 每一挡都必须有澄清、纠错、再次思考
这三件事不是失败兜底,而是系统能力的一部分。
## 新增运行时结构
### A. InteractionBoundaryPacket
职责:表达“这一轮允许做到哪一挡、禁止做到哪一挡”。
建议结构:
```python
class InteractionBoundaryPacket(BaseModel):
boundary_version: str = "v1"
requested_level: Literal[
"status",
"recommendation",
"draft",
"execute",
"unclear",
] = "unclear"
forbidden_levels: list[
Literal["status", "recommendation", "draft", "execute"]
] = Field(default_factory=list)
allow_status: bool = True
allow_recommendation: bool = True
allow_draft: bool = False
allow_execute: bool = False
allow_write: bool = False
needs_clarification: bool = False
clarification_reason: str = ""
clarification_questions: list[str] = Field(default_factory=list)
correction_allowed: bool = True
correction_targets: list[
Literal["project", "object", "level", "priority", "assumption"]
] = Field(default_factory=list)
self_review_required: bool = True
confidence: float = 0.0
evidence: list[dict[str, Any]] = Field(default_factory=list)
```
这不是给用户看的,而是给 gatekeeper 用的。
### B. AnswerControlDecision
职责:把 `SemanticDecision + InteractionBoundaryPacket` 合成真正能执行的层级结果。
建议结构:
```python
class AnswerControlDecision(BaseModel):
effective_level: Literal[
"status",
"recommendation",
"draft",
"execute",
"clarify",
]
blocked_levels: list[str] = Field(default_factory=list)
blocked_workflows: list[str] = Field(default_factory=list)
allowed_workflows: list[str] = Field(default_factory=list)
downgraded_from: str | None = None
requires_confirmation: bool = False
requires_self_review: bool = True
requires_correction_slot: bool = True
reason: str = ""
```
## 四挡定义
### 1. status
定义:
- 只回答当前现状
- 不给建议
- 不起草
- 不执行
允许:
- 当前已知内容
- 当前未知内容
- 当前只看到哪些记录
禁止:
- 偷偷给候选建议
- 偷偷起草或执行
### 2. recommendation
定义:
- 可以给候选、排序、理由
- 不能起草
- 不能执行
- 必须明确“这是建议,不是已验证事实”
### 3. draft
定义:
- 可以起草一版
- 必须带假设、缺口、待确认点
- 不能执行
### 4. execute
定义:
- 必须显式确认
- 可以落库 / 接入 / 执行
- 必须回显要动哪个对象、影响范围和执行结果
## 决策顺序
后续实现必须按这个顺序:
1. 现有 `WorkflowSemanticPlanner` 继续产出 `SemanticDecision`
2. 同轮补产出 `InteractionBoundaryPacket`
3. 把 `workflow_plans` 映射到四挡
4. 用 boundary packet 过滤 workflow
5. 产出 `AnswerControlDecision`
6. 再决定最终主链:
- `query.answer(status)`
- `query.answer(recommendation)`
- `draft_pending_confirm`
- `execute`
也就是说,`signal_source_flow` 可以被识别出来,但如果:
- `allow_draft = false`
- `allow_execute = false`
最终仍然只能落到:
- `query.answer(recommendation)`
## 负向边界优先级
必须明确:
1. 负向边界优先于系统自己的升级冲动
2. 负向边界低于用户后续显式升级确认
例如:
### 场景 A
```text
先别出草稿,只给我推荐几个高价值外部信号源。
```
预期:
- recommendation 可以回答
- draft / execute 必须被 block
### 场景 B
后续用户再说:
```text
可以,把第 1 个起草成接入草稿。
```
预期:
- 显式升级到 draft
- 仍不自动 execute
## 澄清、纠错、再次思考
### 1. 澄清
每一挡都允许澄清。
适用情况:
- 项目不清
- 业务对象不清
- 用户到底要 status / recommendation / draft / execute 不清
- 当前约束冲突
需要结构化字段:
- `needs_clarification`
- `clarification_reason`
- `clarification_questions`
### 2. 纠错
用户必须能低成本纠错:
- 不是这个项目
- 不是这个对象
- 不是这个方向
- 我现在不是要草稿,只要建议
- 我改了,现在直接出草稿
要求:
- 收到纠错后,必须重建新的 `InteractionBoundaryPacket`
- 不准带旧边界续写
- 输出里应承认:已按新纠正口径重算
### 3. 再次思考 / 自检
建议新增:
```python
class SelfReviewResult(BaseModel):
project_aligned: bool = True
object_aligned: bool = True
level_aligned: bool = True
leaked_internal_terms: bool = False
overstepped_boundary: bool = False
clarify_missing: bool = False
notes: list[str] = Field(default_factory=list)
```
至少要检查:
- 我是不是答错项目了
- 我是不是把 recommendation 偷偷升级成 draft 了
- 我是不是泄漏内部术语了
- 我是不是没有分析,只是在说“信息不足”
- 我是不是漏了关键澄清点
自检失败时:
- 降级
- 或补澄清
- 或阻止出站
## 用户可见回复骨架
四挡统一成三段式:
1. 当前判断
2. 理由 / 缺口
3. 纠错或升级入口
### recommendation 例子
```text
如果只是先给建议,我会先看这 3 类外部信号:
1. xxx,因为...
2. yyy,因为...
3. zzz,因为...
这些是候选建议,不代表已经接入,也还没完成验证。
如果方向不对,你可以直接改项目对象或业务目标;如果你要,我也可以下一步只把第 1 个起草成草稿。
```
### sparse 项目例子
```text
自动开票系统这个项目,我现在先不硬说它该落在哪一步。
我现在只看得到它的大致目标:收到开票请求后自动开票,并把发票图片发出去。但还看不到这条链路里谁触发、接什么输入、哪个结果算真正跑通。
如果你愿意,我们先把这条流程拆开:谁发起、系统接什么、最后产出什么,再往下判断最合适的信号放在哪。
```
## 高标准黄金案例(业务化 V3)
这批案例要替换掉旧的“架构味太重 / 问法太空”的样例。问题必须像业务同事会问的话。
### 01. 自动开票系统 / status
- 输入:`自动开票系统现在最容易卡在哪一步?你按现在项目情况直接说。`
- 预期层级:`status`
- 预期:不出建议,不出草稿,只说明当前最容易卡的链路或当前缺口
### 02. 自动开票系统 / recommendation
- 输入:`自动开票系统除了现在这些数据,你觉得还应该盯哪些外部信号?先给建议,不要起草。`
- 预期层级:`recommendation`
- 预期:给 3 个候选信号 + 理由,不进 draft
### 03. AI客服 / status
- 输入:`AI客服这个项目现在主要靠什么数据来做用户洞察?`
- 预期层级:`status`
- 预期:围绕当前数据源或已知对象回答,不偷换成推荐
### 04. AI客服 / recommendation
- 输入:`AI客服这个项目,除了现在这些数据,你觉得还应该补哪几类外部线索?直接说最有用的几个。`
- 预期层级:`recommendation`
- 预期:给候选 + 业务理由
### 05. 门店库存异常日报助手 / recommendation
- 输入:`这个项目如果要更早发现库存异常,你会先多看哪几类外部信号?先给建议,不要出方案。`
- 预期层级:`recommendation`
- 预期:业务化候选,不保守拒答
### 06. 直播复盘辅助工具 / recommendation
- 输入:`这个项目如果只补一个外部信号,你觉得先补哪个最值?直接说原因。`
- 预期层级:`recommendation`
- 预期:优先级明确,不起草
### 07. 测试产能警告 / recommendation with negative boundary
- 输入:`我看这个项目现在还没有成型的信号源。你先别出草稿,只按当前项目情况,帮我推荐几个最值得接的外部信号源,并说清楚各自的价值。`
- 预期层级:`recommendation`
- 预期:绝不发队列 ack、绝不建 draft
### 08. 测试产能警告 / explicit upgrade to draft
- 前置:上一轮 recommendation 已返回
- 输入:`可以,把第一个整理成接入草稿给我看。`
- 预期层级:`draft`
- 预期:允许升级,但不 execute
### 09. 确认立项 / internal status
- 输入:`确认立项现在 assignee 推荐做到哪了?`
- 预期层级:`status`
- 预期:回答当前状态,不泄漏 `status_summary / contract`
### 10. 跨项目切换 / scope reset
- 前置:上一轮问的是 `测试产能警告`
- 输入:`AI客服这个项目里,用户洞察数据现在到底给谁看、解决什么事?`
- 预期层级:`status`
- 预期:必须切到 AI 客服,不允许带旧项目续写
### 11. 稀疏项目 / clarify
- 输入:`这个项目到底该怎么做,你先说。`
- 预期层级:`clarify`
- 预期:必须澄清项目或对象,不能直接起草或乱答
### 12. execute 前确认
- 输入:`那就把第一个外部信号源直接新增进去。`
- 预期层级:`execute`
- 预期:必须显式确认,不准直接写
## 今天和昨天的失败反例,必须转成自动化
### Fail-01
- recommendation ask 误进 `signal_source.onboard`
- 断言:必须失败
### Fail-02
- recommendation ask 被答成现状核查
- 断言:必须失败
### Fail-03
- recommendation ask 被答成“当前不能推荐”
- 断言:必须失败
### Fail-04
- 客户可见文本泄漏 `分析包 / missing_mapping / focus_objects`
- 断言:必须失败
### Fail-05
- sparse 项目只会说“还缺业务步骤”
- 断言:必须失败
### Fail-06
- 新项目问句被旧线程污染
- 断言:必须失败
### Fail-07
- 用户说 `不要执行`,系统仍然进入 write flow
- 断言:必须失败
### Fail-08
- 用户说 `只给建议`,系统仍然进入 `draft_pending_confirm`
- 断言:必须失败
## 测试设计
### 1. schema / contract
- `test_interaction_boundary_packet_schema`
- `test_answer_control_decision_schema`
### 2. gatekeeper
- `test_recommendation_boundary_blocks_signal_source_onboard`
- `test_status_boundary_blocks_recommendation_upgrade`
- `test_explicit_upgrade_from_recommendation_to_draft_allowed`
- `test_execute_requires_confirmation_even_after_prior_upgrade`
### 3. mainline routing
- `test_query_answer_recommendation_only_stays_query`
- `test_status_only_does_not_return_candidates`
- `test_unclear_level_returns_clarify`
- `test_negative_boundary_blocks_write_flow`
### 4. Feishu outbox
- `test_feishu_recommendation_only_never_emits_queue_ack`
- `test_feishu_recommendation_reply_has_no_internal_terms`
- `test_feishu_negative_boundary_no_draft_pending_confirm`
### 5. sparse project
- `test_sparse_project_status_uses_known_goal_not_packet_jargon`
- `test_sparse_project_recommendation_explains_known_goal_and_unknown_flow`
### 6. correction / rethink
- `test_user_correction_rebuilds_boundary_packet`
- `test_self_review_blocks_overstep_to_draft`
- `test_self_review_blocks_internal_term_leak`
## >9 分验收标准
### 自动化稳定性 > 9
- 新增 contract / gatekeeper / Feishu outbox / sparse project 测试全绿
- recommendation 相关高风险误路由 case 全部自动化覆盖
### 链路清晰度 > 9
- 任意一条 query 都能在结构化结果里明确看到:
- `requested_level`
- `forbidden_levels`
- `effective_level`
- `blocked_workflows`
### 项目贴合度 > 9
- 回复必须贴当前项目对象
- 稀疏项目也至少能拆出最小业务链
- 不允许长时间停留在“缺步骤 / 缺信号源”空话
### 回复自然度 > 9
- 文风像业务同事
- 不像架构师
- 不像系统模板
- 不泄漏 packet / contract / internal terms
### 高风险误路由单条结果 > 9
- recommendation ask 错升 draft/execute 这类 case 必须逐条变绿
- 不能再用“总体表现还行”掩盖单点失败
## 实施顺序
1. 先补 schema:
- `InteractionBoundaryPacket`
- `AnswerControlDecision`
2. 再补 gatekeeper
3. 再把 recommendation-only 从 query.answer 主链里独立出来
4. 再补 clarify / correction / self-review
5. 最后按新的业务化黄金案例跑验证
## 真源落点建议
- `backend/app/services/ai_pmo/semantic_context/decision_schema.py`
- `backend/app/services/ai_pmo/workflow_semantic_planner/service.py`
- Feishu ingress / gatekeeper 主链
- `backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_signal_source.py`
- `docs/architecture/RUNTIME_GUARDRAILS.md`
- `docs/architecture/CODE_REFERENCE_INDEX.md`
## 完成标准
只有当下面全部满足时,这版才算过线:
1. recommendation 不再误进 draft / execute
2. status / recommendation / draft / execute 四挡真的独立
3. 稀疏项目不再只会打太极
4. 用户可见回复自然业务化,不像架构师
5. 今天和昨天这些失败案例都变成自动化绿灯