本文介绍基于 WebSocket 协议的实时多模态交互 API。WebSocket协议延迟低、资源占用少,是首选接入方案。
- Go:
gorilla/websocket - PHP:
Ratchet - Node.js:
ws
- TLS 版本要求 TLS1.2 或以上
- 开启 SNI(SERVER NAME INDICATION)
- 配置 CA 证书(GlobalSign Root CA - R3)(也可至GlobalSign官网下载)
前提条件
已开通服务并获取与配置 API Key。请配置API Key到环境变量,而非硬编码在代码中,防范因代码泄露导致的安全风险。
调用时序图
[关键流程] 服务端返回Started消息表示会话创建成功,但客户端禁止立即发送音频。客户端必须等待并接收到DialogStateChanged事件且state为Listening后,方可开始发送音频流。

服务地址
鉴权
需要在发起初始的WebSocket握手(HTTP Upgrade)请求时,把API Key放在HTTP Header里(需要将your_api_key替换为真实的API Key):
语音交互
多模态交互应用开启了语音交互后,支持语音识别和语音合成。
语音识别支持的模型包括:Paraformer实时语音识别(Paraformer),FUN-ASR实时语音识别(FunASR),Qwen-Audio-3.0-ASR-Flash-Streaming,千问3-ASR-Flash-Realtime(qwen3-asr-flash-realtime),多模态交互轻量版语音识别(AppSpecificASR-Realtime)。
语音合成支持的模型包括:语音合成CosyVoice-v2大模型(cosyvoice-v2),语音合成CosyVoice-v3-Flash大模型(cosyvoice-v3-flash),语音合成CosyVoice-v3-plus大模型(cosyvoice-v3-plus),语音合成CosyVoice-v3.5-Flash大模型(cosyvoice-v3.5-flash),语音合成CosyVoice-v3.5-Plus大模型(cosyvoice-v3.5-plus),Qwen-Audio-3.0-TTS-Plus(qwen-audio-3.0-tts-plus)、Qwen-Audio-3.0-TTS-Flash(qwen-audio-3.0-tts-flash),千问3-TTS-Flash-Realtime(qwen3-tts),千问3-TTS-Instruct-Flash-Realtime(qwen3-tts-instruct),千问3-声音设计(qwen3-tts-vd),千问3-声音复刻(qwen3-tts-vc),Sambert语音合成(sambert),多模态交互轻量版语音合成(AppSpecificTTS)。
语音合成支持的音色,可以在控制台上选择了模型后,点击右侧语音交互体验区域的右上角查看音色列表。
官方音色也可以参考官方文档:支持的音色,sambert支持的音色参考Sambert音色列表(去掉开头的"sambert-"和末尾的"-v1"后就是voice的取值)。
使用复刻音色时,确认复刻音色状态为"OK"后才能使用。查询方法参考查询特定音色。
消息类型
二进制消息(Binary Message)
当前二进制消息仅包含音频数据。
上传音频
上传音频时,将原始音频直接转为二进制流即可,无需额外处理。
上传的语音识别音频需满足:16bit(采样位深)、单声道、有符号、little-endian PCM编码,采样率参考Start消息的参数parameters.upstream.sample_rate的取值说明。
如果希望减少网络流量和带宽占用,用户可以把PCM音频编码为Opus格式,同时设置上传音频格式为raw-opus。
上传音频时,根据Start消息中upstream.mode设置不同,采取的措施也不同:
-
mode为
tap2talk或duplex:客户端需持续上传音频,服务端自动检测语音活动。建议每100ms上传一次数据,间隔太长或太短会对延时和处理效率造成负面影响。- 音频上传速率计算公式:
数据每次上传的字节数 = 采样率 * 采样位深/8 * 时间间隔(ms)/ 1000 - 以16kHz采样率、16bit位深、100ms间隔为例,每次应上传
16000 * (16/8) * 100 / 1000 = 3200字节的PCM数据。
- 音频上传速率计算公式:
-
mode为
push2talk:客户端无需持续上传音频,但需通过SendSpeech和StopSpeech通知服务端音频识别的开始和结束。发送SendSpeech后需立即上传音频,否则会增加处理时间。
下发音频
服务端将大模型回复发送至TTS生成语音然后下发给客户端:
- 下发音频为16bit单声道,采样率和编码由Start消息参数定义。
- 下发速度取决于TTS服务性能,通常快于播放速度。
- 音频下发前发送RespondingStarted事件;结束后发送RespondingEnded事件。
- 客户端需在播放完成后上报LocalRespondingEnded,通知服务端播放结束。
文本消息(Text Message)
文本消息是JSON格式字符串,按传递方向分为两类:
- 输入消息(Input Message):客户端发送给服务端的指令(directive),表示客户端希望服务端执行特定动作。
- 输出消息(Output Message):服务端发送给客户端的事件(event),表示服务端动作执行结果或进展。
header和payload。
-
payload:内容随消息类型变化。 -
header:内容固定,包含以下参数:参数
类型
是否必选
说明
task_id
string
是
本次连接唯一标识,用于在工程链路上跟踪任务执行。由客户端生成,格式建议为36位uuid字符串,格式示例:"f894c16f-f20e-4c1d-837e-89e0fbc63a43"
streaming
string
是
输入输出类型,对于多模态交互必须为 "duplex" ,表示流式输入,流式输出
action
string
是
模型输入消息类型:
run-task: 任务的第一个输入消息
finish-task: 任务的最后一个输入消息
continue-task: 任务中其他输入消息
连接保活策略
百炼平台规定,如果在任意连续的60秒内服务端没有向客户端发送任何消息,则认为调用发生错误,WebSocket连接将被服务端主动断开并返回ResponseTimeout错误。
若客户端需在无交互时保持连接,应定期发送心跳消息(HeartBeat)。服务端会回应心跳,确保连接活跃,避免超时关闭。
移动端和C++ SDK已内置心跳保活逻辑,用户无需手动发送。
文本消息类型
开始会话
Start - Input Message
请求开始会话消息。服务收到Start消息后,向客户端发送Started消息。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
task_group | string | 是 | 任务组名称,固定为"aigc",请直接复制使用 | |
task | string | 是 | 任务名称,固定为"multimodal-generation",请直接复制使用 | |
function | string | 是 | 调用功能,固定为"generation",请直接复制使用 | |
model | string | 是 | 阿里云百炼模型名称,固定为"multimodal-dialog",请直接复制使用 | |
input | directive | string | 是 | 指令名称:Start |
workspace_id | string | 是 | 客户在阿里云百炼业务空间ID(Workspace ID),可在多模态交互开发套件控制台,点击左下角业务空间名称,"业务空间详情"中查看,目前仅支持主账号默认业务空间。 | |
app_id | string | 是 | 客户创建的应用ID(APP ID),可在多模态交互开发套件控制台的"我的应用"页面查看。 | |
dialog_id | string | 否 | 对话ID,默认不填时是开启新会话,服务端会自动生成并在事件中下发,格式示例:"12345678-1234-1234-1234-1234567890ab",共36个字符。当希望继续之前的对话时,把当时服务端下发的dialog_id在这里传入 | |
parameters | upstream | object | 是 | 参数说明参考下方 parameters.upstream的参数说明表格 |
downstream | object | 否 | 参数说明参考下方 parameters.downstream的参数说明表格 | |
client_info | object | 是 | 参数说明参考下方 parameters.client_info的参数说明表格 | |
biz_params | object | 否 | 参数说明参考下方 parameters.biz_params的参数说明表格 |
一级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|
type | string | 是 | 上行类型: AudioOnly 仅语音通话 |
mode | string | 否 | 客户端使用的模式,默认tap2talk。 可选项:
三种模式的对比可以参考下方的客户端使用的三种模式对比表格。 |
audio_format | string | 否 | 音频格式,支持pcm,raw-opus,默认为pcm |
sample_rate | int | 否 | 语音识别的采样率,支持范围:
默认为16000 |
vocabulary_id | string | 否 | 热词id,设置该参数时会覆盖管控台热词配置。当管控台提供的热词不能满足客户需求时,可以考虑用Open API程序化管理热词,参见热词API文档。 |
language | string | 否 | 语音识别语种,默认和控制台选择的语言保持一致。设置多个语种时,使用英文逗号分隔,例如: |
一级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|
voice | string | 否 | 合成语音的音色,支持范围取决于用户在管控台选择的语音合成模型 |
sample_rate | int | 否 | 合成语音的采样率,支持范围:
默认为24000。 千问-TTS、千问3-TTS模型仅支持24000。 |
audio_format | string | 否 | 音频格式,支持pcm,opus,mp3,raw-opus,默认为pcm。 千问-TTS模型仅支持pcm。 注意:opus 和 raw-opus的区别是opus格式的每一包数据都有额外ogg封装(RFC 7845) |
frame_size | int | 否 | 合成音频的帧大小,取值范围:
默认值为60,单位ms 只在合成音频格式为opus或raw-opus时生效 |
volume | int | 否 | 合成音频的音量,取值范围0-100,默认50 |
speech_rate | int | 否 | 合成音频的语速,取值范围50-200,表示默认语速的50%-200%,默认100 |
pitch_rate | int | 否 | 合成音频的声调,取值范围50-200,默认100 |
bit_rate | int | 否 | 合成音频的比特率,取值范围:6~510kbps,默认值为32,单位kbps,只在合成音频格式为mp3, opus或raw-opus时生效 |
intermediate_text | string | 否 | 控制返回给用户哪些中间文本:
可以设置多种,以逗号分隔,默认为transcript |
word_timestamp_enabled | boolean | 否 | 是否下发tts合成音频对应的时间戳。如果设置为true,会在RespondingContent.extra_info下返回时间戳信息,用于客户端显示字幕等,默认为false。 必须在intermediate_text有指定dialog的情况下才会返回; 只有CosyVoice音色列表中表明支持时间戳的音色和复刻音色才会返回。 |
transmit_rate_limit | int | 否 | 下发音频发送速率限制,单位:字节每秒 |
incremental_response | boolean | 否 | 是否增量返回大模型结果,true为增量,false为全量。默认为false,全量下发 |
instruction | string | 否 | 设置指令,用于控制方言、情感等合成效果。该功能适用的模型以及在不同模型的格式要求请参见指令控制。 |
language | string | 否 | 语音合成语种,默认和控制台选择的语言保持一致。 |
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
user_id | string | 是 | 终端用户ID,客户根据自己业务规则生成,用来针对不同终端用户实现定制化功能。最大长度36个字符。 | |
device | uuid | string | 否 | 客户端全局唯一的ID,需要用户自己生成并传入SDK,最大长度40个字符。一个终端用户可以有多个设备,那么每一个设备的uuid都不同,但user_id相同。 |
network | ip | string | 否 | 调用方公网IP |
location | latitude | string | 否 | 调用方纬度信息,在需要客户端精确位置的业务场景提交 |
longitude | string | 否 | 调用方经度信息,在需要客户端精确位置的业务场景提交 | |
city_name | string | 否 | 调用方所在城市,指明客户端粗略位置 |
一级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|
user_defined_params | json object | 否 | 设置需要透传给agent 和 mcp 服务的参数,各类agent传递的参数参考调用官方Agent文档说明, mcp 传递参数依照 mcp 服务本身所需的参数。可以在extra_config子节点中设置对话扩展参数,目前支持:1. enable_web_search,表示是否开启联网搜索。这里的设置优先级更高,会覆盖管控台配置;2. agent_timeout,表示agent连接超时的时间,传值范围是10秒到120秒。如果不传,则默认为10秒。 |
user_prompt_params | json object | 否 | 用于设置用户自定义prompt变量,由用户自定义设置json中的key和value。管控台上配置自定义prompt变量的方法参考应用配置-提示词 |
user_query_params | json object | 否 | 用于设置用户自定义对话变量,由用户自定义设置json中的key和value。管控台上配置自定义对话变量的方法参考应用配置-对话变量 |
客户端使用的三种模式对比:
对比项 | push2talk | tap2talk | duplex |
|---|---|---|---|
类型 | 客户端控制模式 | 点击模式 | 双工模式 |
音频上传方式 | 按需 | 持续 Listening状态超过20秒不上传音频即报错 | 持续 任何状态超过20秒不上传音频都报错 |
VAD检测方 | 客户端 | 服务端 | 服务端 |
打断方式 | RequestToSpeak消息打断 | RequestToSpeak消息打断 | 语音打断 |
使用场景 | 由用户控制开始/结束客户端语音发送和识别,适用于按键说话,松开停止说话的场景。 | 客户端需持续上传音频,服务端自动检测语音活动的场景。但不支持用户语音打断大模型输出,只能发送RequestToSpeak打断消息。 | 客户端需持续上传音频,服务端自动检测语音活动的场景。用户随时可以说话打断大模型输出。 |
Started - Output Message
一级参数 | 二级参数 | 类型 | 说明 |
|---|---|---|---|
output | event | string | 事件名称:Started |
dialog_id | string | 对话ID |
结束会话
Stop - Input Message
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:Stop |
dialog_id | string | 否 | 对话ID |
Stopped - Output Message
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:Stopped |
dialog_id | string | 是 | 对话ID |
服务端下发状态切换事件
DialogStateChanged - Output Message
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:DialogStateChanged |
state | string | 是 | AI交互状态,取值范围:Listening,Thinking, Responding 注意:其中状态Listening 只是表示SDK可以发语音给服务端,不代表客户端是否开麦 | |
dialog_id | string | 是 | 对话ID |
请求上传语音
RequestToSpeak - Input Message
当前状态不是Listening,而用户又想说话时,先提交此事件打断大模型的回答,等待服务端应答。
具体触发此事件的用户行为根据交互类型有所不同,比如用户按下按钮、语音打断(依赖双工模块)等。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:RequestToSpeak |
dialog_id | string | 否 | 对话ID |
RequestAccepted - Output Message 请求被准许
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:RequestAccepted |
dialog_id | string | 是 | 对话ID |
上传语音指令
SendSpeech - Input Message
当Start消息指定模式为push2talk,需要客户端告知服务端用户何时开始说话。在Listening状态下,当用户按下按键时应上报SendSpeech消息,通知服务端即将开始上传语音,语音数据应紧接着此事件之后发送。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:SendSpeech |
dialog_id | string | 否 | 对话ID |
StopSpeech - Input Message
当Start消息指定模式为push2talk的时候,用户说完话松开按键时,客户端必须使用StopSpeech消息通知服务端结束语音指令输入。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:StopSpeech |
dialog_id | string | 否 | 对话ID |
CancelSpeech - Input Message
当Start消息指定模式为push2talk或tap2talk的时候,在语音输入过程中,用户可以使用CancelSpeech消息结束语音输入。服务会结束识别,回到空闲状态。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:CancelSpeech |
dialog_id | string | 否 | 对话ID |
语音识别开始/结束
SpeechStarted - Output Message
当服务端检测到asr语音起点时下发此事件。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:SpeechStarted |
dialog_id | string | 是 | 对话ID |
SpeechEnded - Output Message
当服务端检测到asr语音尾点时下发此事件,如果客户端还在上传音频,则收到此事件后应停止上传音频。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:SpeechEnded |
dialog_id | string | 是 | 对话ID |
指定应答内容
RequestToRespond - Input Message
在Listening状态时,通知服务端与用户主动交互,服务端会根据type字段把在text字段中上传的文本直接转换为语音下发,或调用大模型,返回的结果再转换为语音下发。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:RequestToRespond |
dialog_id | string | 是 | 对话ID | |
type | string | 是 | 服务应该采取的交互类型,目前支持两种:
| |
text | string | 是 | 要处理的文本,非null。
| |
parameters | history | list[] | 否 | 客户自己组织的问答历史,会覆盖服务内默认维护的问答历史,影响后续所有问答。 |
images | list[] | 否 | 需要分析的图片信息 | |
biz_params | object | 否 | 参数说明参考下方 parameters.biz_params的参数说明表格 |
一级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|
role | string | 是 | 本记录是哪个角色说的,只支持user, assistant两种。 注意:不支持设为system |
content | string | 是 | 具体文本内容 |
一级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|
type | string | 是 | 图片类型,支持两种:base64/url |
value | string | 是 | 图片内容。
|
一级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|
videos | list[] | 否 | 用来控制进入和退出视频通话。 示例如下: payload.biz_params.videos.action为connect,表示进入视频模式。 payload.biz_params.videos.action为exit,表示退出视频模式。 |
其他参数 | 否 | 与Start消息中 |
parameters.biz_params与Start消息中的parameters.biz_params相同,传递对话系统自定义参数。RequestToRespond的biz_params参数只在本次请求中生效。AI语音应答状态
RespondingStarted - Output Message
AI语音应答开始,sdk要准备接收服务端下发的语音数据
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:RespondingStarted |
dialog_id | string | 是 | 对话ID |
RespondingEnded - Output Message
AI语音应答结束
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:RespondingEnded |
dialog_id | string | 是 | 对话ID |
客户端播放事件
LocalRespondingStarted - Input Message
客户端开始播放服务端下发的音频
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:LocalRespondingStarted |
dialog_id | string | 否 | 对话ID |
LocalRespondingEnded - Input Message
客户端播放服务端下发的音频完成,服务端根据此消息判断端侧语音播放结束,结束当前问答,重新切换到Listening状态。
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:LocalRespondingEnded |
dialog_id | string | 否 | 对话ID |
文本下发事件
SpeechContent - Output Message
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:SpeechContent |
dialog_id | string | 是 | 对话ID | |
text | string | 是 | 用户语音识别出的文本,流式返回,每次返回从识别开始到当前的完整识别结果。例如,您会先收到 | |
finished | bool | 是 | 输出是否结束 |
RespondingContent - Output Message
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:RespondingContent |
dialog_id | string | 是 | 对话ID | |
round_id | string | 是 | 本轮交互的ID | |
llm_request_id | string | 是 | 调用llm的request_id | |
text | string | 是 | 系统对外输出的文本,流式全量输出 | |
spoken | string | 是 | 合成语音时使用的文本,流式全量输出 | |
finished | bool | 是 | 输出是否结束 | |
extra_info | object | 否 | 其他扩展信息,目前支持:
如果没有扩展信息要提交则省略此字段。 |
客户端更新事件
UpdateInfo - Input Message
一级参数 | 二级参数 | 三级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|---|
input | directive | string | 是 | 指令名称:UpdateInfo | |
dialog_id | string | 否 | 对话ID | ||
parameters | images | list[] | 否 | 图片数据 | |
client_info | status | object | 否 | 客户端当前状态 | |
biz_params | object | 否 | 与Start消息中biz_params相同,传递对话系统自定义参数。UpdateInfo指令中biz_params下面每个子项会全量替换Start指令中biz_params下面的同名项,并在本次连接后续所有对话中生效。 | ||
upstream | language | String | 否 | 语音识别语种更新,不配置则语种不变。设置多个语种时,使用英文逗号分隔,例如: | |
downstream | language | String | 否 | 语音合成语种更新,不配置则语种不变。 |
心跳事件
可以通过定期向服务端发送此消息,避免连接超时断开。考虑到预留网络延迟和处理时间的buffer,建议发送频率50秒一次。服务端会回应相同消息,客户端收到不需要做任何处理,忽略即可。
HeartBeat - Input Message
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
input | directive | string | 是 | 指令名称:HeartBeat |
dialog_id | string | 否 | 对话id |
HeartBeat - Output Message
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | event | string | 是 | 事件名称:HeartBeat |
dialog_id | string | 是 | 对话id |
错误事件
Error - Output Message
一级参数 | 二级参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|---|
output | error_code | int | 是 | 错误码 |
error_name | string | 是 | 错误名称 | |
error_message | string | 是 | 错误消息 |