Skip to content

B. WebSocket 协议参考 ​

JoyInside WebSocket 语音通道的完整速查:建连、对话模式、轮次时序、消息结构、音频参数、错误码、全场景事件对照。

B.0 连接参数说明 ​

建连 URL ​

wss://ws.joyinside.com/soulmate/voiceChat/v1
  ?botId={botId}
  &sessionId={botId + random}   # 推荐多轮对话场景复用同一sessionId
  &requestId={uuid}
  &uid=xxx                   
  [&needManualCall=true]        # 可选,按键对话模式
  [&feature=AUDIO_BOOK_V2]      # 可选,场景扩展,见第6章
  [&location=xxx]               # 可选,位置信息

URL 参数说明 ​

参数必选说明
botId是设备唯一标识,见 4.2 设备注册与绑定
sessionId是会话 ID。推荐:多轮对话场景复用同一 sessionId,保持上下文连续
requestId是一次 WS 建连的唯一标识,用于全链路追踪
uid是用户唯一标识,uid关联用户长期记忆。注意:请勿重复使用
needManualCall否按键对话模式(依赖客户端控制),必须传值:true,如不传则默认为false,为连续对话模式,该参数会决定不同对话模式下的串场词话术。
feature否场景扩展参数,如有声书 AUDIO_BOOK_V2,完整取值见 第6章 业务场景接入
location否位置信息

Header 参数说明 ​

参数必选类型说明
Authorization是string鉴权头,格式固定为 Bearer ${accessToken},其中 accessToken 为通过 getToken 接口获取的访问令牌。Token 获取方式见 4.1 Token 鉴权。

B.1 上下行消息一览表 ​

上行事件(设备端 → 云端) ​

事件名contentType触发时机协议明细
CLIENT_VOICE_CHAT_UPDATEEVENT建连后发一次,配置音频/音色/角色B.4.2
AUDIOAUDIO流式上传音频片段B.4.3
CLIENT_AUDIO_FINISHEVENT手动模式结束音频上传B.4.3
TEXTTEXT发文本与智能体对话B.4.4
CLIENT_INPUT_TEXT_TO_SPEECHEVENT主动提交文字合成语音(不触发智能体)B.4.6
CLIENT_INTERRUPTEVENT手动模式打断 TTS 播放B.4.7
VOICE_CHAT_TRIGGERACTIVITY主动触发智能体对话B.4.9
CLIENT_UPDATE_CHAT_CONTEXTACTIVITY注入短期记忆(需申请权限)B.4.9
CLIENT_UPDATE_COORDINATES_CONTEXTACTIVITY上报经纬度(需申请权限)B.4.9
PINGPING心跳保活,30s 间隔B.4.10
MCPMCP设备端MCP响应(initialize/tools-list/tools-call)B.4.12

下行事件(云端 → 设备端) ​

事件名contentType触发时机协议明细
CFG_BOT_EVENTEVENT建连成功后下发默认配置B.4.1
SERVER_VOICE_CHAT_UPDATEDEVENT配置更新成功响应B.4.2
ASRASR语音识别结果B.4.3
CALL_AGENT_START_EVENTEVENT智能体对话开始B.4.5
AGENTAGENT智能体回复文本(流式)B.4.5
ACTIVITYACTIVITY智能体主动开口(静默推送)B.4.5
EMPTY_CONTENTEVENT未识别到有效输入(拒识)B.4.5
COMPLETEEVENT当轮对话完成B.4.5
TTS_SENTENCE_STARTEVENT音频字幕(先于 TTS 下发)B.4.6
TTSTTS智能体回复音频(流式)B.4.6
TTS_COMPLETEEVENTTTS 音频全部下发完成B.4.6
CALL_AGENT_INTERRUPTEDEVENT打断事件(端侧需清空播放队列)B.4.7
CALL_SKILL_EVENTEVENT指令/IOT/情绪事件B.4.8
CLIENT_CHAT_CONTEXT_RECEIVEDEVENT上下文更新成功响应B.4.9
PONGPONG心跳响应B.4.10
USER_AUDIT_FAILEVENT审核命中B.4.11
REPEAT_CLIENT_SESSIONEVENT互踢(同 botId 双连接)B.4.11
MCPMCP设备端MCP请求(initialize/tools-list/tools-call)B.4.12

B.2 通用消息结构 ​

字段类型必选说明
midstring是消息唯一标识(UUID)
contentTypestring是EVENT / AUDIO / TEXT / PONG / ACTIVITY
contentobject是事件数据载体
codenumber下行200 成功
msgstring下行状态描述
requestIdstring下行请求唯一标识
roundIdstring下行轮次标识(排查主键,见 4.6 roundId)
tlong下行服务端处理时间戳(毫秒)

B.3 错误码速查 ​

错误码完整定义(getToken 1001-1006 / WS 建连 40100-40104 / HTTP 400/408 / 其他)见 9.6 错误码速查表,排查时以该表为权威源。

⚠ WS 建连 40100-40104 不返回设备端,设备只看连接被关闭。排查结合服务端日志与 roundId,详见 4.1 鉴权 与 9.1 建联失败。

B.4 事件协议明细(按功能维度聚合) ​

本节展开每个事件的完整 JSON 协议结构 + 字段说明,按功能维度聚合上下行事件。


B.4.1 建连后(CFG_BOT_EVENT) ​

建连成功后,服务端主动下发默认语音对话配置(音色、TTS 音频格式、设备型号)。无业务上行事件。

方向事件
下行CFG_BOT_EVENT

默认配置不一定满足业务需求,收到后需发 CLIENT_VOICE_CHAT_UPDATE 覆盖(见 B.4.2)。

下行:默认语音对话配置(CFG_BOT_EVENT) ​

建联成功后服务端下发默认配置。

外层结构:

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 EVENT
contentobject是识别结果数据
content.eventTypestring是固定 CFG_BOT_EVENT
content.eventDataobject是默认语音对话配置(见下表)
content.roundIdstring下行必选消息轮次 index

eventData 字段:

字段类型必选说明
timbreobject是输出音色配置
timbre.voiceNamestring是音色名称
timbre.voiceSpeedfloat是语速
ttsobject是输出音频配置
tts.auestring是音频编码(pcm/opus/mp3)
tts.bitint是位深
tts.channelsint是通道数
tts.srstring是采样率
deviceModelstring否设备型号
deviceIdstring否设备 ID
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7",
  "mid": null,
  "contentType": "EVENT",
  "content": {
    "roundId": "",
    "eventType": "CFG_BOT_EVENT",
    "eventData": {
      "timbre": {
        "voiceName": "小犀",
        "voiceSpeed": 1.0
      },
      "tts": {
        "aue": "pcm",
        "bit": 16,
        "channels": 1,
        "sr": "16000"
      },
      "deviceModel": "UNKNOWN",
      "deviceId": "UNKNOWN"
    }
  },
  "t": 1749117478297
}

B.4.2 配置更新(CLIENT_VOICE_CHAT_UPDATE / SERVER_VOICE_CHAT_UPDATED) ​

建连后只发一次,配置音频格式/采样率/二进制传输/音色。收到 SERVER_VOICE_CHAT_UPDATED 才算成功。

方向事件
上行CLIENT_VOICE_CHAT_UPDATE
下行SERVER_VOICE_CHAT_UPDATED

⚠ 重复发送会打断对话;对话中切换角色也需重发此事件。

上行:更新语音对话配置(CLIENT_VOICE_CHAT_UPDATE) ​

外层结构:

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 EVENT
contentobject是事件数据载体
content.eventTypestring是固定 CLIENT_VOICE_CHAT_UPDATE
content.eventDataobject是语音对话配置项(见下表)

语音对话配置项(eventData.audio / eventData.chat):

字段类型必选取值 / 默认说明
audioobject否—音频配置
audio.binarybool否true/falsetrue=二进制传输(上下行),false=base64 文本(上下行)
audio.vadbool否默认 false端侧 VAD 启用全局 roundId,true 开启 / false 关闭 参考:5.3.7 端侧 VAD 启用全局 roundId 使用说明
audio.inputobject否—输入音频配置
audio.input.codecstring否pcm/opus上行音频编码
audio.input.sampleRatestring否16000/24000/32000上行采样率
audio.input.frameSizestring否字节数输入 单个opus音频包的字节数,仅多个定长opus音频包拼包时传
audio.input.binarybool否true/false上行单独二进制开关,设此字段时 audio.binary 不设
audio.outputobject否—输出音频配置
audio.output.codecstring否pcm/opus/mp3下行 TTS 编码
audio.output.sampleRatestring否16000/24000/32000下行采样率
audio.output.binarybool否true/false下行单独二进制开关
audio.output.streambool否true/false开启流式音频下发, 仅针对 mp3 格式,默认false。参考:5.3.5 Mp3 下行流式音频
audio.output.enableOpusCbrbool否默认 false输出 opus 是否启用 CBR
audio.output.frameSizeMsstring否pcm:60-120 / opus:10/20/40/60下行 TTS 帧时长(ms),opus 默认 60,mp3 不支持按该字段切分
audio.timbreobject否—输出音色配置
audio.timbre.voiceSpeedfloat否0.8-1.2输出音频语速
audio.timbre.voiceVolumefloat否0.5-10输出音频音量

⚠ binary 覆盖关系:audio.binary 是上下行总开关。若上下行二进制策略不同,单独设 audio.input.binary / audio.output.binary,此时不设 audio.binary。

完整 JSON 示例(点击展开)
json
{
  "mid": "24279824-8def-48c6-8d1c-ea8ec3aa50ac",
  "contentType": "EVENT",
  "content": {
    "eventType": "CLIENT_VOICE_CHAT_UPDATE",
    "eventData": {
      "audio": {
        "binary": true,
        "vad": true,
        "input": {
          "codec": "pcm",
          "sampleRate": "16000"
        },
        "output": {
          "codec": "opus",
          "stream": false,
          "sampleRate": "16000",
          "frameSizeMs": "40",
          "enableOpusCbr": false
        },
        "timbre": {
          "voiceSpeed": 1.0,
          "voiceVolume": 5.0
        }
      }
    }
  }
}

下行:更新配置成功响应(SERVER_VOICE_CHAT_UPDATED) ​

外层结构:

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 EVENT
contentobject是识别结果数据
content.eventTypestring是固定 SERVER_VOICE_CHAT_UPDATED
content.eventDataobject是语音对话配置项(与上行结构相同)
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7",
  "mid": null,
  "contentType": "EVENT",
  "content": {
    "eventType": "SERVER_VOICE_CHAT_UPDATED",
    "eventData": {
      "audio": {
        "binary": true,
        "input": { "codec": "pcm", "sampleRate": "16000" },
        "output": { "codec": "opus", "sampleRate": "16000", "frameSizeMs": "40" }
      }
    }
  },
  "t": 1752724083510
}

B.4.3 语音输入与识别 ​

上行:流式上传音频(AUDIO) ​

流式向服务端提交音频片段。

外层结构:

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 AUDIO
contentobject是音频数据载体(见下表)

content 字段:

字段类型必选说明
audioBase64string是音频数据 Base64 编码(二进制传输时改用 ws.send(bytes))
indexstring是音频数据序号,由 1 递增;最后一帧可为取反值(~index)
midstring否音频轮次 ID(建议 UUID),开启端侧 VAD 时建议必传

切包规则:PCM 单包 ≤300ms,Opus 单包 ≤480 字节,间隔=音频时长。详见 4.5 音频格式与分片。

完整 JSON 示例(点击展开)
json
{
  "mid": "f70e8955-8b39-4ae8-bba1-2bea4aa6c50b",
  "contentType": "AUDIO",
  "content": {
    "audioBase64": "PwAVAOv/qP9i/yP/Df8O/wP/Cv8X/wr/8v7X/....",
    "index": 1,
    "mid": "aceb6a01-fa2e-4ada-a8f5-9e95c3cbb4d4"
  }
}

上行:结束音频上传(CLIENT_AUDIO_FINISH) ​

手动模式下通知服务端音频上传结束。

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 EVENT
contentobject是事件数据载体
content.eventTypestring是固定 CLIENT_AUDIO_FINISH
完整 JSON 示例(点击展开)
json
{
  "mid": "24279824-8def-48c6-8d1c-ea8ec3aa50ac",
  "contentType": "EVENT",
  "content": {
    "eventType": "CLIENT_AUDIO_FINISH"
  }
}

下行:音频识别内容(ASR) ​

流式语音识别结果。

外层结构:

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 ASR
contentobject是识别结果数据

content 字段:

字段类型必选取值说明
textstring是—识别出的文本内容
textTypestring是IS_FINAL结果类型,IS_FINAL 为最终识别结果
langstring否普通话/英文语种识别
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "ASR success",
  "requestId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "ASR",
  "content": {
    "text": "语音测试,给我个结果",
    "textType": "IS_FINAL",
    "lang": "普通话"
  },
  "t": 1745507675867
}

B.4.4 文本输入 ​

上行:发送文本对话内容(TEXT) ​

发文本与智能体对话,提交后流式回复文本 + 音频。

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 TEXT
contentobject是文本数据载体
content.inputstring是文本字符串
完整 JSON 示例(点击展开)
json
{
  "mid": "f70e8955-8b39-4ae8-bba1-2bea4aa6c50b",
  "contentType": "TEXT",
  "content": {
    "input": "讲个故事吧"
  }
}

B.4.5 智能体对话与回复 ​

下行:智能体对话开始(CALL_AGENT_START_EVENT) ​

根据识别结果开启对话。

外层结构:

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 EVENT
contentobject是事件数据载体

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
eventTypestring是固定为 CALL_AGENT_START_EVENT
eventDataobject是对话开始数据
eventData.inputstring是智能体对话输入内容
eventData.startTimelong是智能体对话开始时间(毫秒)
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "b1c9fc68-01c4-48b4-ba79-a8440dc9a9fa_222726_1",
    "eventType": "CALL_AGENT_START_EVENT",
    "eventData": {
      "input": "语音测试,给我个结果",
      "startTime": 1745507675867
    },
    "t": 1745507675867
  }
}

下行:智能体回复文本(AGENT) ​

智能体回复文本,流式下发,可当字幕展示。

外层结构:

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 AGENT
contentobject是智能体生成的文本回复

content 字段:

字段类型必选取值说明
roundIdstring是—消息轮次index
rolestring是assistant角色标识
contentstring是—流式文本片段
reasoningContentstring是—智能体思考内容
finishReasonstring是stop/error/audit结束原因:stop 正常结束 / error 错误 / audit 安全审核过滤
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "LLM success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "AGENT",
  "content": {
    "roundId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7_2",
    "role": "assistant",
    "content": "嘿!你好呀,",
    "reasoningContent": "",
    "finishReason": ""
  },
  "t": 1749117487494
}

下行:智能体主动回复文本(ACTIVITY) ​

静默推送触发的主动对话文本(一定时间无对话交互时触发)。字段与 AGENT 相同,区别在 contentType 为 ACTIVITY。

外层结构:

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 ACTIVITY
contentobject是智能体主动生成的文本回复

content 字段:

字段类型必选取值说明
roundIdstring是—消息轮次index
rolestring是assistant角色标识
contentstring是—流式文本片段
reasoningContentstring是—智能体思考内容
finishReasonstring是stop/error/content_filter结束原因

⚠ AGENT 的审核命中是 audit,ACTIVITY 的审核命中是 content_filter,两者不同。

完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "LLM success",
  "contentType": "ACTIVITY",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "content": {
    "roundId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7_2",
    "role": "assistant",
    "content": "嘿!你好呀,",
    "reasoningContent": "",
    "finishReason": ""
  },
  "t": 1749117487494
}

下行:智能体对话忽略(EMPTY_CONTENT) ​

未识别到有效音频,不开启对话(拒识四层防护见 拒识四层防护)。

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
eventTypestring是固定为 EMPTY_CONTENT
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7_1",
    "eventType": "EMPTY_CONTENT",
    "eventData": {
      "startTime": 1749117482960
    }
  },
  "t": 1749117482960
}

下行:语音当轮对话完成(COMPLETE) ​

当轮对话结束。

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
eventTypelong是固定为 COMPLETE
eventDataobject是数据项
eventData.timelong是完成时间戳(毫秒)
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7_2",
    "eventType": "COMPLETE",
    "eventData": {
      "time": 1749117488694
    }
  },
  "t": 1749117488694
}

B.4.6 TTS 音频合成 ​

上行:请求音频合成(CLIENT_INPUT_TEXT_TO_SPEECH) ​

主动提交文字合成语音,不触发智能体,只流式生成 TTS 音频片段。提交时若智能体正在输出语音会被中断。

外层结构:

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 EVENT
contentobject是事件数据载体
content.eventTypestring是固定 CLIENT_INPUT_TEXT_TO_SPEECH
content.eventDataobject是请求数据项(见下表)

eventData 字段:

字段类型必选说明
textstring是文本信息(会切分且分段生成音频),长度限制 (0, 1000) 字节
完整 JSON 示例(点击展开)
json
{
  "mid": "f70e8955-8b39-4ae8-bba1-2bea4aa6c50b",
  "contentType": "EVENT",
  "content": {
    "eventType": "CLIENT_INPUT_TEXT_TO_SPEECH",
    "eventData": {
      "text": "需要合成的文本"
    }
  }
}

下行:音频字幕(TTS_SENTENCE_START) ​

音频对应的字幕句子,先于 TTS 音频下发。后续的 TTS 音频均属于当前字幕。

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
eventTypelong是固定为 TTS_SENTENCE_START
eventDataobject是字幕数据项
eventData.textstring是对应文本字幕
eventData.timelong是时间戳(毫秒)
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "140adc55-8d74-4eae-80d1-1425c36c8541_1",
    "eventType": "TTS_SENTENCE_START",
    "eventData": {
      "time": 1748525295575,
      "text": "音频对应的文本内容"
    }
  },
  "t": 1748525295575
}

下行:智能体回复音频(TTS) ​

发送语音合成后的流式音频片段。

外层结构:

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 TTS
contentobject是识别结果数据

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
audioBase64string是音频数据 Base64(二进制传输时改用 binary frame)
audioAuestring是音频编码
audioDurationint是音频时长(毫秒),⚠ 参考不准确
finishbool是是否本轮最后一片(true/false)

⚠ audioDuration 为参考值不准确,不要用于精确时长计算。

完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "TTS success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "TTS",
  "content": {
    "roundId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7_2",
    "audioBase64": "UklGRiQAAABXQVZFZm10IBAAAAAB...",
    "audioAue": "mp3",
    "audioDuration": 2000,
    "finish": false
  },
  "t": 1749117488653
}

下行:语音音频回复完成(TTS_COMPLETE) ​

TTS 音频全部下发完成。

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
eventTypelong是固定为 TTS_COMPLETE
eventDataobject是数据项
eventData.timelong是完成时间戳(毫秒)
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "551cc928-a9bb-464e-9ef0-aa7366b170a9_211532_1",
    "eventType": "TTS_COMPLETE",
    "eventData": {
      "time": 1752758135335
    }
  },
  "t": 1752758135335
}

B.4.7 打断 ​

上行:打断智能体(CLIENT_INTERRUPT) ​

手动模式下打断 TTS 播放必须发送。

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 EVENT
contentobject是事件数据载体
content.eventTypestring是固定 CLIENT_INTERRUPT

⚠ 手动模式下,新一轮对话开始时若 TTS 还在输出,必须先发此事件打断,否则轮次判定异常。

完整 JSON 示例(点击展开)
json
{
  "mid": "24279824-8def-48c6-8d1c-ea8ec3aa50ac",
  "contentType": "EVENT",
  "content": {
    "eventType": "CLIENT_INTERRUPT"
  }
}

下行:智能体打断事件(CALL_AGENT_INTERRUPTED) ​

自由对话模式下,客户端收到此事件后需打断正在播放的 TTS,准备播放新音频流。

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
eventTypelong是固定为 CALL_AGENT_INTERRUPTED
eventDataobject是数据项
eventData.startTimelong是事件发生时间(毫秒)

⚠ 端侧处理:停止 TTS 播放,清空播放队列,等待新 TTS。排查见 9.3 打断失效。

完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7_2",
    "eventType": "CALL_AGENT_INTERRUPTED",
    "eventData": {
      "startTime": 1763968984181
    }
  },
  "t": 1763968984181
}

B.4.8 指令与情绪事件 ​

下行:指令事件(CALL_SKILL_EVENT) ​

设备控制类指令(音量/电量/IOT 控制),属自定义事件子类。设备端收到后无需语义判断,直接调用对应功能模块。闲聊场景下,情绪事件也复用本事件下发,供端侧驱动表情/动作。

按用途分两类:

  • 指令类:IOT 控制、设备动作(如前进/开灯),见 6.1 IOT 控制。
  • 情绪类:闲聊场景下下发情绪(7 种基础情绪 + 23 种自定义情绪),驱动端侧表情。

外层结构(指令类 / 情绪类通用):

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 EVENT
contentobject是事件数据载体(见下两类明细)

指令类 content 字段:

字段类型必选说明
roundIdstring是消息轮次 index
eventTypestring是固定 CALL_SKILL_EVENT
eventDataobject是数据项
eventData.dataobject是指令数据
eventData.data.intentCodestring是指令编码
eventData.data.intentClassifystring是意图分类(如 前进 / LIGHT_UP)
eventData.data.argsobject否指令参数(slotKey: slotValue)
eventData.data.instructionsarray是指令列表(可多条)
eventData.data.instructions[].actionstring是指令动作编码
eventData.data.instructions[].descstring是指令描述
eventData.data.instructions[].argsobject是指令参数(slotKey: slotValue)
指令类完整 JSON 示例(点击展开)
json
{
    "code": 200,
    "msg": "Event success",
    "requestId": "3871de5b-7e83-40ec-ba43-0e4f51f88b14",
    "mid": "3871de5b-7e83-40ec-ba43-0e4f51f88b14_181908_2",
    "contentType": "EVENT",
    "content": {
        "roundId": "3871de5b-7e83-40ec-ba43-0e4f51f88b14_181908_2",
        "eventType": "CALL_SKILL_EVENT",
        "eventData": {
            "msg": "端侧事件下发",
            "data": {
                "instructions": [
                    {
                        "action": "ACTION_SLIDE_FORWARD",
                        "args": {},
                        "desc": "前进"
                    }
                ],
                "args": {},
                "intentClassify": "前进",
                "intentCode": "ACTION_SLIDE_FORWARD"
            },
            "type": "CALL_SKILL_EVENT"
        }
    },
    "t": 1786357156662
}

情绪类 content 字段:

字段类型必选说明
roundIdstring是消息轮次 index
eventTypestring是固定 CALL_SKILL_EVENT
eventDataobject是数据项
eventData.msgstring是描述(如 闲聊表情情绪事件)
eventData.dataobject是情绪数据
eventData.data.intentClassifystring是意图分类,情绪类固定 闲聊
eventData.data.argsobject是情绪参数
eventData.data.args.EMOTIONstring是情绪编码,需要 JoyInside 运营平台 > 产品配置 > 开启情绪策略,平台才会返回该字段值,取下表 23 种自定义情绪之一
eventData.data.args.TTS_EMOTIONstring否TTS 音色情绪描述(如 高兴)

23 种自定义情绪 EMOTION 取值表:

情绪EMOTION情绪EMOTION
愤怒angry_1担忧anxious_1
谴责blamed_1疑惑confused_1
撒娇coquetry_1失望disappoint_1
鄙视disdainful_1兴奋exciting_1
期待expect_1恐惧fear_1
开心happy_1厌恶hate_1
犹豫hesitate_1好奇inquisitive_1
平静peace_1伤心sad_1
震惊shock_1害羞shy_1
厌倦sick_1悲伤sorrowful_1
委屈wronged_1摇头disagree_1
点头nod_1
情绪类完整 JSON 示例(点击展开)
json
{
    "code": 200,
    "msg": "Event success",
    "requestId": "3871de5b-7e83-40ec-ba43-0e4f51f88b14",
    "mid": "3871de5b-7e83-40ec-ba43-0e4f51f88b14_181908_21",
    "contentType": "EVENT",
    "content": {
        "roundId": "3871de5b-7e83-40ec-ba43-0e4f51f88b14_181908_21",
        "eventType": "CALL_SKILL_EVENT",
        "eventData": {
            "msg": "闲聊表情情绪事件",
            "data": {
                "args": {
                    "EMOTION": "happy_1",
                    "TTS_EMOTION": "高兴"
                },
                "intentClassify": "闲聊"
            },
            "type": "CALL_SKILL_EVENT"
        }
    },
    "t": 1786360424484
}

B.4.9 主动触发与上下文更新 ​

上行:主动触发对话(VOICE_CHAT_TRIGGER) ​

VOICE_CHAT_TRIGGER 用于端侧跳过 ASR/NLU 环节、直接锁定意图,让智能体按指令执行。适用于:

  • 按键、传感器等外设事件直接触发某个技能;
  • 端侧已明确用户意图,无需再走一次语音识别。

基础字段:

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 ACTIVITY
contentobject是事件数据载体
content.activityTypestring是固定 VOICE_CHAT_TRIGGER
content.kvDataobject是自定义事件消息体
content.kvData.typestring是业务类型 code,见下方枚举;不同 type 会带上各自的扩展字段

content.kvData.type 业务类型枚举:

业务类型 code说明
function_call端侧控制意图,锁定到指定 skill 技能。当前唯一支持值,后续可能扩展
场景一:type = function_call(锁定意图到指定技能) ​

在基础字段之上,需额外传入 content.kvData.function:

字段类型必选说明
content.kvData.functionstring (JSON)是函数调用参数,需 JSON 字符串化后传入,反序列化后结构见下表

function 反序列化后的结构:

字段类型必选说明
toolCodestring是工具类型。当前仅支持 switch_intent(切换意图),后续可能扩展
paramsobject是工具参数
params.skillCodestring是目标技能 ID,从JoyInside 运营平台 → 控制台 → 技能管理处复制
params.switchModestring是切换模式。当前仅支持 auto,后续可能扩展
完整 JSON 示例(点击展开)
json
{
  "mid": "f70e8955-8b39-4ae8-bba1-2bea4aa6c50b",
  "contentType": "ACTIVITY",
  "content": {
    "activityType": "VOICE_CHAT_TRIGGER",
    "kvData": {
      "type": "function_call",
      "function": "{\"toolCode\": \"switch_intent\",\"params\": {\"skillCode\": \"17fdb67ba8850928917eaa2a85809931\",\"switchMode\": \"auto\"}}"
    }
  }
}

上行:主动更新对话上下文(CLIENT_UPDATE_CHAT_CONTEXT) ​

更新短期记忆,需向 JoyInside 运营团队申请权限。服务端收到后下发 CLIENT_CHAT_CONTEXT_RECEIVED 确认。

字段类型必选取值说明
midstring是—消息唯一标识
contentTypestring是ACTIVITY固定值
contentobject是—事件数据载体
content.activityTypestring是CLIENT_UPDATE_CHAT_CONTEXT固定值
content.effectiveTimeMinutesint是1~1440记忆时长(分钟)
content.kvDataobject是—自定义扩展信息,提示词用 ${extInfo.字段} 取用
完整 JSON 示例(点击展开)
json
{
  "mid": "1",
  "contentType": "ACTIVITY",
  "content": {
    "activityType": "CLIENT_UPDATE_CHAT_CONTEXT",
    "effectiveTimeMinutes": 5,
    "kvData": {
      "自定义字段名": "自定义值"
    }
  }
}

上行:上报经纬度更新城市地址(CLIENT_UPDATE_COORDINATES_CONTEXT) ​

⚠ 使用此功能需向 JoyInside 运营团队申请权限。

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 ACTIVITY
contentobject是事件数据载体
content.activityTypestring是固定 CLIENT_UPDATE_COORDINATES_CONTEXT
content.coordinatesobject是坐标系数据
content.coordinates.latstring是纬度
content.coordinates.lngstring是经度
完整 JSON 示例(点击展开)
json
{
  "mid": "1",
  "contentType": "ACTIVITY",
  "content": {
    "activityType": "CLIENT_UPDATE_COORDINATES_CONTEXT",
    "coordinates": {
      "lat": "39.9042",
      "lng": "116.4074"
    }
  }
}

下行:上下文更新成功(CLIENT_CHAT_CONTEXT_RECEIVED) ​

CLIENT_UPDATE_CHAT_CONTEXT 成功响应。

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
activityTypestring是固定为 CLIENT_CHAT_CONTEXT_RECEIVED
activityDataobject是{}
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Activity success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "1_3",
    "activityType": "CLIENT_CHAT_CONTEXT_RECEIVED",
    "activityData": {}
  },
  "t": 1775802187178
}

下行:经纬度更新成功(CLIENT_UPDATE_COORDINATES_CONTEXT) ​

CLIENT_UPDATE_COORDINATES_CONTEXT 成功响应。

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
activityTypestring是固定为 CLIENT_UPDATE_COORDINATES_CONTEXT
activityDataobject是{}
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Activity success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "1_3",
    "activityType": "CLIENT_UPDATE_COORDINATES_CONTEXT",
    "activityData": {
      "cityName": "北京",
      "updated": true
    }
  },
  "t": 1775802187178
}

B.4.10 心跳保活 ​

上行:心跳(PING) ​

维持长连接,建议 30 秒间隔,服务端响应 PONG。

字段类型必选说明
midstring是消息唯一标识
contentTypestring是固定 PING

有声书场景心跳间隔不同,见 6.2 有声书。

完整 JSON 示例(点击展开)
json
{
  "mid": "f70e8955-8b39-4ae8-bba1-2bea4aa6c50b",
  "contentType": "PING"
}

下行:心跳响应(PONG) ​

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
midstring是消息唯一标识
tlong下行必选服务端处理时间戳(毫秒)
contentTypestring是固定 PONG
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7",
  "mid": "a4595acb-de6c-4ac9-92b2-8fa59a7f91f7_2",
  "contentType": "PONG",
  "t": 1749117488694
}

B.4.11 安全审核与互踢 ​

下行:审核命中(USER_AUDIT_FAIL) ​

输入音频命中审核,同时 AGENT 事件 finishReason=audit。

content 字段:

字段类型必选说明
roundIdstring是消息轮次index
eventTypestring是固定为 USER_AUDIT_FAIL
eventDataobject是{}
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "roundId": "",
    "eventType": "USER_AUDIT_FAIL",
    "eventData": { }
  }
}

下行:互踢(REPEAT_CLIENT_SESSION) ​

同 botId 双连接,后建踢先建,先建收到此事件被关闭。

根本原因与排查见 双连接互踢。

content 字段:

字段类型必选说明
eventTypelong是固定为 REPEAT_CLIENT_SESSION
eventDataobject是{}
完整 JSON 示例(点击展开)
json
{
  "code": 200,
  "msg": "Event success",
  "requestId": "08ddd338-fd5b-4572-b03a-43974dc145db",
  "mid": "c673b518375a4c23aeab8cb8458994d6",
  "contentType": "EVENT",
  "content": {
    "eventType": "REPEAT_CLIENT_SESSION",
    "eventData": { }
  }
}

B.4.12 设备端MCP事件 ​

设备端 MCP(Model Context Protocol)复用语音对话 WebSocket 连接,contentType 为 MCP 的消息即 MCP 协议帧。服务端作为 MCP Client 发起握手、拉取工具列表、调用工具;设备端作为 MCP Server 响应并回传结果。

完整接入流程与各阶段独有配置说明见 7.4 MCP 接入。

下行通用消息结构(服务端 → 设备) ​

MCP 下行事件,各阶段(initialize / tools/list / tools/call)共用以下外层结构,content.params 内容随 method 不同而变化。

字段类型必选说明
codeint下行必选响应状态码,200 表示成功
msgstring下行必选状态描述信息
requestIdstring下行必选请求唯一标识符
contentTypestring是固定 MCP
contentobject是MCP 协议数据载体
content.idint是请求 ID。initialize 固定为 1,tools/list 固定为 2,tools/call 从 3 起步递增
content.methodstring是请求方法:initialize / tools/list / tools/call
content.paramsobject否请求参数,随 method 不同而变化(详见各阶段说明)
tlong下行必选服务端处理时间戳(毫秒)

上行通用消息结构(设备 → 服务端) ​

MCP 上行事件,各阶段共用以下外层结构。设备通过 content.result(成功/业务结果)或 content.error(协议错误)回传,content.id 与下行请求一一对应。

字段类型必选说明
midstring是请求唯一标识符
contentTypestring是固定 MCP
contentobject是MCP 协议数据载体
content.idint是与下行请求 content.id 一致
content.resultobject否调用结果封装(成功/业务结果时使用,详见各阶段说明)
content.errorobject否错误信息封装(协议层错误时使用,详见各阶段说明)

content.result 与 content.error 二选一:正常返回(含业务出错 isError=true)使用 result,协议层错误使用 error。各阶段独有字段及 JSON 示例见 7.4 MCP 接入。


下一步 ​