Files
AI_Printer/docs/websocket.md
admin 8df2095acf chore(repo): keep only current main snapshot
History squashed to one root commit to permanently drop old branch history and objects.
2026-02-28 16:41:12 +08:00

49 KiB
Raw Blame History

本文介绍基于 WebSocket 协议的实时多模态交互 API。WebSocket协议延迟低、资源占用少是首选接入方案。

WebSocket是一种支持全双工通信的网络协议。客户端和服务器通过一次握手建立持久连接双方可以互相主动推送数据因此在实时性和效率方面具有显著优势。

对于常用编程语言有许多现成的WebSocket库和示例可供参考例如

  • Gogorilla/websocket

  • PHPRatchet

  • Node.jsws

建议您先了解WebSocket的基本原理和技术细节再参照本文进行开发。

说明

对于RTOS或某些旧版Linux系统建立安全Websocket 通信所依赖的 TLS 隧道,需要做如下配置:

  • TLS 版本要求 TLS1.2 或以上

  • 开启 SNISERVER NAME INDICATION

  • 配置 CA 证书(GlobalSign Root CA - R3也可至GlobalSign官网下载

前提条件

已开通服务并获取API Key。请配置API Key到环境变量,而非硬编码在代码中,防范因代码泄露导致的安全风险。

说明

对于客户端调用的场景在客户端处理API Key有安全风险建议从服务端用API Key获取临时鉴权Token再把Token下发给客户端使用。具体方法请参考生成临时 API Key

调用时序图

[关键流程] 服务端返回Started消息表示会话创建成功,但客户端禁止立即发送音频。客户端必须等待并接收到DialogStateChanged事件且stateListening后,方可开始发送音频流。

image

服务地址

wss://dashscope.aliyuncs.com/api-ws/v1/inference

鉴权

需要在发起初始的WebSocket握手HTTP Upgrade请求时把API Key放在HTTP Header里需要将your_api_key替换为真实的API Key

"Authorization": "Bearer your_api_key"

语音交互

多模态交互应用开启了语音交互后,支持语音识别和语音合成。

语音识别支持的模型包括:Gummy实时语音识别GummyParaformer实时语音识别ParaformerFUN-ASR实时语音识别FunASR千问3-ASR-Flash-Realtimeqwen3-asr-flash-realtime多模态交互轻量版语音识别AppSpecificASR-Realtime

语音合成支持的模型包括:语音合成CosyVoice-v2大模型cosyvoice-v2语音合成CosyVoice-v3-plus大模型cosyvoice-v3-plus语音合成CosyVoice-v3-Flash大模型cosyvoice-v3-flashSambert语音合成sambert千问3-TTSqwen3-tts多模态交互轻量版语音合成AppSpecificTTS

语音合成支持的音色,可以在控制台上选择了模型后,点击右侧语音交互体验区域的右上角查看音色列表。

官方音色也可以参考官方文档cosyvoice-v2 / cosyvoice-v3-plus / cosyvoice-v3-flash 支持的官方音色参考音色列表qwen3-tts 支持的官方音色参考支持的音色sambert支持的音色参考模型列表(去掉开头的"sambert-"和末尾的"-v1"后就是voice的取值

使用复刻音色时确认复刻音色状态为“OK”后才能使用。查询方法参考查询指定音色

消息类型

二进制消息Binary Message

当前二进制消息仅包含音频数据。

上传音频

上传音频时,将原始音频直接转为二进制流即可,无需额外处理。

上传的语音识别音频需满足16bit采样位深、单声道、有符号、little-endian PCM编码采样率参考Start消息的参数parameters.upstream.sample_rate的取值说明。

如果希望减少网络流量和带宽占用用户可以把PCM音频编码为Opus格式同时设置上传音频格式为raw-opus。

上传音频时,根据Start消息中upstream.mode设置不同,采取的措施也不同:

  • mode为 tap2talkduplex客户端需持续上传音频服务端自动检测语音活动。建议每100ms上传一次数据间隔太长或太短会对延时和处理效率造成负面影响。

    • 音频上传速率计算公式:数据每次上传的字节数 = 采样率 * 采样位深/8 * 时间间隔ms/ 1000

    • 以16kHz采样率、16bit位深、100ms间隔为例每次应上传 16000 * (16/8) * 100 / 1000 = 3200 字节的PCM数据。

  • mode为 push2talk:客户端无需持续上传音频,但需通过SendSpeechStopSpeech通知服务端音频识别的开始和结束。发送SendSpeech后需立即上传音频,否则会增加处理时间。

下发音频

服务端将大模型回复发送至TTS生成语音然后下发给客户端

  • 下发音频为16bit单声道采样率和编码由Start消息参数定义。

  • 下发速度取决于TTS服务性能通常快于播放速度。

  • 音频下发前发送RespondingStarted事件;结束后发送RespondingEnded事件。

  • 客户端需在播放完成后上报LocalRespondingEnded,通知服务端播放结束。

文本消息Text Message

文本消息是JSON格式字符串按传递方向分为两类

  • 输入消息Input Message客户端发送给服务端的指令directive表示客户端希望服务端执行特定动作。

  • 输出消息Output Message服务端发送给客户端的事件event表示服务端动作执行结果或进展。

文本消息标记交互流程的关键节点,控制流程并传输关键信息。通过时序图可了解不同消息的交互时序。

文本消息包含两部分:headerpayload

  • 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
input workspace_id string 客户在阿里云百炼业务空间IDWorkspace ID),可在多模态交互开发套件控制台,点击左下角业务空间名称,“业务空间详情”中查看,目前仅支持主账号默认工作空间。
input app_id string 客户创建的应用IDAPP ID),可在多模态交互开发套件控制台的“我的应用”页面查看
input dialog_id string 对话ID默认不填时是开启新会话服务端会自动生成并在事件中下发格式示例"12345678-1234-1234-1234-1234567890ab"共36个字符。当希望继续之前的对话时把当时服务端下发的dialog_id在这里传入
parameters upstream object 参数说明参考下方 parameters.upstream的参数说明表格
parameters downstream object 参数说明参考下方 parameters.downstream的参数说明表格
parameters client_info object 参数说明参考下方 parameters.client_info的参数说明表格
parameters biz_params object 参数说明参考下方 parameters.biz_params的参数说明表格

parameters.upstream的参数说明如下****

一级参数 类型 是否必选 说明
type string 上行类型: AudioOnly 仅语音通话
mode string 客户端使用的模式,默认tap2talk。 可选项: - push2talk: 客户端控制模式。 - tap2talk: 点击模式。 - duplex: 双工模式。 三种模式的对比可以参考下方的客户端使用的三种模式对比表格。
audio_format string 音频格式支持pcmraw-opus默认为pcm
sample_rate int 语音识别的采样率,支持范围: - 8000 - 16000 - 24000 - 48000 默认为16000
vocabulary_id string 热词id设置该参数时会覆盖管控台热词配置。当管控台提供的热词不能满足客户需求时可以考虑用Open API程序化管理热词参见热词API文档

parameters.downstream的参数说明如下:

一级参数 类型 是否必选 说明
voice string 合成语音的音色,支持范围取决于用户在管控台选择的语音合成模型
sample_rate int 合成语音的采样率,支持范围: - 8000 - 16000 - 24000 - 48000 默认为24000。 千问-TTS、千问3-TTS模型仅支持24000。
audio_format string 音频格式支持pcmopusmp3raw-opus默认为pcm。 千问-TTS模型仅支持pcm。 注意opus 和 raw-opus的区别是opus格式的每一包数据都有额外ogg封装RFC 7845
frame_size int 合成音频的帧大小,取值范围: - 10 - 20 - 40 - 60 - 100 - 120 默认值为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只在合成音频格式为opus或raw-opus时生效
intermediate_text string 控制返回给用户哪些中间文本: - transcript返回用户语音识别结果 - dialog返回对话系统回答中间结果 可以设置多种以逗号分隔默认为transcript
transmit_rate_limit int 下发音频发送速率限制,单位:字节每秒
incremental_response boolean 是否增量返回大模型结果true为增量false为全量。默认为false全量下发

parameters.client_info的参数说明如下:

一级参数 二级参数 类型 是否必选 说明
user_id string 终端用户ID客户根据自己业务规则生成用来针对不同终端用户实现定制化功能。最大长度36个字符。
device.uuid uuid string 客户端全局唯一的ID需要用户自己生成并传入SDK最大长度40个字符。一个终端用户可以有多个设备那么每一个设备的uuid都不同但user_id相同。
network ip string 调用方公网IP
location latitude string 调用方纬度信息,在需要客户端精确位置的业务场景提交
location longitude string 调用方经度信息,在需要客户端精确位置的业务场景提交
location city_name string 调用方所在城市,指明客户端粗略位置

parameters.biz_params的参数说明如下:

一级参数 类型 是否必选 说明
user_defined_params json object 需要透传给agent的参数各类agent传递的参数参考调用官方Agent文档说明
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打断消息。 客户端需持续上传音频,服务端自动检测语音活动的场景。用户随时可以说话打断大模型输出。

示例如下:

{
    "header": {
        "action":"run-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "task_group":"aigc",
        "task":"multimodal-generation", // 任务类型:多模态生成
        "function":"generation",
        "model":"multimodal-dialog", // 模型名称多模态对话注意与task不同
        "input":{
          "directive": "Start",
          "workspace_id": "llm-***********",
          "app_id": "****************"
        },
        "parameters":{
          "upstream":{
            "type": "AudioOnly",
            "mode": "duplex"
          },
          "downstream":{
            "voice": "longxiaochun_v2",
            "sample_rate": 24000
          },
          "client_info":{
            "user_id": "bin********207",
            "device":{
              "uuid": "432k*********k449"
            },
            "network":{
              "ip": "203.0.113.10"
            },
            "location":{
              "city_name": "北京市"
            }
          },
          "biz_params":{
            "user_defined_params": {
                "agent_id_xxxxx": {
                    "name": "value"
                }
            },
            "user_prompt_params": {
                "name": "value"
            },
            "user_query_params": {
                "name": "value"
            }
          }
        }
    }
}

Started - Output Message

说明

SDK接收到Started之后,先不可以向服务发送音频,应等待DialogStateChanged消息确认切换到Listening状态之后才发送音频。

一级参数 二级参数 类型 说明
output event string 事件名称Started
dialog_id string 对话ID

示例如下:

Started返回消息样例

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "Started",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

结束会话

Stop - Input Message

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称Stop
dialog_id string 对话ID

示例如下:

Stop请求样例

{
    "header": {
        "action":"finish-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "Stop",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

Stopped - Output Message

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称Stopped
dialog_id string 对话ID

示例如下:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "Stopped",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

服务端下发状态切换事件

DialogStateChanged - Output Message

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称DialogStateChanged
state string AI交互状态取值范围ListeningThinking Responding 注意其中状态Listening 只是表示SDK可以发语音给服务端不代表客户端是否开麦
dialog_id string 对话ID

示例如下:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "DialogStateChanged",
          "state": "Listening",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

请求上传语音

RequestToSpeak - Input Message

当前状态不是Listening而用户又想说话时先提交此事件打断大模型的回答等待服务端应答。

具体触发此事件的用户行为根据交互类型有所不同,比如用户按下按钮、语音打断(依赖双工模块)等。

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称RequestToSpeak
dialog_id string 对话ID

示例如下:

{
    "header": {
        "action":"continue-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "RequestToSpeak",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

RequestAccepted - Output Message 请求被准许

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称RequestAccepted
dialog_id string 对话ID

示例如下:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "RequestAccepted",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

上传语音指令

SendSpeech - Input Message

当Start消息指定模式为push2talk需要客户端告知服务端用户何时开始说话。在Listening状态下当用户按下按键时应上报SendSpeech消息通知服务端即将开始上传语音语音数据应紧接着此事件之后发送。

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称SendSpeech
dialog_id string 对话ID

示例如下:

{
    "header": {
        "action":"continue-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "SendSpeech",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

StopSpeech - Input Message

当Start消息指定模式为push2talk的时候用户说完话松开按键时客户端必须使用StopSpeech消息通知服务端结束语音指令输入。

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称StopSpeech
dialog_id string 对话ID

示例如下:

{
    "header": {
        "action":"continue-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "StopSpeech",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

CancelSpeech - Input Message

当Start消息指定模式为push2talk或tap2talk的时候在语音输入过程中用户可以使用CancelSpeech消息结束语音输入。服务会结束识别回到空闲状态。

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称CancelSpeech
dialog_id string 对话ID

示例如下:

{
    "header": {
        "action":"continue-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "CancelSpeech",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

语音识别开始/结束

SpeechStarted - Output Message

当服务端检测到asr语音起点时下发此事件。

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称SpeechStarted
dialog_id string 对话ID

示例如下:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "SpeechStarted",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

SpeechEnded - Output Message

当服务端检测到asr语音尾点时下发此事件如果客户端还在上传音频则收到此事件后应停止上传音频。

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称SpeechEnded
dialog_id string 对话ID

示例如下:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "SpeechEnded",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

指定应答内容

RequestToRespond - Input Message

在Listening状态时通知服务端与用户主动交互服务端会根据type字段把在text字段中上传的文本直接转换为语音下发或调用大模型返回的结果再转换为语音下发。

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称RequestToRespond
input dialog_id string 对话ID
input type string 服务应该采取的交互类型,目前支持两种: - transcript表示直接把文本转语音 - prompt表示把文本发送给大模型让其进行回答
input text string 要处理的文本非null。 - 调用部分agent时text可以是""空字符串服务端只需要使用parameters中的images或者biz_params参数即可处理。具体参考调用官方Agent
parameters images list[] 需要分析的图片信息
parameters biz_params object 参数说明参考下方 parameters.biz_params的参数说明表格

parameters.biz_params的参数说明如下:

一级参数 类型 是否必选 说明
videos list[] 用来控制进入和退出视频通话。 示例如下: payload.biz_params.videos.action为connect表示进入视频模式。 payload.biz_params.videos.action为exit表示退出视频模式。
其他参数 Start消息中parameters.biz_params相同传递对话系统自定义参数。RequestToRespond的biz_params参数只在本次请求中生效。

说明

除了videos参数外parameters.biz_paramsStart消息中的parameters.biz_params相同传递对话系统自定义参数。RequestToRespond的biz_params参数只在本次请求中生效。

{
    "header": {
        "action":"continue-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "RequestToRespond",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb",
          "type": "prompt",
          "text": "你好,你有什么想聊的呢"
        },
        "parameters":{
          "images":[{
              "type": "base64",
              "value": "aGVsbG8gd29ybGQ="
          }],
          "biz_params":{
            "user_defined_params":{},
            "videos": [
                  {
                    "action": "connect/exit", 
                    "type": "voicechat_video_channel"
                  }
                ]
          }
        }
    }
}

AI语音应答状态

RespondingStarted - Output Message

AI语音应答开始sdk要准备接收服务端下发的语音数据

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称RespondingStarted
dialog_id string 对话ID

示例如下:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "RespondingStarted",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

RespondingEnded - Output Message

AI语音应答结束

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称RespondingEnded
dialog_id string 对话ID

示例如下:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "RespondingEnded",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

客户端播放事件

LocalRespondingStarted - Input Message

客户端开始播放服务端下发的音频

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称LocalRespondingStarted
dialog_id string 对话ID

示例如下:

{
    "header": {
        "action":"continue-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "LocalRespondingStarted",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

LocalRespondingEnded - Input Message

客户端播放服务端下发的音频完成服务端根据此消息判断端侧语音播放结束结束当前问答重新切换到Listening状态。

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称LocalRespondingEnded
dialog_id string 对话ID

示例如下:

{
    "header": {
        "action":"continue-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "LocalRespondingEnded",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

文本下发事件

SpeechContent - Output Message

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称SpeechContent
dialog_id string 对话ID
text string 用户语音识别出的文本,流式返回,每次返回从识别开始到当前的完整识别结果。例如,您会先收到"text": "你好",接着收到"text": "你好世界"
finished bool 输出是否结束

示例如下:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "SpeechContent",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb",
          "text": "一二三",
          "finished": false
        }
    }
}

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 其他扩展信息,目前支持: - commands: 命令字符串,**此字段为JSON字符串需要进行二次解析。**各类agent使用的命令字符串可以参考调用官方Agent的说明。 - agent_info: 智能体信息 - tool_calls: 插件返回的信息 如果没有扩展信息要提交则省略此字段。

示例如下:

{
    "header": {
        "event": "result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output": {
            "event": "RespondingContent",
            "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb",
            "text": "您输入了数字序列“12345”。如果您有关于这些数字的问题或者需要我用它们来完成某项任务请告诉我更多的细节我会尽力帮助您。",
            "spoken": "您输入了数字序列“12345”。如果您有关于这些数字的问题或者需要我用它们来完成某项任务请告诉我更多的细节我会尽力帮助您。",
            "finished": true,
            "extra_info": {
                "commands": "[{\"name\":\"VOLUME_SET\",\"params\":[{\"name\":\"series\",\"normValue\":\"70\",\"value\":\"70\"}]}]",
                "tool_calls": [
                    {
                        "id": "",
                        "type": "function",
                        "function": {
                            "name": "function_name",
                            "arguments": "{\"id\": \"123\", \"name\": \"test\"}",
                            "outputs": "{\"result\": \"success\"}",
                            "status": {
                                "code": 200,
                                "message": "Success."
                            }
                        }
                    }
                ]
            }
        }
    }
}

客户端更新事件

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下面的同名项并在本次连接后续所有对话中生效。

示例如下:

{
    "header": {
        "action":"continue-task",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
        "streaming":"duplex"
    },
    "payload": {
        "input":{
          "directive": "UpdateInfo",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        },
        "parameters":{
          "images":[{
              "type": "base64",
              "value": "base64String"
          }],
          "client_info": {
              "status": {
                  "bluetooth_announcement": {
                      "status": "stopped"
                  },
                  "stream_media_playback": {
                      "status": "stopped"
                  },
                  "phone_ringing": {
                      "status": "stopped"
                  },
                  "stream_media_playback_qq": {
                      "status": "stopped"
                  }
              }
          },
          "biz_params":{
          }
        }
    }
}

心跳事件

可以通过定期向服务端发送此消息避免连接超时断开。考虑到预留网络延迟和处理时间的buffer建议发送频率50秒一次。服务端会回应相同消息客户端收到不需要做任何处理忽略即可。

HeartBeat - Input Message

一级参数 二级参数 类型 是否必选 说明
input directive string 指令名称:HeartBeat
dialog_id string 对话id

示例:

{
  "header": {
    "action": "continue-task",
    "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43",
    "streaming": "duplex"
  },
  "payload": {
    "input": {
      "directive": "HeartBeat",
      "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
    }
  }
}

HeartBeat - Output Message

一级参数 二级参数 类型 是否必选 说明
output event string 事件名称:HeartBeat
dialog_id string 对话id

示例:

{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "HeartBeat",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb"
        }
    }
}

错误事件

Error - Output Message

一级参数 二级参数 类型 是否必选 说明
output error_code int 错误码
output error_name string 错误名称
output error_message string 错误消息
{
    "header": {
        "event":"result-generated",
        "task_id": "f894c16f-f20e-4c1d-837e-89e0fbc63a43"
    },
    "payload": {
        "output":{
          "event": "Error",
          "dialog_id": "dd84xxxx-xxxx-xxxx-xxxx-xxxxb7bb",
          "error_code": 500,
          "error_name": "InternalLLMError", 
          "error_message": "Internal LLM error"
        }
    }
}

错误码

如遇报错问题,请参见多模态交互套件-错误码进行排查。

若问题仍未解决请联系技术支持反馈遇到的问题并提供完整的request_id和dialog_id以便进一步排查问题。

术语说明

VADVoice Activity Detection语音活动检测。

ASRAutomatic Speech Recognition自动语音识别。

TTSText-to-Speech文本转语音语音合成。

LLMLarge Language Model大语言模型。

本文介绍使用阿里云百炼多模态交互套件可能出现的错误信息及解决方案。

AccessDenied.Unpurchased

{"header":{"task_id":"xxxxx","event":"task-failed","error_code":"AccessDenied.Unpurchased","error_message":"Access to model denied. Please make sure you are eligible for using the model.","attributes":{}},"payload":{}}

Access to model denied. Please make sure you are eligible for using the model.

**原因:**错误码error_code出现在header里用户未开通阿里云百炼服务无法建连。

**解决方案:**注册或登录阿里云账号,然后前往模型广场开通百炼服务。

Model.AccessDenied

{"header":{"task_id":"xxxxx","event":"task-failed","error_code":"Model.AccessDenied","error_message":"Model access denied.","attributes":{}},"payload":{}}

Model access denied.

原因: 错误码error_code出现在header里使用的业务空间不是默认业务空间无法建连。目前多模态交互只支持从默认业务空间调用。

**解决方案:**使用默认业务空间的API Key调用多模态交互。

RequestTimeOut

{"header":{"task_id":"xxxxx","event":"task-failed","error_code":"ResponseTimeout","error_message":"Response timeout!","attributes":{}},"payload":{}}

Response timeout!

原因: 错误码error_code出现在header里百炼网关报错无法建连。百炼网关要求服务端和客户端必须持续通信如果超过1分钟没有交互则会超时报错。

解决方案: 持续交互避免长时间无消息传递。若客户端需在无交互时保持连接应定期发送心跳消息HeartBeat。服务端会回应心跳确保连接活跃避免超时关闭。具体的心跳消息格式参见心跳事件

**421-**InvalidParameter

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":421,"status_name":"InvalidParameter","status_message":"xxxxx"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx"}}}

type of directive payload is error, please choose transcript or prompt

**原因:**错误码status_code出现在header里收到该错误后连接会断开是RequestToRespond的参数type取值错误。

**解决方案:**修正RequestToRespond的参数type重新发请求。type只能支持以下两种

1transcript 表示直接把文本转语音。

2prompt 表示把文本送大模型回答。

status_message是其他报错信息

**原因:**status_code出现在header里收到该错误后连接会断开是其他的参数取值错误 status_message 信息都有具体的提示说明。

**解决方案:**根据 status_message 信息提示修正参数取值。

**422-**DirectiveNotSupported

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":422,"status_name":"DirectiveNotSupported","status_message":"Directive not supported: xxx"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx"}}}

Directive not supported: xxx

**原因:**错误码status_code出现在header里收到该错误后连接会断开。传入的指令 directive 的取值是不支持的指令。

**解决方案:**请检查指令名称,使用多模态交互可用的指令。参考文本消息类型的说明。

**432-**AppConfigError

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":432,"status_name":"AppConfigError","status_message":"xxxxxxx"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx"}}}

**原因:**错误码status_code出现在header里收到该错误后连接会断开。获取到百炼应用的配置时出现问题。

**解决方案:**参考status_message 里的具体信息,修改传入的参数配置。

**433-**BillingAuthError

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":433,"status_name":"BillingAuthError","status_message":"xxxxxxx"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx"}}}

Billing auth info not found!

**原因:**错误码status_code出现在header里收到该错误后连接会断开。当前使用的账号未开通百炼多模态交互服务。

**解决方案:**为当前账号开通百炼多模态交互服务,或使用已开通的账号。

**444-**ClientAudioTimeout

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":444,"status_name":"ClientAudioTimeout","status_message":"Waiting for client audio timed out."},"payload":{"output":{"event":"Error","dialog_id":"xxxxx"}}}

Waiting for client audio timed out.

**原因:**错误码status_code出现在header里收到该错误后连接会断开。服务端长时间收不到客户端的音频输入。

**解决方案:**在duplex模式应持续向服务端上传音频在tap2talk模式应保证在状态切换到Listening之后立刻持续上传音频也可以在所有状态下都上传音频在push2talk模式发送SendSpeech消息后应立刻上传音频直到发送StopSpeech消息。

**449-**TooManyInterrupt

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":449,"status_name":"TooManyInterrupt","status_message":"Send too many RequestToRespond or RequestToSpeak directives in a short time!"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx"}}}

Send too many RequestToRespond or RequestToSpeak directives in a short time!

**原因:**错误码status_code出现在header里收到该错误后连接会断开。用户短时间内发送过多RequestToRespond或RequestToSpeek 打断正常交互通常是调用程序bug导致。

**解决方案:**排查程序调用逻辑避免多次发送RequestToRespond或RequestToSpeek 。

**424-**AudioFormatError

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":424,"status_name":"AudioFormatError","status_message":"xxxxx"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx"}}}

Failed to decode audio! Please check audio format! / ASR decode error, please check audio format!

**原因:**错误码status_code出现在header里收到该错误后连接会断开。输入音频的格式不合规ASR无法正常解析音频。

**解决方案:**检查输入的音频格式,输入正确的音频数据。

**425-**NoInputAudioError

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":200,"status_name":"Success","status_message":"Success"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx","round_id":"xxxxx","llm_request_id":"xxxxx","error_code":425,"error_name":"NoInputAudioError","error_message":"ASR input audio error, no input audio , please check audio data!"}}}

ASR input audio error, no input audio , please check audio data!

**原因:**错误码error_code出现在payload里收到该错误后连接不会断开。没有获取到有效的输入音频数据ASR无法识别。

**解决方案:**检查是否有音频数据发送,重新输入正确的音频数据。

**426-**InvalidTtsVoice

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":200,"status_name":"Success","status_message":"Success"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx","round_id":"xxxxx","llm_request_id":"xxxxx","error_code":426,"error_name":"InvalidTtsVoice","error_message":"tts voice error , need xxx voice."}}}

tts voice error , need xxx voice.

**原因:**错误码error_code出现在payload里收到该错误后连接不会断开。音色参数 voice 取值错误,选择的音色不是当前的语音合成模型支持的音色。

**解决方案:**将voice修正为正确的音色。

1官方音色

  • 参考官方文档cosyvoice-v2 / cosyvoice-v3 / cosyvoice-v3-plus / cosyvoice-v3-flash 支持的官方音色参考音色列表qwen-tts-realtime / qwen3-tts 支持的官方音色参考支持的音色sambert支持的音色参考模型列表(去掉开头的"sambert-"和末尾的"-v1"后就是voice的取值

  • 其他语音合成模型的音色都可以在多模态交互控制台上查看:在左侧语音交互配置区域选择对应的语音合成模型,点击右侧语音交互体验区域的右上角即可查看可用的音色列表。

2复刻音色确认音色状态为“OK”后才能使用。查询方法参考查询指定音色

**451-**NoSpeechRecognized

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":200,"status_name":"Success","status_message":"Success"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx","round_id":"xxxxx","llm_request_id":"xxxxx","error_code":451,"error_name":"NoSpeechRecognized","error_message":"No speech recognized from audio!"}}}

No speech recognized from audio!

**原因:**错误码error_code出现在payload里收到该错误后连接不会断开。服务没有识别到用户讲话通常是push2talk模式下用户发送了SendSpeech后没有说话就又发送了StopSpeech指令。其他模式下也有极少数情况是由背景噪音引起。

**解决方案:**检查消息发送的逻辑,确认是否有用户说话的音频数据发送到服务端。

500-InternalSynthesizerError/InternalAsrError /InternalLLMError/LLMTimeoutError

{"header":{"event":"result-generated","task_id":"xxxxx","status_code":200,"status_name":"Success","status_message":"Success"},"payload":{"output":{"event":"Error","dialog_id":"xxxxx","round_id":"xxxxx","llm_request_id":"xxxxx","error_code":500,"error_name":"InternalAsrError","error_message":"Internal asr error"}}}

Internal synthesizer error/Internal asr error/Internal LLM error/LLM response timeout

**原因:**错误码error_code出现在payload里收到此类错误后连接不会断开。服务内部错误tts/asr/llm出错。

**解决方案:**出现此类错误时可以重新发起请求来恢复使用。如果需要确认具体原因请记录出错时完整的request_id和dialog_id联系技术支持。