180 lines
7.4 KiB
Markdown
180 lines
7.4 KiB
Markdown
# 云端语音 · `dialog_result` 与飞控二次确认(v1)
|
||
|
||
供 **云端服务** 与 **机端 voice_drone_assistant** 同步实现。**尚无线上存量**:本文即 **`dialog_result` 的飞机位约定**,服务端可按 v1 直接改结构,无需迁就旧字段。
|
||
|
||
---
|
||
|
||
## 1. 目标
|
||
|
||
1. **`routing=chitchat`**:只走闲聊与对应 TTS,**不**下发可执行飞控负载。
|
||
2. **`routing=flight_intent`**:携 **`flight_intent`(v1)** + **`confirm`**;机端是否立刻执行仅由 **`confirm.required`** 决定,并支持 **确认 / 取消 / 超时** 交互。
|
||
3. **ASR**:飞控句是否改用云端识别见 **附录 A**;与 `confirm` 独立。
|
||
|
||
---
|
||
|
||
## 2. 术语
|
||
|
||
| 术语 | 含义 |
|
||
|------|------|
|
||
| **首轮** | 用户说一句;本轮 WS 收到 `dialog_result` 为止。 |
|
||
| **确认窗** | `confirm.required=true` 时,机端播完本轮 PCM 后 **仅收口令** 的时段,时长 **`confirm.timeout_sec`**。 |
|
||
| **`flight_intent`** | 见 `FLIGHT_INTENT_SCHEMA_v1.md`。 |
|
||
|
||
---
|
||
|
||
## 3. `dialog_result` 形状(云端 → 机端)
|
||
|
||
### 3.1 公共顶层(每轮必带)
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `turn_id` | string | 是 | 与现有一致,关联本 turn。 |
|
||
| **`protocol`** | string | 是 | 固定 **`cloud_voice_dialog_v1`**,便于机端强校验、排障。 |
|
||
| `routing` | string | 是 | **`chitchat`** \| **`flight_intent`** |
|
||
| `user_input` | string | 建议 | 本回合用于生成回复的用户文本(可为云端 STT 结果)。 |
|
||
|
||
### 3.2 `routing=chitchat`
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `chat_reply` | string | 是 | 闲聊文本(与 TTS 语义一致或由服务端定义)。 |
|
||
| `flight_intent` | — | **禁止** | 不得出现。 |
|
||
| `confirm` | — | **禁止** | 不得出现。 |
|
||
|
||
### 3.3 `routing=flight_intent`
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `flight_intent` | object | 是 | v1:`is_flight_intent`、`version`、`actions`、`summary` 等。 |
|
||
| **`confirm`** | object | 是 | 见 §3.4;**每轮飞控必带**,机端拒收缺字段报文。 |
|
||
|
||
### 3.4 `confirm` 对象(`routing=flight_intent` 时必填)
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| **`required`** | bool | 是 | `true`:进入确认窗,**首轮禁止**执行飞控;`false`:首轮允许按机端执行开关立即执行(调试/免确认策略)。 |
|
||
| **`timeout_sec`** | number | 是 | 确认窗秒数;建议默认 **10**。 |
|
||
| **`confirm_phrases`** | string[] | 是 | 非空;与口播一致,推荐 **`["确认"]`**。 |
|
||
| **`cancel_phrases`** | string[] | 是 | 非空;推荐 **`["取消"]`**。 |
|
||
| **`pending_id`** | string | 是 | 本轮待定意图 ID(建议 UUID);日志、可选第二轮遥测(附录 B)。 |
|
||
| **`summary_for_user`** | string | 建议 | 与口播语义一致,供日志/本地 TTS 兜底;**最终以本轮 PCM 为准**。 |
|
||
|
||
---
|
||
|
||
## 4. 播报(理解与提示)
|
||
|
||
- **TTS**:仍用 **`tts_audio_chunk` + PCM**;内容示例:复述理解 + **「请回复确认或取消」**;服务端在 `confirm_*_phrases` 中与口播保持一致(推荐 **`确认` / `取消`**)。
|
||
- 机端 **须** 在 **本轮 PCM 播放结束**(或播放管线给出「可收听下一句」)后再进入确认窗,避免抢话。
|
||
|
||
---
|
||
|
||
## 5. 机端短语匹配(确认窗内)
|
||
|
||
对用户 **一句** STT 规范化后,与 `confirm_phrases` / `cancel_phrases` 比对(机端实现见 `match_phrase_list`):
|
||
|
||
1. **取消优先**:若命中 `cancel_phrases` 任一 → 取消本轮。
|
||
2. **确认**:否则若命中 `confirm_phrases` 任一 → 执行 **`flight_intent`**。
|
||
3. **规则要点**:**全等**(去尾标点)算命中;或对 **很短** 的句子(长度 ≤ 短语长+2)允许 **子串** 命中,以便「好的确认」类说法;**整句复述**云端长提示(如「请回复确认或取消」)不会因同时含「确认」「取消」子串而误匹配。
|
||
4. **未命中**:可静候超时(v1 建议确认窗内 **可多句** 直至超时,由机端实现决定)。
|
||
4. **超时 / 取消** 固定中文播报见下表(机端本地 TTS,降低时延):
|
||
|
||
| 事件 | 文案 |
|
||
|------|------|
|
||
| 超时 | `未收到确认指令,请重新下发指令` |
|
||
| 取消 | `已取消指令,请重新唤醒后下发指令` |
|
||
| 确认并执行 | `开始执行飞控指令` |
|
||
|
||
若产品强制云端音色,见 **附录 C**。
|
||
|
||
---
|
||
|
||
## 6. 机端执行条件(归纳)
|
||
|
||
| 条件 | 行为 |
|
||
|------|------|
|
||
| `routing=chitchat` | 不执行飞控。 |
|
||
| `routing=flight_intent` 且 `confirm.required=false` 且机端已开执行开关 | 首轮校验通过后 **可立即** 执行。 |
|
||
| `routing=flight_intent` 且 `confirm.required=true` | **仅**在确认窗内命中确认短语后执行;**首轮绝不**执行。 |
|
||
|
||
---
|
||
|
||
## 7. 机端状态机(摘要)
|
||
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> Idle
|
||
Idle --> Chitchat: routing=chitchat
|
||
Idle --> ExecNow: routing=flight_intent 且 confirm.required=false
|
||
Idle --> ConfirmWin: routing=flight_intent 且 confirm.required=true
|
||
|
||
ConfirmWin --> ExecIntent: 命中 confirm_phrases
|
||
ConfirmWin --> SayCancel: 命中 cancel_phrases
|
||
ConfirmWin --> SayTimeout: timeout_sec
|
||
|
||
ExecNow --> Idle
|
||
ExecIntent --> Idle
|
||
SayCancel --> Idle
|
||
SayTimeout --> Idle
|
||
Chitchat --> Idle
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 会话握手
|
||
|
||
**`session.start`**(或等价)的 `client` **须** 带:
|
||
|
||
```json
|
||
{
|
||
"protocol": {
|
||
"dialog_result": "cloud_voice_dialog_v1"
|
||
}
|
||
}
|
||
```
|
||
|
||
服务端仅对声明该协议的客户端下发 §3 结构;机端若未声明,服务端可拒绝或返显式错误码(由服务端定义)。
|
||
|
||
---
|
||
|
||
## 9. 安全说明
|
||
|
||
二次确认减轻 **错词误飞**,不替代 **急停、遥控介入、场地规范**。
|
||
TTS 若为「请回复确认或取消」,服务端请在 `confirm_phrases` / `cancel_phrases` 中下发 **`确认`**、**`取消`**(与口播一致);**听与判均在机端**,云端无需再收一轮确认消息。
|
||
|
||
---
|
||
|
||
## 附录 A:云端 ASR(可选)
|
||
|
||
服务端可将飞控相关 utterance 改为 **云端 STT** 结果填入 `user_input`,与 `flight_intent` 解析同源;**执行仍以 `flight_intent` + `confirm` 为准**。
|
||
|
||
---
|
||
|
||
## 附录 B:第二轮 `turn`(可选遥测)
|
||
|
||
用户确认后机端可再发一轮文本(ASR 原文),payload 可带 `pending_id`、`phase: confirm_ack`;**执行成功与否不依赖**该轮响应。
|
||
|
||
---
|
||
|
||
## 附录 C:超时/取消走云端 TTS(可选)
|
||
|
||
若 `confirm.play_server_tts_on_timeout` 为真(服务端与机端扩展字段),则由云端推 PCM;**易增延迟**,v1 默认 **关**,以 §5 本地播报为准。
|
||
|
||
---
|
||
|
||
## 文档关系
|
||
|
||
| 文档 | 关系 |
|
||
|------|------|
|
||
| `FLIGHT_INTENT_SCHEMA_v1.md` | `flight_intent` 体 |
|
||
| `DEPLOYMENT_AND_OPERATIONS.md` | 部署 |
|
||
|
||
**版本**:`cloud_voice_dialog_v1`(本文);后续 breaking 变更递增 `cloud_voice_dialog_v2` 等。
|
||
|
||
---
|
||
|
||
## 机端实现状态(voice_drone_assistant)
|
||
|
||
- **`CloudVoiceClient`**:`session.start.client` 已带 `protocol.dialog_result: cloud_voice_dialog_v1`;`run_turn` 返回含 `protocol`、`confirm`。
|
||
- **`main_app.TakeoffPrintRecognizer`**:解析 `confirm`;`required=true` 且已开 `ROCKET_CLOUD_EXECUTE_FLIGHT` 时,播完本轮 PCM 后进入 **`FLIGHT_CONFIRM_LISTEN`**,本地匹配短语 / 超时文案见 **`voice_drone.core.cloud_dialog_v1`**。
|
||
- **服务端未升级前**:若缺 `protocol` 或 `confirm`,机端 **不执行** 飞控(仍播 TTS)。
|