401 lines
13 KiB
Markdown
401 lines
13 KiB
Markdown
# Interaction Boundary 四挡合同 IO 审阅稿
|
||
|
||
## 目的
|
||
|
||
这份文档不讲实现细节,只把这次真正跑过的 interaction boundary 相关测试,按“输入是什么、系统最终产出什么、我们到底在验什么”重新摊开。
|
||
|
||
对应本次实际跑过的自动化入口:
|
||
|
||
- [backend/tests/test_semantic_decision_service.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_semantic_decision_service.py)
|
||
- [backend/tests/test_workflow_semantic_planner.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_workflow_semantic_planner.py)
|
||
- [backend/tests/test_ai_pmo_ingress_mainline.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_ai_pmo_ingress_mainline.py)
|
||
- [backend/tests/test_external_query_planner.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_external_query_planner.py)
|
||
- [backend/tests/test_feishu_card_action_contract.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_feishu_card_action_contract.py)
|
||
|
||
## 高标准判定
|
||
|
||
我的评分口径不是“断言过了就算过”,而是按能不能支撑正式合同基线来打:
|
||
|
||
- `9.0` 以下:有价值,但还不够让我放心收进正式基线
|
||
- `9.0 - 9.2`:过线,但偏合同层/局部层证明
|
||
- `9.3 - 9.5`:扎实,已经能证明主链行为
|
||
- `9.6+`:非常硬,几乎就是这次需求最关键的验收证据
|
||
|
||
每条案例都至少要证明一件事:
|
||
|
||
1. recommendation ask 不会再偷偷滑进 draft / execute。
|
||
2. 显式升级到 draft 时,系统能保留 draft,不会被误压回 query。
|
||
3. planner 识别出的底层 workflow 与最终允许执行的层级是两回事,最终以 boundary/control 为准。
|
||
4. 这组 boundary/control 元数据不会在 ingress/query 链中途丢失。
|
||
5. 外部 recommendation 的最终客户可见文案仍是“建议”,不是拒答、不是现状核查、也不是起草确认。
|
||
|
||
按这个口径,这份审阅稿里我接受的最低门槛是:单条案例要 `> 9.0` 才算能过我的标准。
|
||
|
||
## 审阅案例
|
||
|
||
### 01. 负向边界 schema:recommendation 明确禁止 draft / execute
|
||
|
||
- 输入:
|
||
|
||
```json
|
||
{
|
||
"requested_level": "recommendation",
|
||
"forbidden_levels": ["draft", "execute"],
|
||
"allow_status": true,
|
||
"allow_recommendation": true,
|
||
"allow_draft": false,
|
||
"allow_execute": false,
|
||
"correction_targets": ["project", "level"],
|
||
"confidence": 0.91
|
||
}
|
||
```
|
||
|
||
- 实际输出:
|
||
|
||
```json
|
||
{
|
||
"requested_level": "recommendation",
|
||
"forbidden_levels": ["draft", "execute"],
|
||
"allow_draft": false,
|
||
"allow_execute": false,
|
||
"correction_targets": ["project", "level"]
|
||
}
|
||
```
|
||
|
||
- 通过点:
|
||
- recommendation 被结构化收成正式 level
|
||
- draft / execute 的负向边界被完整保留
|
||
- 后续可纠错目标明确包含 `project / level`
|
||
- 评分:`9.1 / 10`
|
||
- 结论:能过我的标准
|
||
- 原因:这条把“recommendation 明确禁止 draft / execute”这个负向边界固定成了正式 schema,合同层很干净;但它还只是结构层证明,不单独覆盖 planner/runtime 的真实执行,所以分不会更高。
|
||
|
||
### 02. Answer control schema:底层 workflow 被挡住时要显式写出来
|
||
|
||
- 输入:
|
||
|
||
```json
|
||
{
|
||
"effective_level": "recommendation",
|
||
"blocked_levels": ["draft", "execute"],
|
||
"blocked_workflows": ["signal_source_flow:onboard"],
|
||
"allowed_workflows": ["query_flow:answer"],
|
||
"downgraded_from": "draft"
|
||
}
|
||
```
|
||
|
||
- 实际输出:
|
||
|
||
```json
|
||
{
|
||
"effective_level": "recommendation",
|
||
"blocked_workflows": ["signal_source_flow:onboard"],
|
||
"allowed_workflows": ["query_flow:answer"],
|
||
"downgraded_from": "draft"
|
||
}
|
||
```
|
||
|
||
- 通过点:
|
||
- 系统不会只说“被挡了”,而是能说清楚到底挡掉了哪个 workflow
|
||
- query.answer 成为最终允许主链
|
||
- 评分:`9.1 / 10`
|
||
- 结论:能过我的标准
|
||
- 原因:这条把“被挡住的不是抽象 level,而是具体 workflow”说清楚了,后面做审计、诊断、回放都靠它;短板同样是它偏合同表达层,真正把分数抬高的是后面的 runtime case。
|
||
|
||
### 03. recommendation-only:识别到 signal_source_flow,但最终降回 query.answer
|
||
|
||
- 输入:
|
||
|
||
```text
|
||
先别出草稿,只按当前项目情况推荐几个最值得接的外部信号源。
|
||
```
|
||
|
||
- planner 初始识别:
|
||
|
||
```json
|
||
{
|
||
"workflow_type": "signal_source_flow",
|
||
"workflow_action": "onboard",
|
||
"operation_codes": ["signal_source.onboard"]
|
||
}
|
||
```
|
||
|
||
- interaction boundary:
|
||
|
||
```json
|
||
{
|
||
"requested_level": "recommendation",
|
||
"forbidden_levels": ["draft", "execute"],
|
||
"allow_draft": false,
|
||
"allow_execute": false
|
||
}
|
||
```
|
||
|
||
- 最终输出 bundle:
|
||
|
||
```json
|
||
{
|
||
"primary_workflow": "query_flow",
|
||
"workflows": [
|
||
{
|
||
"workflow_type": "query_flow",
|
||
"workflow_action": "answer",
|
||
"operation_codes": ["query.answer"]
|
||
}
|
||
],
|
||
"diagnostics": {
|
||
"interaction_boundary": {
|
||
"requested_level": "recommendation"
|
||
},
|
||
"answer_control": {
|
||
"effective_level": "recommendation",
|
||
"blocked_workflows": ["signal_source_flow:onboard"],
|
||
"downgraded_from": "draft"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
- 通过点:
|
||
- 允许“识别到底层 write workflow”
|
||
- 但最终主链明确停在 `query.answer`
|
||
- `signal_source_flow:onboard` 没有再误滑进 draft pending confirm
|
||
- 评分:`9.7 / 10`
|
||
- 结论:明显过线,而且是这次最关键的验收点之一
|
||
- 原因:这条直接证明“先识别 workflow,再按 boundary 收口”的核心设计真的落地了。它不是模糊地避免误判,而是允许识别到底层草稿动作,再明确降回 recommendation,可解释性和行为正确性都很强。
|
||
|
||
### 04. 显式升级到 draft:不再被 recommendation guard 误伤
|
||
|
||
- 输入:
|
||
|
||
```text
|
||
可以,把第一个整理成接入草稿给我看。
|
||
```
|
||
|
||
- interaction boundary:
|
||
|
||
```json
|
||
{
|
||
"requested_level": "draft",
|
||
"forbidden_levels": ["execute"],
|
||
"allow_draft": true,
|
||
"allow_execute": false
|
||
}
|
||
```
|
||
|
||
- 最终输出 bundle:
|
||
|
||
```json
|
||
{
|
||
"primary_workflow": "signal_source_flow",
|
||
"workflows": [
|
||
{
|
||
"workflow_type": "signal_source_flow",
|
||
"workflow_action": "onboard",
|
||
"operation_codes": ["signal_source.onboard"]
|
||
}
|
||
],
|
||
"diagnostics": {
|
||
"answer_control": {
|
||
"effective_level": "draft",
|
||
"blocked_workflows": []
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
- 通过点:
|
||
- recommendation-only guard 不会误挡掉用户后续显式升级
|
||
- draft 允许,execute 仍未放行
|
||
- 评分:`9.5 / 10`
|
||
- 结论:能稳稳过我的标准
|
||
- 原因:如果只有上一条降级,没有这一条升级,整个合同就会变成“只会压,不会放”。这条证明四挡合同不是一刀切保护壳,而是真的尊重用户显式升级指令,行为上是完整的。
|
||
|
||
### 05. 写请求原样保留:正常 signal source 草稿请求仍走 onboard
|
||
|
||
- 输入:
|
||
|
||
```text
|
||
给项目ID: 2 接一个 YouTube 录屏加评论回放的信号源,先不要执行,先出草稿。
|
||
```
|
||
|
||
- fake planner 输出:
|
||
|
||
```json
|
||
{
|
||
"primary_workflow": "signal_source_flow",
|
||
"workflow_type": "signal_source_flow",
|
||
"workflow_action": "onboard",
|
||
"operation_codes": ["signal_source.onboard"],
|
||
"project_id": 2
|
||
}
|
||
```
|
||
|
||
- ingress resolve 后实际输出:
|
||
|
||
```json
|
||
{
|
||
"intent_name": "signal_source.onboard",
|
||
"project_id": 2,
|
||
"source_request": true
|
||
}
|
||
```
|
||
|
||
- 通过点:
|
||
- 正常“先出草稿”的写请求没有被新 boundary 逻辑误压成 query
|
||
- 兼容旧的无 boundary bundle 透传
|
||
- 评分:`9.3 / 10`
|
||
- 结论:能过我的标准
|
||
- 原因:这条主要是在守兼容性,证明新合同没有把本来正确的 draft 请求打坏。它不像 03/04 那样直接验证新能力核心,但对上线安全性很重要,所以我给中高分。
|
||
|
||
### 06. recommendation 降级后,boundary/control 元数据不会在 ingress 丢失
|
||
|
||
- 输入:
|
||
|
||
```text
|
||
你先别出草稿,只按当前项目情况推荐几个最值得接的外部信号源。
|
||
```
|
||
|
||
- planner bundle 输入:
|
||
|
||
```json
|
||
{
|
||
"primary_workflow": "query_flow",
|
||
"workflow_action": "answer",
|
||
"operation_codes": ["query.answer"],
|
||
"diagnostics": {
|
||
"interaction_boundary": {
|
||
"requested_level": "recommendation",
|
||
"forbidden_levels": ["draft", "execute"]
|
||
},
|
||
"answer_control": {
|
||
"effective_level": "recommendation",
|
||
"blocked_workflows": ["signal_source_flow:onboard"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
- resolve intent 后实际输出:
|
||
|
||
```json
|
||
{
|
||
"intent_name": "query.read_only",
|
||
"workflow_route": "query.answer",
|
||
"interaction_boundary": {
|
||
"requested_level": "recommendation"
|
||
},
|
||
"answer_control": {
|
||
"effective_level": "recommendation",
|
||
"blocked_workflows": ["signal_source_flow:onboard"]
|
||
}
|
||
}
|
||
```
|
||
|
||
- 通过点:
|
||
- `intent.name` 仍是现有体系里的 `query.read_only`
|
||
- 但业务 route 已明确是 `query.answer`
|
||
- boundary/control 没在 `workflow_bundle -> canonical intent` 这段链路里丢掉
|
||
- 评分:`9.4 / 10`
|
||
- 结论:能过我的标准
|
||
- 原因:planner 里算对还不够,这条证明 metadata 能穿过 ingress 主链继续活着,不会“前面识别对了、后面又掉光了”。这属于真正的链路级证明,不是单点断言。
|
||
|
||
### 07. external recommendation presenter:外部证据在校验中,也要直接给建议
|
||
|
||
- 输入:
|
||
|
||
```text
|
||
测试产能警告这个项目,如果只考虑外部信号源,你会优先推荐哪 3 类?直接给推荐结果和理由。
|
||
```
|
||
|
||
- 外部上下文:
|
||
|
||
```json
|
||
{
|
||
"retrieval_status": "verifier_blocked",
|
||
"impact_status": "no_direct_impact",
|
||
"recommendation_goal": "给测试产能警告推荐最值得先看的外部信号源。"
|
||
}
|
||
```
|
||
|
||
- presenter 实际输出:
|
||
|
||
```json
|
||
{
|
||
"prompt_variant_id": "external_signal_source_recommendation",
|
||
"answer_text": "如果只看外部信号源,我会先盯三类:1. 测试执行结果或失败告警... 2. 发布与变更记录... 3. 工单或异常反馈..."
|
||
}
|
||
```
|
||
|
||
- 通过点:
|
||
- recommendation ask 不再被压成 `external_verifier_blocked` 拒答
|
||
- 输出是候选建议 + 理由,不是现状核查,也不是草稿入口
|
||
- 评分:`9.4 / 10`
|
||
- 结论:能过我的标准
|
||
- 原因:这条把合同效果推到了 presenter 层,证明 recommendation 问法在外部证据校验未完成时,仍能输出“建议型答案”。它很好地对齐了用户真正看到的产品行为。
|
||
|
||
### 08. Feishu 最终客户可见文本:优先直出 recommendation,不回 packet fallback
|
||
|
||
- 输入:
|
||
|
||
```text
|
||
测试产能警告这个项目,如果只考虑外部信号源,你会优先推荐哪 3 类?直接给推荐结果和理由,不要复述当前现状,不要起草需求。
|
||
```
|
||
|
||
- direct_reply_text:
|
||
|
||
```text
|
||
外部实时查询:如果只看外部信号源,我会先看测试执行结果或失败告警、发布与变更记录、工单或异常反馈这三类,因为它们最容易直接反映产能异常。
|
||
```
|
||
|
||
- 最终 Feishu 文本输出:
|
||
|
||
```text
|
||
如果只看外部信号源,我会先看测试执行结果或失败告警、发布与变更记录、工单或异常反馈这三类,因为它们最容易直接反映产能异常。
|
||
|
||
来源:项目库 + 外部公开资料(当前仍在校验)
|
||
```
|
||
|
||
- 通过点:
|
||
- 直接优先吃 recommendation 正文
|
||
- 不回落到 analysis packet fallback
|
||
- 不出现 `External Freshness Guard`
|
||
- 也不把 recommendation ask 说成“已收到需求/准备起草”
|
||
- 评分:`9.5 / 10`
|
||
- 结论:能稳稳过我的标准
|
||
- 原因:这是最贴近客户可见结果的一条。前面所有 schema、planner、ingress、presenter 做得再好,只要 Feishu 落地文案退回旧 fallback,就都不算真的完成;这条证明最终用户看到的文本已经站对位置了。
|
||
|
||
## 实际运行结果
|
||
|
||
执行命令:
|
||
|
||
```bash
|
||
cd /Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend
|
||
/Users/yuuuu/Documents/AIProjectManger/backend/venv/bin/python -m pytest \
|
||
tests/test_semantic_decision_service.py \
|
||
tests/test_workflow_semantic_planner.py \
|
||
tests/test_ai_pmo_ingress_mainline.py::test_kernel_intent_resolve_uses_workflow_bundle_for_signal_source_request \
|
||
tests/test_ai_pmo_ingress_mainline.py::test_kernel_intent_resolve_preserves_interaction_boundary_when_recommendation_downgrades_to_query \
|
||
tests/test_external_query_planner.py::test_presenter_prefers_recommendation_answer_for_signal_source_recommendation_question \
|
||
tests/test_feishu_card_action_contract.py::test_render_feishu_qa_direct_reply_text_prefers_recommendation_answer_for_external_signal_recommendation \
|
||
-vv
|
||
```
|
||
|
||
实际结果:
|
||
|
||
```text
|
||
collected 15 items
|
||
15 passed, 8 warnings in 3.59s
|
||
```
|
||
|
||
说明:
|
||
|
||
- warning 全是现有环境里的旧 warning,主要是 Pydantic V2 deprecation、`lark_oapi` 和 `websockets` 的 deprecation。
|
||
- 这次 interaction boundary 改动相关 case 全部通过。
|
||
|
||
## 总结判断
|
||
|
||
- 8 条里我给得最低的是 `9.1`,所以都能过我的标准。
|
||
- 最硬的三条是 `03 / 04 / 08`:分别对应“降级正确”“升级正确”“最终客户可见文本正确”。
|
||
- 相对偏弱的是 `01 / 02`,不是因为它们做得差,而是它们偏 schema/合同层,单独看还不算完整行为闭环。
|