5.8 KiB
Cloud Voice — pcm_asr_uplink v1(机端麦克风 → 阿里云 Fun-ASR → 云端 LLM/TTS)
本文档供机端团队实现与 voicellmcloud 的 WebSocket 对接:用户语音以 PCM 分片上行,服务端调用 阿里云百炼 Fun-ASR 实时识别(与 Qwen LLM 共用 DASHSCOPE_API_KEY),识别完成后与 text_uplink 相同:dialog_result → llm.text_delta* → tts_audio_chunk* → turn.complete。
路径、鉴权:与现网一致 — WS_PATH(默认 ws://<host>:8765/v1/voice/session),首帧 session.start 中带 auth_token(若服务端启用 BEARER_TOKEN)。
产品约束(机端):若要求「未唤醒不上云、Fun-ASR 不按量浪费」,必须按 CLOUD_VOICE_CLIENT_WAKE_GATE_v1.md 控制何时发送 turn.audio.*。服务端不对唤醒词做校验。
多轮助手 UX(问候、滴声、断句提示音、5s 超时、飞控/闲聊):CLOUD_VOICE_ASSISTANT_SESSION_v1.md。
1. 与 text_uplink 的差异
| 项目 | text_uplink |
pcm_asr_uplink(本文) |
|---|---|---|
session.start.transport_profile |
text_uplink |
pcm_asr_uplink |
| 用户上行 | turn.text(机端 STT 结果) |
turn.audio.start / chunk / end + 可选调试用 turn.text |
| 服务端 STT | 无 | Fun-ASR(DashScope) |
| 下行 | 相同 | 相同,并增加 asr.partial(可选展示) |
session.ready.server_caps.accepts_audio_uplink:本模式下为 true。
2. 音频约定(强制)
| 字段 | 值 |
|---|---|
| 采样率 | 16000 Hz(与 turn.audio.start.sample_rate_hz 及服务端 ASR_AUDIO_SAMPLE_RATE 一致) |
| 声道 | mono |
| 位深 | 16-bit signed little-endian(pcm_s16le) |
| 分片载体 | turn.audio.chunk.pcm_base64 = 裸 PCM 字节的 Base64(无 WAV 头) |
| 禁止 | 对 PCM 使用 WebSocket binary 上行 — 服务端接收循环只读文本帧;误发 binary 将收到 error 或直接断连,机端或表现为「收到空文本帧」。 |
参考块大小:官方示例常用 每包约 3200 帧(200ms) 量级;可依网络微调,勿长时间不传数据(服务端侧连接有句末/静音策略,详见阿里云文档)。
3. 时序(每一轮用户说话)
机端 服务端
|-- session.start (pcm_asr_uplink) ------->|
|<-- session.ready -------------------------|
|-- turn.audio.start (turn_id) ----------->|
|-- turn.audio.chunk (pcm_base64) * ------>|
| ... |--> Fun-ASR 流式识别
|<-- asr.partial (可选, 多次) --------------|
|-- turn.audio.end (turn_id) -------------->|
| |--> Final 文本并入 LLM 管线
|<-- dialog_result -------------------------|
|<-- llm.text_delta* -----------------------|
|<-- tts_audio_chunk* + binary -------------|
|<-- turn.complete -------------------------|
- 同一
turn_id贯穿:turn.audio.*→asr.partial→dialog_result/ TTS /turn.complete。 turn.audio.start与上一轮turn.complete之间:不得交叉另一轮turn.audio.start;且不得在 ASR 进行中发送turn.text/tts.synthesize(服务端会拒绝)。- 识别结果为空:服务端回复
error(ASR_FAILED),不进入 LLM。
4. JSON 消息字段
4.1 session.start
在原有字段基础上设置:
"transport_profile": "pcm_asr_uplink"
其余 proto_version、session_id、auth_token、client 与 text_uplink 相同。
4.2 turn.audio.start
{
"type": "turn.audio.start",
"proto_version": "1.0",
"transport_profile": "pcm_asr_uplink",
"turn_id": "<UUID>",
"sample_rate_hz": 16000,
"format": "pcm_s16le"
}
4.3 turn.audio.chunk
{
"type": "turn.audio.chunk",
"proto_version": "1.0",
"transport_profile": "pcm_asr_uplink",
"turn_id": "<与 start 相同>",
"pcm_base64": "<Base64(裸 PCM s16le mono)>"
}
4.4 turn.audio.end
{
"type": "turn.audio.end",
"proto_version": "1.0",
"transport_profile": "pcm_asr_uplink",
"turn_id": "<与 start 相同>"
}
4.5 下行 asr.partial(听写/状态,可选 UI)
{
"type": "asr.partial",
"proto_version": "1.0",
"transport_profile": "pcm_asr_uplink",
"turn_id": "<UUID>",
"text": "<当前识别文本>",
"is_final": false
}
is_final:对应 Fun-ASR 分句结束时为 true(可与下一段增量衔接展示)。
5. 调试与回退
- 仅用文本调试:可在
pcm_asr_uplink会话中发送turn.text(需不在 Fun-ASR 进行中),服务端逻辑与text_uplink一致。 - 仅 TTS、无 LLM:仍可用
tts.synthesize(须在无 ASR 进行时)。
6. 服务端环境变量(运维)≠ 机端配置
| 变量 | 含义 |
|---|---|
DASHSCOPE_API_KEY |
与 Qwen 相同,百炼控制台 API Key |
DASHSCOPE_WEBSOCKET_URL |
默认北京推理 WebSocket;国际域见阿里云「实时语音识别」地域说明 |
DASHSCOPE_ASR_MODEL |
默认 fun-asr-realtime |
ASR_AUDIO_SAMPLE_RATE |
默认 16000(机端必须一致) |
机端不需要持有 DashScope Key;仅需连你们已部署的 voicellmcloud。
7. 参考
- 下行消息(
dialog_result、tts_audio_chunk、turn.complete等):docs/API_SPECIFICATION.md - 协议总则:
docs/CLOUD_VOICE_PROTOCOL_v1_text_uplink.md - 阿里云实时语音识别产品说明与示例:Model Studio — Real-time speech recognition