Skip to main content
WSS

说明

基于 WebSocket 的实时语音对话接口,支持客户端持续发送语音输入,服务端实时返回用户语音转写、模型文本回复与模型语音回复。文本帧均为 JSON,二进制帧用于传输 PCM 音频数据。
  • 接入地址wss://preview.api.senseaudio.cn/ws/v1/realtime/voice-dialog
  • 鉴权方式:Bearer Token,格式 Authorization: Bearer SENSEAUDIO_API_KEY
  • 客户端文本帧:JSON 文本帧,必须包含 type 字段
  • 客户端音频帧pcm_s16le、采样率 16000Hz、单声道;建议每 40ms 发送一帧(1280 字节)
  • 服务端音频帧pcm_s16le、采样率 24000Hz、单声道
  • 计费单位:按二进制帧传输的 PCM 音频总长度计费,不足 1 秒按 1 秒计
  • start 必须作为连接后的第一个客户端消息发送,且同一连接内不能重复发送。
  • 客户端必须等待服务端返回 ready 后,才能开始发送二进制音频帧。
  • update 不能修改 modelaudio_setting
  • greeting 非空时会产生独立的开场白轮次及其 turn.done。客户端不能把该事件误认为用户语音轮次结束。

请求头 (Request Headers)

本文完整示例面向 Node.js 和 Python 服务端程序。浏览器原生 WebSocket API 不能设置自定义 Authorization 请求头,也不应把长期 API Key 暴露在浏览器代码中;浏览器场景应通过受控后端代理或专用的短期鉴权机制接入。

接入流程

客户端事件

1. start - 开始语音对话

start 用于初始化实时语音对话,必须作为第一个消息发送。同一连接内重复发送 start 会触发 bad_request,服务端随后以 1008 断开连接。 请求参数 请求示例
greeting 非空时,服务端会在 ready 后返回开场白音频,并以一个独立的 turn.done 结束该轮。若客户端需要等开场白播放完再上传用户语音,应先等待这个 turn.done;完整代码示例将 greeting 设为空,以便只演示用户语音轮次。

2. update - 更新对话配置

update 用于在已经开始的对话中修改配置。除 type 外,至少需要包含一个可更新字段;未包含的字段保持不变。如果配置有误,服务端返回 error,不会应用本次更新,连接不会断开。
update 不支持修改 modelaudio_setting
请求参数 请求示例

3. 音频流传输(Binary Message)

客户端必须在收到服务端 ready 后发送二进制音频帧。
  • 格式pcm_s16le
  • 采样率16000Hz
  • 声道数1
  • 推荐帧长40ms,即 640 个采样点、1280 字节
  • 发送节奏:按音频实际时长发送,不要将整个文件作为一个大二进制消息突发上传
  • 计费规则:按二进制帧传输的 PCM 音频总长度计费,不足 1 秒按 1 秒计

4. commit - 手动提交本轮音频

commit 用于手动提交当前已缓冲的音频,表示此轮用户音频输入结束。后续二进制帧不属于已提交的这一轮,而会进入新的输入缓冲。
commit 不会关闭 WebSocket 或持续麦克风流。实时客户端通常会继续发送麦克风帧,以支持下一轮输入和打断。在当前 preview 环境的兼容性测试中,commit 后完全停止二进制帧可能长时间收不到完成事件,并最终出现 fatal / stream idle timeout。本节实时麦克风示例不主动发送 commit,而是持续上传麦克风帧并依赖服务端 VAD 自动分轮。所有上传的二进制帧都可能参与计费;客户端在结束、关闭或出错时必须立即停止采集和发送。

5. cancel - 打断模型回复

cancel 用于打断并取消当前模型回复。

6. end - 结束对话

end 用于结束当前对话。服务端收到后会以 1000 关闭 WebSocket 连接。

服务端事件

ready - 连接就绪

表示服务端到模型的连接已经建立,可以开始发送音频数据。若 start.greeting 非空,ready 后还会收到一轮开场白事件;该轮也会以 turn.done 结束。

speech.started - 检测到用户开口

表示服务端检测到用户已经开始说话。

user.transcript.delta - 用户转写增量

用户语音转写的增量结果。该结果会随用户语音输入逐渐修正,前端渲染时建议使用最新值替换展示。

user.transcript.done - 用户转写最终稿

用户语音结束后返回的最终转写结果。语音结束包括服务端自动判断结束和客户端手动 commit 提交。

assistant.text.delta - 模型回复文本增量

模型回复文本的增量片段。客户端需要将本字段追加到之前收到的文本后,得到当前模型回复内容。

assistant.text.done - 模型回复文本全文

本轮模型回复文本的完整内容。

assistant.audio.start - 模型回复音频开始

表示模型回复音频开始。之后收到的二进制帧均为本轮模型回复音频。当前服务端输出为单声道 PCM。

assistant.audio.done - 模型回复音频结束

表示本轮模型回复音频结束,response_idassistant.audio.start 中的 response_id 一致。

turn.done - 本轮结束

表示一个对话轮次结束。非空 greeting 的开场白轮次和每个用户语音轮次都会分别返回 turn.done;客户端应维护会话状态,不能无条件在第一个 turn.done 后结束连接。

error - 错误通知

发生错误时,服务端返回 error。错误分为致命错误和非致命错误;致命错误会在服务端发送该消息后断开 WebSocket,非致命错误不会断开连接。

使用示例

以下示例直接采集系统麦克风,并把模型返回的音频实时播放到扬声器。建议使用耳机,避免扬声器声音被麦克风重新采集后触发误识别或错误打断。 运行前先设置 API Key:
示例默认连接生产地址。验证 preview 环境时,可额外设置:
示例在收到 ready 后持续上传 16000Hz / 单声道 / pcm_s16le 麦克风帧,由服务端 VAD 自动判断每轮语音结束,因此不会主动发送 commit。模型音频按服务端声明的 24000Hz / 单声道 / pcm_s16le 实时播放;普通 turn.done 只表示一轮完成,连接会继续用于下一轮。正常使用时按 Ctrl+C 发送 end。当服务端在模型播报期间返回 speech.started 时,示例会发送一次 cancel 并清除尚未播放的旧回复。若 greeting 非空,示例会先播完开场白再开启麦克风,避免开场白回采形成错误的用户轮次。
依赖:Node.js 18+;npm install ws@8 decibri@5decibri@5 提供预编译音频后端,当前支持 Windows x64、macOS arm64,以及 Linux x64/arm64。Linux 需要可用的 ALSA 环境;macOS 和 Windows 需要允许终端访问麦克风。
将上方代码保存为 realtime_voice.js,然后查看设备或直接运行:
两个示例都没有实现声学回声消除(AEC),请优先使用耳机。Node.js 的 decibri 会把麦克风输入重采样为 16000Hz;其他音频路径能否打开目标采样率取决于操作系统和设备。若初始化失败,请选择支持重采样的系统设备或音频后端,不要直接修改协议规定的输入 16000Hz 与当前输出 24000Hz

错误码说明

鉴权发生在 WebSocket Upgrade 阶段。缺少 Token、Token 无效或鉴权格式错误时,服务端返回 HTTP 401,不会先建立 WebSocket 再发送 JSON error

音色列表

注意事项

  1. 首条消息要求start 必须作为第一个消息发送,且同一连接内只能发送一次。
  2. 音频发送时机:必须等待 ready 后再发送二进制音频帧。
  3. 开场白轮次greeting 非空时,应区分开场白的 turn.done 与用户语音轮次的 turn.done
  4. 文本帧格式:客户端与服务端的文本帧均为 JSON,且必须包含 type 字段。
  5. 音频帧格式:客户端上传音频必须为裸 pcm_s16le / 16000Hz / 单声道,建议按 1280 字节 / 40ms 分帧发送。
  6. 持续上行与超时:长连接客户端应持续处理麦克风流,并设置应用层连接与设备超时;结束、关闭或出错时必须停止采集和发送。
  7. 服务端音频解析:模型返回的二进制音频帧按 assistant.audio.start 中的 sample_rateformat 解析,当前为单声道;实时播放应使用有界队列,避免阻塞 WebSocket 接收回调。
  8. 打断处理:用户在模型播报期间开口时,可在收到 speech.started 后发送一次 cancel,同时丢弃已取消回复中尚未播放以及仍在途的音频帧。
  9. 回声控制:示例没有实现 AEC,建议使用耳机,避免模型播报被麦克风回采并触发新的用户轮次。
  10. 结束连接:如需主动结束对话,请发送 end,服务端会以关闭码 1000 正常关闭连接。

相关资源

语音合成 WebSocket

基于 WebSocket 的实时文本转语音合成协议。

语音识别 WebSocket

基于 WebSocket 的实时语音识别协议。
bearerAuth
type:http

Bearer Token 鉴权,格式 Authorization: Bearer <SENSEAUDIO_API_KEY>

method
type:string

GET

headers
type:object
Authorization
type:string
必填

Bearer Token,格式:Bearer <SENSEAUDIO_API_KEY>。

start - 开始语音对话
type:object

初始化模型与对话配置。

update - 更新对话配置
type:object

更新后续轮次使用的音色或系统提示词。

commit - 提交本轮音频
type:object

提交当前用户音频缓冲。

cancel - 打断模型回复
type:object

打断并取消当前模型回复。

end - 结束会话
type:object

结束对话并请求正常关闭 WebSocket。

PCM 音频二进制帧
type:string

原始 WebSocket Binary Message,不是 JSON 或 Base64 文本。

ready - 连接就绪
type:object

模型连接已建立;非空 greeting 会先产生独立开场白轮次。

speech.started - 检测到用户开口
type:object

服务端检测到用户开始说话。

user.transcript.delta - 用户转写增量
type:object

返回当前最新的用户语音转写。

user.transcript.done - 用户转写最终稿
type:object

返回本轮用户语音的最终转写。

assistant.text.delta - 模型文本增量
type:object

返回模型回复文本的增量片段。

assistant.text.done - 模型文本全文
type:object

返回本轮模型回复文本全文。

assistant.audio.start - 模型音频开始
type:object

后续二进制帧为本轮模型回复音频。

assistant.audio.done - 模型音频结束
type:object

本轮模型回复音频发送完成。

turn.done - 轮次结束
type:object

一个开场白或用户语音轮次结束。

error - 错误通知
type:object

返回致命或非致命错误。

PCM 音频二进制帧
type:string

原始 WebSocket Binary Message,不是 JSON 或 Base64 文本。