7.5 KiB
7.5 KiB
语音助手会话方案 v1(服务端 + 机端对齐)
本文档描述 「唤醒 → 问候 → 滴声开录 → 断句上云 → 提示音 → 云端理解与 TTS → 分支循环/待机」 的端到端方案,供 服务端(voicellmcloud) 与 机端(本仓库 voice_drone_assistant) 分工落地。
v1 明确不做:播报中途 抢话 / 打断 TTS(barge-in);播放 TTS 时机端 关麦或不处理用户语音。
关联协议:
- 音频上行与 Fun-ASR:CLOUD_VOICE_PROTOCOL_pcm_asr_uplink_v1.md
- 未唤醒不上云:由服务端/产品文档
CLOUD_VOICE_CLIENT_WAKE_GATE_v1约定(机端须本地门禁后再建联上云) - 总接口:以 voicellmcloud 仓库
API_SPECIFICATION为准 - 飞控确认窗:CLOUD_VOICE_FLIGHT_CONFIRM_v1.md
1. 产品流程(用户视角)
- 用户说唤醒词(如「无人机」,由机端配置),仅本地处理,不上云 ASR。
- 机端播放问候语(如「你好,有什么事儿吗」)— 可用本地 TTS 或
tts.synthesize。 - 机端 滴一声,表示 开始收音;同时启动 5 秒静默超时 计时(见 §4)。
- 用户说话;机端 VAD/端点检测 得到 一整句 后:
- 播放 极短断句提示音(表示「已截句、将上云」);
- 提示音播放期间闭麦或做回声隔离,提示音结束后 短消抖(建议 150~300 ms)再恢复采集逻辑,避免把提示音当成用户语音。
- 将该句 PCM 以
turn.audio.*发云端;云端 Fun-ASR → LLM →dialog_result→ TTS;机端播完 全部tts_audio_chunk及收到turn.complete后,视为本轮播报结束(见 §3 服务端)。 - 分支:
routing === flight_intent:进入 飞控子状态机(口头确认/取消/超时),不使用 §4 的「闲聊滴声后 5s」规则覆盖确认窗;超时以dialog_result.confirm.timeout_sec及 CLOUD_VOICE_FLIGHT_CONFIRM_v1.md 为准。routing === chitchat:本轮结束后 再滴一声,进入下一轮 步骤 4(同一 WebSocket 会话内 新turn_id再起一轮turn.audio.*)。
- 若在 步骤 3 的滴声之后 连续 5 s 内未检测到有效语音(见 §4),机端播 超时提示音,不再收音,回到 待机(仅唤醒)。
2. 机端状态机(规范性)
| 状态 | 含义 | 开麦 | 上云 ASR | 备注 |
|---|---|---|---|---|
STANDBY |
仅监听唤醒 | 按现网 VAD | 禁止 turn.audio.* |
本地 STT + 唤醒词 |
GREETING |
播问候 | 可关麦或忽略输入 | 否 | 避免问候进识别 |
PROMPT_LISTEN |
已滴「开始录」,等用户一句 | 开 | 否 | 5s 超时在此状态监控 |
SEGMENT_END |
已断句,播短提示音 | 闭麦/屏蔽 | 否 | 消抖后再转 UPLOADING |
UPLOADING |
发送 turn.audio.* |
否 | 是 | 一轮一个 turn_id |
PLAYING_CLOUD_TTS |
播云端 TTS | 关麦(v1 无抢话) | 否 | 至 turn.complete + PCM 播完 |
FLIGHT_CONFIRM |
飞控确认窗 | 按飞控文档 | 可 turn.text 或按产品另定 |
独立超时,不共用 5s |
CHITCHAT_TAIL |
闲聊结束,将再滴一声 | — | 否 | 回到 PROMPT_LISTEN |
并发:同一时刻仅允许 一路 turn.audio.start~end;须等 turn.complete 后再开下一轮(与现有 pipeline_lock 一致)。
唤醒前:须满足未唤醒不上云的产品/协议约定。
3. 服务端(voicellmcloud)职责 — v1 无新消息类型
3.1 单轮行为(不变)
对每个完整 turn.audio.* 或 turn.text:
- Fun-ASR(仅
pcm_asr_uplink+ 音频轮)→ 文本 - LLM 流式 →
dialog_result(routing/flight_intent/chat_reply等) tts_audio_chunk*→turn.complete
服务端 不 下发「请再滴一声」「进入待机」类机端 UX 信令;这些由机端根据 routing + turn.complete 固定规则 驱动。
3.2 机端判定「播报完成」
须同时满足:
- 收到该轮
turn.complete - 已按序播完该轮关联的 binary PCM(
tts_audio_chunk与现实现一致)
然后机端再执行 §1 步骤 6 的分支。
3.3 可选下行
asr.partial:机端 不得 用于驱动状态跳转;仅可 UI 展示。- 错误:
error/ASR_FAILED等 → 机端播简短失败提示后,建议 回STANDBY或回到PROMPT_LISTEN(产品定)。
4. 5 秒静默超时(闲聊路径)
| 项 | 约定 |
|---|---|
| 起算点 | 「开始收音」的 滴声播放结束 时刻(或滴声后固定 50~100 ms 偏移,避免与滴声能量重叠)。 |
| 「无说话」 | 麦克 RMS / VAD 低于阈值,持续累计 ≥ 5 s(建议可配置,默认 5)。 |
| 期间若开始说话 | 清零超时;断句上云后本超时在下一轮「滴声」后重新起算。 |
| 触发动作 | 播 超时提示音 → 进入 STANDBY(不再滴声、不上云)。 |
| 不适用 | FLIGHT_CONFIRM 整段;确认窗用 服务端给的 timeout_sec。 |
机端配置(system.yaml cloud_voice):listen_silence_timeout_sec、post_cue_mic_mute_ms、segment_cue_duration_ms;环境变量见 main_app.py 头部说明。
5. 断句后提示音(工程)
| 项 | 约定 |
|---|---|
| 目的 | 用户感知「已截句,可等待播报」 |
| 实现 | 机端本地短 WAV / 蜂鸣;时长建议 ≤ 200 ms |
| 回声 | SEGMENT_END 阶段闭麦或硬件 AEC;结束后 ≥ 150 ms 再进入 UPLOADING |
| 与云端 | 无需 上传该提示音 |
6. 时序简图(闲聊多轮)
sequenceDiagram
participant U as 用户
participant D as 机端
participant S as 服务端
U->>D: 唤醒词(本地)
D->>D: GREETING 播问候
D->>D: 滴声 → PROMPT_LISTEN(起 5s 定时)
U->>D: 一句语音
D->>D: VAD 断句 → 短提示音 → UPLOADING
D->>S: turn.audio.start/chunk/end
S->>D: asr.partial(可选)
S->>D: dialog_result + TTS + turn.complete
D->>D: PLAYING_CLOUD_TTS(关麦)
alt chitchat
D->>D: 再滴声 → PROMPT_LISTEN
else flight_intent
D->>D: FLIGHT_CONFIRM(独立超时)
end
7. 配置建议(机端)
| 键 | 默认值 | 说明 |
|---|---|---|
listen_silence_timeout_sec |
5 |
滴声后起算 |
post_cue_mic_mute_ms |
150~300 |
断句提示音后再采集 |
cue_tone_duration_ms / segment_cue_duration_ms |
≤200 |
断句提示 |
flight_confirm_handling |
遵循飞控文档 | 禁用闲聊 5s 覆盖 |
8. 机端开发自检
STANDBY下无turn.audio.start。PLAYING_CLOUD_TTS与SEGMENT_END提示音阶段 不开麦(v1)。- 每轮新
turn_id;不并行两轮音频上行。 flight_intent后进入FLIGHT_CONFIRM,不误用 5s 闲聊超时。chitchat在 TTS 完成后 再滴 再PROMPT_LISTEN。
9. 非目标(v1)
- 播报中抢话、打断 TTS、实时 re-prompt。
- 服务端驱动「滴声/待机」(均由机端规则实现)。
- 连续免唤醒「直接说指令」跨多轮(若需另开 v2)。
10. 修订记录
| 版本 | 日期 | 说明 |
|---|---|---|
| v1 | 2026-04-07 | 首版:小爱类会话 + 双端分工;不含 barge-in |