817 lines
18 KiB
Markdown
817 lines
18 KiB
Markdown
# Unified Project AI Handoff 成功案例验收包
|
||
|
||
## 目的
|
||
|
||
这份文档把 `统一 Project Operating Context + 三路 handoff` 的 12 条黄金场景收成可直接过目的“成功案例包”。
|
||
|
||
本文聚焦三件事:
|
||
|
||
1. 每条 case 的最小输入
|
||
2. 从哪里入站、经过哪些主链、按什么步骤验
|
||
3. 成功时应该看到的结构化输出与最终用户可见输出
|
||
|
||
## 使用边界
|
||
|
||
- 本文是“成功目标样例 + 验收步骤”文档,不等于 12 条都已经做完人工业务走读。
|
||
- 文中的结构化输出与最终输出,表示该 case 验收成功时应看到的目标结果。
|
||
- 自动化证据以 [2026-04-17-feishu-problem-inventory.md](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/docs/superpowers/specs/2026-04-17-feishu-problem-inventory.md) 为真源。
|
||
- 飞书前台验收默认先看“后端最终出站”:
|
||
- 非交互 QA 看 `qa_direct` 文本
|
||
- 强交互 requirement / draft 看 action card payload
|
||
- 所有 Feishu 场景都必须经过 `feishu_reply_outbox`;如果没有看到 outbox,就不能算飞书链路验收成功。
|
||
|
||
## 通用验收步骤
|
||
|
||
每条 case 都按同一顺序验:
|
||
|
||
1. 准备前置上下文
|
||
2. 用真实入站面发送最小输入
|
||
3. 先看结构化输出是否命中预期主链
|
||
4. 再看最终用户可见输出是否符合合同
|
||
5. 记录 pass / fail 与证据
|
||
|
||
每条 case 至少记录这 6 项:
|
||
|
||
- 输入
|
||
- 入站面
|
||
- 主链
|
||
- 结构化输出
|
||
- 最终输出
|
||
- 结果判定
|
||
|
||
## Feishu 场景统一 Transport 合同
|
||
|
||
凡是本文中真实入站面包含 Feishu 的 case,除了看业务主链,还必须额外确认 transport 层。
|
||
|
||
### 非交互 QA 文本
|
||
|
||
必经链路:
|
||
|
||
```text
|
||
message.receive_v1
|
||
-> handle_message_event()
|
||
-> _handle_message_receive()
|
||
-> capture_from_feishu()
|
||
-> _route_scene_reply()
|
||
-> _build_feishu_qa_direct_reply_text()
|
||
-> _safe_reply_text()
|
||
-> FeishuReplyOutboxMixin._enqueue_reply_outbox()
|
||
-> feishu_reply_outbox
|
||
```
|
||
|
||
必验点:
|
||
|
||
- `reply_route=qa_direct`
|
||
- `feishu_reply_outbox.message_text` 是纯文本
|
||
- 文本里包含成功案例要求的正文 / 当前项目 / 外部判断 / 下一步
|
||
|
||
### 交互卡片
|
||
|
||
必经链路:
|
||
|
||
```text
|
||
message.receive_v1 或 card.action.trigger
|
||
-> handle_message_event()
|
||
-> _handle_message_receive() / _handle_card_action_trigger()
|
||
-> _route_scene_reply()
|
||
-> _build_action_card_from_capture_result()
|
||
-> _safe_reply_card()
|
||
-> FeishuReplyOutboxMixin._enqueue_reply_outbox()
|
||
-> feishu_reply_outbox
|
||
```
|
||
|
||
必验点:
|
||
|
||
- `reply_route=qa_action_card` 或对应 card action 路由
|
||
- `feishu_reply_outbox.message_text` 以 `__pmflow_feishu_card__:` 开头
|
||
- 解码后的 card payload 保留正确 `action` 和 `work_item_id`
|
||
|
||
---
|
||
|
||
## Case 01
|
||
|
||
### 场景
|
||
|
||
纯内部系统问题
|
||
|
||
### 前置条件
|
||
|
||
- 当前在项目页或带 `project_id=17` 的 Web 问答入口
|
||
- 无 active requirement-plan / draft confirm 干扰
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`当前 PMFlow 里 MCP 模板有几个?`
|
||
- 真实入站面:Web `POST /rag/ask`
|
||
|
||
示例请求:
|
||
|
||
```json
|
||
{
|
||
"question": "当前 PMFlow 里 MCP 模板有几个?",
|
||
"asked_via": "pmflow_manual",
|
||
"project_id": 17,
|
||
"action_mode": "read"
|
||
}
|
||
```
|
||
|
||
### 详细步骤
|
||
|
||
1. 从项目页问答入口发起问题。
|
||
2. 查看 `/rag/ask` 返回 payload 中的 `route_decision`。
|
||
3. 确认 `route_mode=internal`,且没有被转成 external。
|
||
4. 查看最终 `answer` 是否以 `内部知识库查询:` 开头。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"route_decision": {
|
||
"route_mode": "internal",
|
||
"effective_source_policy": "internal"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```text
|
||
内部知识库查询:当前 PMFlow 里共有 2 个 MCP 模板。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 命中 internal 主链
|
||
- 不混入外部来源摘要
|
||
- 不是泛化聊天式说明
|
||
|
||
---
|
||
|
||
## Case 02
|
||
|
||
### 场景
|
||
|
||
纯外部事实问题
|
||
|
||
### 前置条件
|
||
|
||
- 普通 QA 线程
|
||
- 无 active requirement-plan
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`OpenAI Docs 最近有没有新的 Responses API 最佳实践?`
|
||
- 真实入站面:Web `POST /rag/ask`
|
||
|
||
示例请求:
|
||
|
||
```json
|
||
{
|
||
"question": "OpenAI Docs 最近有没有新的 Responses API 最佳实践?",
|
||
"asked_via": "pmflow_manual",
|
||
"action_mode": "read"
|
||
}
|
||
```
|
||
|
||
### 详细步骤
|
||
|
||
1. 从 Web QA 入口提交问题。
|
||
2. 检查 `route_decision.route_mode` 是否为 `external`。
|
||
3. 检查 external 证据是否经过 fail-closed 过滤。
|
||
4. 查看最终回答是否保持 `外部实时查询:` 合同。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"route_decision": {
|
||
"route_mode": "external",
|
||
"effective_source_policy": "external"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```text
|
||
外部实时查询:OpenAI Docs 最近补充了新的 Responses API 最佳实践说明。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 只能走 external 主链
|
||
- internal 来源不得混进 external 正文
|
||
|
||
---
|
||
|
||
## Case 03
|
||
|
||
### 场景
|
||
|
||
先判断,再给 plan 入口
|
||
|
||
### 前置条件
|
||
|
||
- 当前项目明确
|
||
- repo 摘要可用
|
||
- 允许 external lane 构建 `fit_brief`
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`OpenAI Docs 这种能力适不适合我们当前项目?`
|
||
- 真实入站面:
|
||
- Web `POST /rag/ask`
|
||
- Feishu `message.receive_v1`
|
||
|
||
Web 示例请求:
|
||
|
||
```json
|
||
{
|
||
"question": "OpenAI Docs 这种能力适不适合我们当前项目?",
|
||
"asked_via": "pmflow_manual",
|
||
"project_id": 12,
|
||
"source_chat_id": "chat-12",
|
||
"action_mode": "read"
|
||
}
|
||
```
|
||
|
||
Feishu 最小入站:
|
||
|
||
```json
|
||
{
|
||
"message_type": "text",
|
||
"chat_id": "chat-12",
|
||
"sender_open_id": "ou-alpha",
|
||
"message_id": "om-case-03",
|
||
"content": "OpenAI Docs 这种能力适不适合我们当前项目?"
|
||
}
|
||
```
|
||
|
||
### 详细步骤
|
||
|
||
1. 从 Web 或 Feishu 发问题。
|
||
2. 检查 `project_operating_context` 是否带上当前项目。
|
||
3. 检查 `execution_recipe.plan_handoff_mode` 是否为 `offer_after_answer`。
|
||
4. 检查 `handoff_mode / can_enter_plan / recommended_next_step`。
|
||
5. Feishu 侧检查 `_route_scene_reply()` 是否走到 `qa_direct`。
|
||
6. Feishu 侧检查 `feishu_reply_outbox.message_text` 是否为最终出站文本。
|
||
7. Feishu 侧再看最终 `qa_direct` 文本是否已经变成围绕当前项目实体的自然分析回复,而不是标签摘要。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"project_operating_context": {
|
||
"current_project_id": 12,
|
||
"fit_scope": "current_project_and_repo",
|
||
"decision_strategy": "answer_then_offer_plan"
|
||
},
|
||
"execution_recipe": {
|
||
"primary_lane": "external",
|
||
"fit_brief_required": true,
|
||
"external_evidence_required": true,
|
||
"plan_handoff_mode": "offer_after_answer"
|
||
},
|
||
"handoff_mode": "offer_after_answer",
|
||
"can_enter_plan": true,
|
||
"recommended_next_step": "如果你要,我可以基于当前结论进入 plan,继续把需求范围和下一步收清楚。"
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
Web:
|
||
|
||
```text
|
||
外部实时查询:目前更像背景相关,建议先验证它是否能映射到当前项目正式对象。
|
||
```
|
||
|
||
Feishu:
|
||
|
||
```text
|
||
外部实时查询:目前更像背景相关,建议先验证它是否能映射到当前项目正式对象。
|
||
|
||
结合当前项目看,Alpha 是一个 AI 项目管理工作台,当前仓库负责统一项目上下文与 AI handoff。就这次判断来说,这条外部信息目前更像背景相关,还不能直接映射到当前正式对象,所以现在更适合作为参考,而不是直接当成已经命中当前项目的正式变化。
|
||
|
||
如果你要,我可以基于当前结论进入 plan,继续把需求范围和下一步收清楚。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 先给判断
|
||
- 再给 plan 入口
|
||
- 不得首轮直接切到 plan 主链
|
||
|
||
---
|
||
|
||
## Case 04
|
||
|
||
### 场景
|
||
|
||
显式强锚点直接进 plan
|
||
|
||
### 前置条件
|
||
|
||
- 上一轮已经给出结论
|
||
- 当前消息显式 reply 到上一轮结论
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`那按这个推进`
|
||
- 真实入站面:Feishu `message.receive_v1` reply/thread
|
||
|
||
示例入站:
|
||
|
||
```json
|
||
{
|
||
"message_id": "om-case-04",
|
||
"reply_to_message_id": "om-case-03-bot",
|
||
"chat_id": "chat-12",
|
||
"content": "那按这个推进"
|
||
}
|
||
```
|
||
|
||
### 详细步骤
|
||
|
||
1. 用 reply/thread 回复上一条结论消息。
|
||
2. 检查 canonical thread context 是否恢复成功。
|
||
3. 检查 `execution_recipe.plan_handoff_mode` 是否命中 `explicit_plan_now`,或直接回到 active requirement context。
|
||
4. 检查 `_route_scene_reply()` 后是否进入 card 或 follow-up 对应出站路径。
|
||
5. 检查最终 Feishu 回包是否通过 `feishu_reply_outbox` 出站。
|
||
6. 检查输出是否继续 requirement-plan,而不是普通 QA。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"execution_recipe": {
|
||
"plan_handoff_mode": "explicit_plan_now"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```text
|
||
AI PMO 需求收敛:我先按这条结论继续收敛需求范围。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 直接 handoff 到 plan
|
||
- 不是重新解释 internal / external 模式
|
||
|
||
---
|
||
|
||
## Case 05
|
||
|
||
### 场景
|
||
|
||
reply/thread 明确续问
|
||
|
||
### 前置条件
|
||
|
||
- 机器人上一条已给出解释性回复
|
||
- 当前消息显式 reply 到该条回复
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`你刚才这条说的“模型路由”具体指哪层?`
|
||
- 真实入站面:Feishu reply/thread 或 QA session follow-up
|
||
|
||
### 详细步骤
|
||
|
||
1. 对上一条机器人解释消息做显式回复。
|
||
2. 检查 follow-up anchor 是否优先命中 reply anchor。
|
||
3. 检查问题是否被重写到上一条回复对象。
|
||
4. 确认没有被旧 `last_subject` 抢走。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"anchor_mode": "reply_anchor",
|
||
"resolved_anchor": {
|
||
"source_message_id": "om-prev-answer"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```text
|
||
内部知识库查询:这里说的“模型路由”指的是 PMFlow 本地路由层里的 tier / provider / response contract 决策层。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 续问对象来自 reply anchor
|
||
- 不是把它当新问题重开
|
||
|
||
---
|
||
|
||
## Case 06
|
||
|
||
### 场景
|
||
|
||
同群同人但切新话题
|
||
|
||
### 前置条件
|
||
|
||
- 同一群聊、同一用户
|
||
- 上一轮刚结束 requirement-plan
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`另外,现在 PMFlow 里 signal source onboarding 做到哪了?`
|
||
- 真实入站面:Feishu `message.receive_v1`
|
||
|
||
### 详细步骤
|
||
|
||
1. 在同一群里直接发一条新的事实问题。
|
||
2. 检查 session inheritance guard 是否拦住旧 requirement-plan 续写。
|
||
3. 检查显式 signal-source 请求是否避开 draft/plan 劫持。
|
||
4. 检查最终回答是否回到 internal query。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"route_decision": {
|
||
"route_mode": "internal"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```text
|
||
内部知识库查询:当前 PMFlow 的 signal source onboarding 已支持受控接入与运行时探测。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 不得继续沿 requirement-plan 解释
|
||
- 必须识别为新的 internal query
|
||
|
||
---
|
||
|
||
## Case 07
|
||
|
||
### 场景
|
||
|
||
旧 active context 劫持新问题
|
||
|
||
### 前置条件
|
||
|
||
- 上一轮挂着 `pending_clarification(kind=query_route_selection)`
|
||
- 当前用户显式改题
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`不是说那个,我现在问 external gateway。`
|
||
- 真实入站面:Feishu `message.receive_v1` 或 Web QA session
|
||
|
||
### 详细步骤
|
||
|
||
1. 先制造一个 query-route 澄清状态。
|
||
2. 再发送这条显式改题消息。
|
||
3. 检查 ingress 是否调用 `WorkflowSemanticPlanner` 看 `topic_switch=new`。
|
||
4. 检查旧 `pending_clarification` 是否被立即清空。
|
||
5. 确认没有继续调用旧 session 的澄清协议消费链。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"pending_clarification": null,
|
||
"next_route": "query.answer"
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```text
|
||
外部实时查询:external gateway 当前负责统一外部查询计划、provider 分发和结果校验。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 旧 `pending_clarification` 必须失效
|
||
- 当前消息必须作为新 query 进入主链
|
||
|
||
---
|
||
|
||
## Case 08
|
||
|
||
### 场景
|
||
|
||
明明该继续 plan,却掉回 query.answer
|
||
|
||
### 前置条件
|
||
|
||
- active requirement-plan 正在进行
|
||
- 上一轮刚发 A/B/C 选项
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`我选 C`
|
||
- 真实入站面:Feishu `message.receive_v1`
|
||
|
||
### 详细步骤
|
||
|
||
1. 先进入 requirement-plan 并发出 A/B/C。
|
||
2. 再发送 `我选 C`。
|
||
3. 检查 active requirement context 是否命中当前 option map。
|
||
4. 确认协议解析直接 bypass 普通 QA semantic gate。
|
||
5. 查看最终输出是否继续 requirement-plan follow-up。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"reply_template_key": "requirement_plan_followup",
|
||
"parsed_choice": "C"
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```text
|
||
C. 混合增强路径
|
||
|
||
⭐ 当前我更推荐:C
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 不得掉回普通 QA
|
||
- 必须继续当前 requirement-plan 主链
|
||
|
||
---
|
||
|
||
## Case 09
|
||
|
||
### 场景
|
||
|
||
明明只是问结论,却被直接拉进 plan
|
||
|
||
### 前置条件
|
||
|
||
- 无 active plan
|
||
- 无显式 reply/thread 强锚点
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`这个方案适不适合我们现在这套 PMFlow?`
|
||
- 真实入站面:Web `POST /rag/ask` 或 Feishu `message.receive_v1`
|
||
|
||
### 详细步骤
|
||
|
||
1. 直接发一条适配性判断问题。
|
||
2. 检查 `execution_recipe.plan_handoff_mode`。
|
||
3. 确认首轮还是 `offer_after_answer`,不是 `explicit_plan_now`。
|
||
4. 确认最终输出先给结论,再给下一步。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"execution_recipe": {
|
||
"plan_handoff_mode": "offer_after_answer"
|
||
},
|
||
"recommended_next_step": "如果你要,我可以基于当前结论进入 plan。"
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```text
|
||
外部实时查询:目前适合作为背景参考,但还需要验证它与当前 PMFlow 正式对象的映射关系。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 首轮不能直接进入 plan
|
||
- 必须保留“先答结论,再给下一步”
|
||
|
||
---
|
||
|
||
## Case 10
|
||
|
||
### 场景
|
||
|
||
卡片动作和纯文本回复不一致
|
||
|
||
### 前置条件
|
||
|
||
- 同一 requirement thread 同时支持按钮和文本协议
|
||
- 当前 active `work_item_id` 已存在
|
||
|
||
### 输入
|
||
|
||
- 文本输入:`选 B`
|
||
- 卡片输入:点击 `B` 按钮
|
||
- 真实入站面:
|
||
- 文本:Feishu `message.receive_v1`
|
||
- 卡片:Feishu `card.action.trigger`
|
||
|
||
### 详细步骤
|
||
|
||
1. 在同一 requirement 轮次里保留当前 action card。
|
||
2. 用文本发 `选 B`。
|
||
3. 再用卡片点击 `B`。
|
||
4. 检查两条路径是否都命中同一 `work_item_id` 和 canonical thread context。
|
||
5. 检查文本和卡片两条路径都写入 `feishu_reply_outbox`。
|
||
6. 检查最终都继续 requirement-plan。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"work_item_id": 88,
|
||
"action": "plan_choice",
|
||
"choice": "B"
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
```json
|
||
{
|
||
"header": {
|
||
"title": {
|
||
"content": "AI PMO 需求收敛"
|
||
}
|
||
},
|
||
"elements": [
|
||
{
|
||
"tag": "action",
|
||
"actions": [
|
||
{
|
||
"value": {
|
||
"action": "plan_choice",
|
||
"choice": "B",
|
||
"work_item_id": 88
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 文本和按钮都命中同一 requirement thread
|
||
- 不能出现“一条续上、一条掉链”
|
||
|
||
---
|
||
|
||
## Case 11
|
||
|
||
### 场景
|
||
|
||
Web 与 Feishu 对同一句话不同链路
|
||
|
||
### 前置条件
|
||
|
||
- 当前项目一致
|
||
- Web 与 Feishu 都从同一项目语境发问
|
||
|
||
### 输入
|
||
|
||
- 用户原话:`这个适合吗`
|
||
- 真实入站面:
|
||
- Web `POST /rag/ask`
|
||
- Feishu `message.receive_v1`
|
||
|
||
### 详细步骤
|
||
|
||
1. 用同一句话分别从 Web 和 Feishu 发起问题。
|
||
2. 对比两边的 `project_operating_context`。
|
||
3. 对比两边的 `execution_recipe` 和 `handoff_mode`。
|
||
4. Web 看结构化 meta。
|
||
5. Feishu 检查 `_route_scene_reply()` 是否进入 `qa_direct`,并写入 `feishu_reply_outbox`。
|
||
6. Feishu 再看最终 `qa_direct` 文本。
|
||
|
||
### 成功结构化输出
|
||
|
||
```json
|
||
{
|
||
"execution_recipe": {
|
||
"plan_handoff_mode": "offer_after_answer"
|
||
},
|
||
"handoff_mode": "offer_after_answer",
|
||
"can_enter_plan": true
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
Web:
|
||
|
||
```text
|
||
外部实时查询:目前更像背景相关,还不能直接映射到当前正式对象。
|
||
```
|
||
|
||
Feishu:
|
||
|
||
```text
|
||
外部实时查询:目前更像背景相关,还不能直接映射到当前正式对象。
|
||
|
||
结合当前项目看,Alpha 是一个 AI 项目管理工作台,当前仓库负责统一项目上下文与 AI handoff。就这次判断来说,这条外部信息目前更像背景相关,还不能直接映射到当前正式对象,所以现在更适合作为参考,而不是直接当成已经命中当前项目的正式变化。
|
||
|
||
如果你要,我可以基于当前结论进入 plan,继续把需求范围和下一步收清楚。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 两边都必须是 `offer_after_answer`
|
||
- 不能一边进 plan、一边留在普通 QA
|
||
|
||
---
|
||
|
||
## Case 12
|
||
|
||
### 场景
|
||
|
||
多候选 meta follow-up 需要澄清
|
||
|
||
### 前置条件
|
||
|
||
- 最近 5 分钟内有 2 条候选回复
|
||
- 当前问题无法唯一锚定某一条
|
||
|
||
### 输入
|
||
|
||
- 第一轮:`那你刚才那条是哪个模型回复的?`
|
||
- 第二轮:`第二条`
|
||
- 真实入站面:Feishu / QA session follow-up
|
||
|
||
### 详细步骤
|
||
|
||
1. 先制造两个最近候选回复。
|
||
2. 发送第一轮 meta follow-up。
|
||
3. 检查是否返回 `ambiguous_recent_reply` 和编号候选。
|
||
4. 再发送 `第二条`。
|
||
5. 检查是否恢复 `original_question` 并绑定正确 `selected_qa_id`。
|
||
|
||
### 成功结构化输出
|
||
|
||
第一轮:
|
||
|
||
```json
|
||
{
|
||
"clarification_code": "ambiguous_recent_reply",
|
||
"clarification_candidates": [
|
||
{"index": 1},
|
||
{"index": 2}
|
||
]
|
||
}
|
||
```
|
||
|
||
第二轮:
|
||
|
||
```json
|
||
{
|
||
"selected_qa_id": 102,
|
||
"effective_question": "我问你这个是哪个模型执行回复的?"
|
||
}
|
||
```
|
||
|
||
### 成功最终输出
|
||
|
||
第一轮:
|
||
|
||
```text
|
||
我找到两条可能对应的回复:
|
||
1. ...
|
||
2. ...
|
||
请告诉我是第几条。
|
||
```
|
||
|
||
第二轮:
|
||
|
||
```text
|
||
内部知识库查询:你选的是第二条,那条回复由当前 query.answer 主链执行。
|
||
```
|
||
|
||
### 成功判定
|
||
|
||
- 第一轮必须先澄清
|
||
- 第二轮必须支持中文编号恢复原问题
|
||
|
||
---
|
||
|
||
## 建议过目顺序
|
||
|
||
如果你是要先审文档,再决定人工走读顺序,建议按这 4 条先看:
|
||
|
||
1. Case 03:先判断,再给 plan 入口
|
||
2. Case 07:旧澄清失效
|
||
3. Case 08:A/B/C 继续 requirement-plan
|
||
4. Case 11:Web / Feishu 同句一致
|
||
|
||
这 4 条最能看出 unified handoff 现在是不是真的站住了。
|