13 KiB
飞控意图「播报—确认—执行」扩展规范 v1
已统括:
dialog_result的权威形状与confirm字段见CLOUD_VOICE_DIALOG_v1.md。本文保留历史讨论(flight_intent_pending、turn.confirmation等备选),新实现请以该文为准。
状态:协议设计稿,供云端与机端/翻译桥对齐实现。
基础协议:proto_version: "1.0",transport_profile: "text_uplink"(不变)。
与 FLIGHT_INTENT 关系:结构化flight_intent仍遵守FLIGHT_INTENT_SCHEMA_v1.md;本规范仅增加执行前门控与补充消息类型。
1. 背景与目标
1.1 问题
本地 ASR 易产生错字、漏字,直接把一句话交给大模型再立即下发飞控,会出现「用户本意与结构化指令不一致」的安全与体验问题。
1.2 目标
| 场景 | 行为 |
|---|---|
| 闲聊 | 与现网一致:routing === "chitchat",无确认门控。 |
| 飞控 | 云端产出合法 flight_intent 后,先通过 TTS 播报一段简短理解反馈,机端不得在此时执行机动;仅在用户口头确认后,才进入「可执行」状态;用户可取消;超时则作废并提示重说。 |
1.3 非目标
- 不在云端做 ASR(仍由机端 STT 出字)。
- 不改变
flight_intent的 JSON Schema(v1)。 - 不强制所有产品打开本能力:由 能力协商 决定(见 §4)。
2. 术语
| 术语 | 含义 |
|---|---|
| 提案轮(proposal turn) | 用户说一句后,云端判定为飞控并返回结构化意图,但标记为「待确认」的一轮。 |
| 门控(gate) | 在该状态下,机端禁止把 flight_intent 交给执行器。 |
| 确认轮(confirmation turn) | 用户在超时窗口内,通过约定话术(或显式消息)完成确认/取消/超时通知的交互。 |
| 可执行回执(approved) | 云端明确告知:本回合的 flight_intent 已获准执行。 |
3. 行为摘要(产品话术)
默认文案(可由云端配置或模板生成,机端以 TTS 实际播放为准展示给用户):
- 提案播报(大模型或模板):用一两句话概括将要执行的操作(需与
flight_intent.summary语义一致,可略作口语化),并提示如何确认/取消。- 示例模板:「理解为:{summary}。若正确请说「确认确认」,若要取消请说「取消取消」。」
- 用户说「确认确认」(及 §7 同义表达):云端下发可执行回执 + 简短 TTS(如「好的,开始执行」);机端此时再将
flight_intent交给桥/PX4。 - 用户说「取消取消」(及 §7 同义表达):云端下发取消回执 + TTS「已取消指令,请重新下发指令」;不执行机动,清除待确认状态。
- 超时(默认 10 秒,可协商):云端下发超时回执 + TTS「未收到确认指令,请重新下发指令」;不执行机动,清除待确认状态。
注意:「确认/取消」的识别应在确认轮内优先于二次飞控解析,避免把「确认确认」误判为新的一条飞控句(实现见 §6)。
4. 能力协商(必做)
为避免破坏旧客户端,本扩展 默认关闭。仅在双方声明一致后启用。
4.1 session.start(客户端 → 云端)
在 client 或 client.capabilities 中增加可选字段(二选一实现方式,团队定稿后只保留一种以免分叉):
方案 A(推荐,挂在 client 下)
{
"type": "session.start",
"proto_version": "1.0",
"transport_profile": "text_uplink",
"session_id": "...",
"client": {
"device_id": "...",
"flight_intent_confirm": {
"enabled": true,
"timeout_sec": 10,
"confirm_phrases": ["确认确认", "确认"],
"cancel_phrases": ["取消取消", "取消"]
}
}
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
flight_intent_confirm.enabled |
boolean |
是 | true 表示要求门控流程。 |
flight_intent_confirm.timeout_sec |
number |
否 | 默认 10;建议范围 5–30。 |
flight_intent_confirm.confirm_phrases |
string[] |
否 | 机端 STT 可能输出多种说法;云端可用来做包含/模糊匹配。 |
flight_intent_confirm.cancel_phrases |
string[] |
否 | 同上。 |
方案 B:单开关 client.capabilities.require_flight_intent_confirm: true,超时与短语全集由 session.ready 返回(云端主控)。
4.2 session.ready(云端 → 客户端)
在 server_caps 中声明云端是否接受并生效该扩展:
{
"type": "session.ready",
"server_caps": {
"flight_intent_confirm": true,
"flight_intent_confirm_timeout_sec": 10
}
}
若客户端 enabled: true 但服务端 flight_intent_confirm: false,回退为即时模式(与历史行为一致:收到 routing: flight_intent 即允许机端执行,具体以产品文档为准)。
5. routing 与 flight_intent_gate(提案轮)
当门控启用且本轮解析结果为飞控意图时,云端 不得 直接使用 routing: "flight_intent" 表示「可执行」。
5.1 新路由枚举值(建议)
在原有 flight_intent / chitchat / error 上增加:
routing |
flight_intent |
机端行为 |
|---|---|---|
flight_intent_pending |
非 null,与 Schema v1 一致 | 禁止执行;仅播放本回合 TTS;进入「待确认」状态。 |
flight_intent |
非 null | 允许执行(仅出现在确认通过之后,或门控未启用时的历史路径)。 |
chitchat |
null | 不变。 |
(若团队希望少改枚举,也可用单一 flight_intent + 下表 gate,见 §5.2 备选。)
5.2 备选:保留 routing: flight_intent,用门控对象区分
dialog_result 增加可选对象:
"flight_intent_gate": {
"phase": "pending_confirm",
"proposal_turn_id": "<与 dialog_result.turn_id 相同>",
"timeout_sec": 10,
"deadline_unix_ms": 1735689600000
}
phase: pending_confirm:禁止执行。- 确认通过后同一
flight_intent再次下发时:phase: approved或省略flight_intent_gate(表示可执行)。
建议:新实现优先采用
flight_intent_pending,机端状态机更简单;备选方案便于在极小改动下渐进上线。
5.3 dialog_result 其它字段(提案轮)
tts_hint.speak_summary_or_reply: 仍为true。- 播报文本:优先使用模型生成的 简短确认话术(≤ 约 80 字为宜),字段建议显式提供,便于机端记日志:
- 建议新增可选字段
confirm_prompt_text: string(与 TTS 内容一致或为其上游文案)。
- 建议新增可选字段
flight_intent.summary仍为 Schema 必填摘要;执行器不得仅用 summary 驱机,规则不变。
5.4 turn.complete
提案轮在 TTS 结束后仍发送 turn.complete(与现协议一致)。机端收到后进入 监听确认 子状态,计时 timeout_sec。
6. 确认轮:推荐消息 turn.confirmation
避免把「确认确认」再走一轮完整 LLM 飞控解析,推荐增加专用上行类型(与 turn.text 平级):
6.1 客户端 → 云端
{
"type": "turn.confirmation",
"proto_version": "1.0",
"transport_profile": "text_uplink",
"turn_id": "<本确认轮新 UUID>",
"relates_to_turn_id": "<提案轮 turn_id>",
"outcome": "confirm" | "cancel" | "timeout",
"text": "确认确认"
}
| 字段 | 说明 |
|---|---|
relates_to_turn_id |
必须等于最近一次 flight_intent_pending(或带 pending_confirm 门控)的 dialog_result.turn_id。 |
outcome |
confirm:用户已确认;cancel:用户取消;timeout:机端计时到期主动上报(无用户话术)。 |
text |
机端 STT 原文;outcome: timeout 时可为空字符串。 |
兼容路径:若暂不实现 turn.confirmation,可约定在待确认状态下,机端仍发 turn.text,云端对短句做 规则优先:先匹配确认/取消短语,再进入 LLM;该路径易与新型飞控口令冲突,仅作过渡。
6.2 云端 → 客户端(确认结果)
对 outcome: confirm:
routing: "flight_intent"flight_intent: 与提案轮字节级一致的 JSON(或可接受:关键actions一致 + 同一trace_id)- TTS:简短执行提示
对 outcome: cancel:
routing: "chitchat"(或routing: "flight_intent_aborted"若实现枚举扩展)chat_reply: 如「已取消指令,请重新下发指令」flight_intent: null
对 outcome: timeout(或云端本地计时触发,见 §8):
- 同取消,文案改为「未收到确认指令,请重新下发指令」
随后 tts_audio_chunk*,turn.complete。
7. 短语与同义(匹配策略)
云端与机端应使用同一套短语表(以 session.start 可选覆盖为准)。建议默认:
| 意图 | 默认短语示例 |
|---|---|
| 确认 | 确认确认、确认、是的、执行 |
| 取消 | 取消取消、取消、不要、算了 |
ASR 容错:可对 text 做规范化(去空格、标点)与子串包含;条件具备时可做编辑距离阈值(产品配置)。禁止把长句闲聊误判为确认(例如:仅当 len(text) <= 20 且匹配规则时才生效,阈值可配置)。
8. 超时由谁计时
| 方案 | 说明 |
|---|---|
| A(推荐) | 机端计时:到期发送 turn.confirmation + outcome: timeout。实现简单,与离线片段无关。 |
| B | 云端计时:提案后服务端 sleep(timeout) 推送结果;需在会话层维护任务,断开连接时要取消任务。 |
规范上 A/B 等价对外语义;实现任择其一,但须在 session.ready 或产品文档中注明。
9. 与大模型的分工
- 提案轮:LLM 仍输出严格
flight_intentJSON(内部解析),并额外生成一句用户可听懂的拟执行说明(不得替代 JSON)。 - 确认轮:无需再跑完整意图模型;云端仅做规则路由 + 固定/模板 TTS。
- 若
turn.text误入确认轮且未匹配确认/取消:产品可选两种之一并在文档中写死:- 严格:忽略或提示「请先确认或取消上一条指令」;
- 宽松:取消待确认状态并当作新轮用户话重新走 LLM(风险:状态复杂,慎用)。
10. 状态机(机端参考)
stateDiagram-v2
[*] --> Idle
Idle --> PendingConfirm: dialog_result routing=flight_intent_pending
PendingConfirm --> Execute: turn.confirmation confirm
PendingConfirm --> Idle: turn.confirmation cancel
PendingConfirm --> Idle: turn.confirmation timeout
Idle --> Idle: chitchat as today
Execute --> Idle: after bridge accepts
禁止:在 PendingConfirm 下将提案中的 flight_intent 写入执行队列。
11. 安全与一致性与 trace_id
- 提案与批准两轮宜共用同一
flight_intent.trace_id(若提案有trace_id),便于日志与桥侧去重。 - 桥侧可对「同一
trace_id第二次可执行下发」做幂等;若缺少trace_id,建议云端在提案轮生成 UUID。
12. 版本与兼容
| 项目 | 约定 |
|---|---|
| 本文 | CLOUD_VOICE_FLIGHT_CONFIRM v1(可与主协议 1.0 并列声明) |
| 旧客户端 | 不发 flight_intent_confirm → 云端只发 routing: flight_intent → 行为与上线前一致。 |
| 新客户端 + 旧云端 | session.ready 无 flight_intent_confirm → 机端按即时执行或本地拒绝(产品定)。 |
13. 实现清单(云端 / 机端)
云端
- 解析
session.start门控配置;session.ready宣告能力。 - 飞控且门控开启 →
flight_intent_pending+ 生成confirm_prompt_text/ TTS。 - 处理
turn.confirmation(及可选turn.text过渡规则)。 - 维护
relates_to_turn_id → pending payload(会话内字典,连接断开清理)。
机端
- 根据
session.ready决定是否进入门控 FSM。 - 对
flight_intent_pending不执行。 - 计时;回传
turn.confirmation。 - 仅在
routing: flight_intent(且非 pending)时送桥执行。
14. 参考文档
文档版本:2026-04-08;修订可递增副版本并保留「breaking changes」小节。