基于websocket协议的产品接入

一、产品介绍

基于websocket协议API请求DUI全链路产品,获得对话交互结果

1.1 适用场景

  • 轻量级嵌入式设备,基于协议开发
  • 采用云对云的方式,使用DUI全链路产品,基于协议开发
  • 其他特殊场景,需要基于协议开发
  • 支持语音,文本,意图三种输入

1.2 使用限制

需要先前往控制台创建全链路产品,并且将产品成功发布,才能正常使用基于websocket协议的API

二、接入说明

2.1 接入前的准备

  • 登录DUI控制台
  • 创建全链路产品
  • 进行产品配置
  • 添加技能
  • 进行产品测试
  • 配置授权
  • 发布产品

2.2 建立websocket连接

本API正式环境的地址是wss://dds.dui.ai/dds/v3/[分支号],其中[分支号]是DUI控制台分支管理页面的内容。如下图所示

2.2.1连接上需要携带的公共参数

参数名

含义

是否必须

取值示例
serviceType 表示使用何种协议 websocket
productId 产品标识 278578090
productVersion 指定使用的产品版本 1
userId 用户标识,字符串uuid 1234567

连接上需要携带的授权参数,包含了授权参数,授权有两种场景,一种是设备对接云,一种是云对云;

2.2.2设备对接云端API的授权参数

参数名

含义

是否必须

取值示例

deviceName 设备激活时获取到的device profile中deviceName字段

0ddddeeeeeeeeeeee88888888260c8ab
nonce 随机字符串, 32字符以内 bf7c8674
sig 签名, 对query parameter中的参数按照预先约定的顺序排序 (devicename + nonce + productId + timestamp),然后基于 deviceSecret对参数做签 名:hmacsha1(deviceSecretSecret, devicename + nonce + productId + timestamp) 0ddddddddd94dd87788888888260c8ab
timestamp unix时间戳(毫秒) 1546059559999

获取deviceName,需要走设备激活流程。

2.2.3云端对接云端的授权参数

参数名

含义

是否必须

取值示例

apikey DUI控制台生成的绑定过ip的访问标识

0ddddeeeeeeeeeeee88888888260c8ab

2.2.4一条完整的云端对接云端的连接示例

wss://dds.dui.ai/dds/v3/test?serviceType=websocket&productId=278578090&apikey=0ddddeeeeeeeeeeee88888888260c8ab

2.2.5在以下情况下建立连接会失败

  • 产品没有发布
  • 产品分支号没有对应已经发布过的产品版本
  • 授权参数不正确,服务端鉴权不通过

2.2.6正确建立websocket连接的报文

2.2.7连接上支持用户级鉴权

wss://dds.dui.ai/dds/v3/test?serviceType=websocket&productId=278578090&apikey=0ddddeeeeeeeeeeee88888888260c8ab&accessToken=xxxx

 

2.3 发送语音请求

websocket连接建立成功之后,调用端首先向服务端发送一个opcode为text的报文;

这个报文的payload是一个json字符串;

2.3.1语音请求text参数

参数名 含义 是否必须 取值示例
topic 用于标识开启一次语音请求,报文中需要携带必要的音频参数以及一些控制参数开启语音请求后,后续需要发送websocket的binary帧携带音频数据发送到服务端 recorder.stream.start
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId uuid,服务端通过相同的sessionId关联多轮请求的上下文;首轮对话请求不需要携带;非首轮对话请求取值是上一轮服务端返回结果中的sessionId DUIddeeeeeeeeeeee88888888260c8ab
audio.audioType 音频类型,推荐使用压缩过的音频格式,以节省带宽,推荐ogg,不支持ogg vorbis,只支持ogg speex ogg, wav,mp3,flv,amr,opus,adpcm
audio.sampleRate 音频数据采样率,推荐使用16000; (ogg支持8000,16000;wav支持8000,16000;mp3支持16000,22050,44100;amr支持8000) 16000
audio.channel 声道 1
audio.sampleBytes 音频数据每采样点大小 2
wakeupWord 触发当次请求的唤醒词,用于oneshot使用场景 你好小驰
commonWakeupWord 设置自定义唤醒词 ["你好小思","你好小四"]
asrParams.res 切换方言识别,英文识别 aisichuan-mix(中川混),aishandong-mix(中鲁混),aishanghai-mix(中沪混),aienglish-mix(中英混),aicantonese-mix(中粤混),aiaccentnorth-mix(中原话),aihenan-mix(河南话),aiminnan(闽南话)
asrParams.enableTone 是否使用拼音带声调 true,false
asrParams.enablePunctuation 识别结果是否开启标点符号 true,false
asrParams.enableVAD 是否使用识别服务内置的vad模块检测 true,false
asrParams.customWakeupScore 自定义唤醒词增强识别的分数,和wakeupWord配合使用,用该分数增强识别wakeupWord唤醒词,并过滤该唤醒词 -15
asrParams.enableConfidence 识别结果是否返回置信度 true,false
asrParams.enableNumberConvert 识别结果中文数字转成阿拉伯数字 true,false
asrParams.realBack 是否使用实时识别结果 true,false
asrParams.phraseHints 请求级热词增强(只对识别生效)
[
    {
        "type": "vocab",
        "name": "行政区",
        "data":["黄浦区"]
    }
]
asrParams.phraseList 数组,用于在一路中做热词增强识别。如果不启用该功能请不要传这个字段;boost表示增强强度,从小到大取值是1,2,3; 默认值是1使用约束:1.目前支持2个槽位:common和wakeup
2.热词总词数小于等于1000个
3.单个热词的限制是:1到10个字符,字符范围只能是简体中文、阿拉伯数字、英文大小写字母
[{"name":"common", "words":["示例"], ”boost“:3},{"name":"wakeup", "words":["唤醒"], ”boost“:3}]
asrParams.enableEmotion 是否开启情感识别 true,false
asrParams.enableAudioDetection 是否开启云端音频检测,如果未检测到有效音频,则会终止后续对话流程 true,false
asrParams.vadPauseTime 支持调用端指定vad在结束语音时采用的静音时长,取值范围是200~2000,单位是ms,默认500ms 1000
asrParams.tedPauseTime 在开启vad文本截断检测之后,支持调用端指定vad在结束语音时采用的静音时长,取值范围是200~10000,单位是ms,默认2000ms 5000
asrParams.enableTedVad 开启vad文本截断检测(简称动态vad) true, false
asrParams.enableCloudVAD 是否开启云端vad检测,开启云端会返回asr.vad.start的topic表示vad start, 此参数和asrParams.enableVAD冲突,开启后会关闭识别服务内置的vad模块检测 true, false
asrParams.vadId 指定云端vad服务使用的资源,开启asrParams.enableCloudVAD之后才生效 vad_aicar_v0.16
asrParams.enableProcessedWavTime 是否开启返回ProcessedWavTime字段 true, false
asrParams.enableNluRec 是否开启nlu_rec true, false
asrParams.enableRecUppercase 是否开启大小写,默认开启 true, false
asrParams.enableNBest 是否开启返回nbest结果, 与开vad的实时反馈不兼容 true, false
asrParams.nbest 开启了asrParams.enableNBest才生效,返回多少个nbest结果enableAudioDetection 3
asrParams.enableNBestConfidence 开启了asrParams.enableNBest才生效, 返回nbest的置信度 true, false
asrParams.enableSeparateNBest 开启了asrParams.enableNBest才生效,返回每一路的nbest结果 true, false
asrParams.cLmId 支持请求传入定制的三路模型标识 ["c-lm-id"]
asrParams.abLmId 支持请求传入定制的二路模型标识 ["ab-lm-id"]
asrParams.itnId ITN模型标识 "itn-id"
asrParams.enableCloudVADRecEnd 开启服务端主动切断音频返回识别结果, 无需客户端再发送stop报文(开启了enableCloudVAD后才生效),开启本开关后一定时间内未发送有效音频会返回错误码为"010370"的识别错误 true, false
asrParams.vadSilentTime 开启enableCloudVADRecEnd后才生效,客户端指定无效音频的最大时长,超出后会返回错误码为"010370"的识别错误 [ 2000 - 10000] ms
asrParams.enableAlignment 开启后识别结果中会返回alignment字段,包含音频和识别结果对应的时间信息 true,false
asrParams.enableDialectProcess 方言识别结果转成普通话, 影响rec结果 true,false
asrParams.enableDialectProcessNluRec 方言识别结果转成普通话, 需要配合asrParams.enableNluRec使用,开启后语义解析会使用转换后普通话结果,识别结果仍为方言 true,false
asrParams.enableCensor 使用最终识别结果请求中控前,先使用敏感词过滤服务检查一遍识别结果,并将检查结果传给中控服务;并且在识别结果中新增"sensitiveWords":["X1","X2"]字段,其中X1,X2表示检测到的敏感词 true,false
asrParams.enableOfflineMode
目前只适用于加速离线一把说这一种场景(2s~5s音频一把送,asrParams.enableOfflineMode:true)
注意在加速完成之后,后续的在线音频流需要调用端保证重新发不含enableOfflineMode参数的start报文

true,false

nluParams.enableCensor 对语义解析的输入做敏感词检查 true,false
nluParams.enableNBest 当指定aiType为nlu时,返回nbest语义结果 true,false
nluParams.enableASRResult 当指定aiType为nlu时,返回asr结果 true, false
nluParams.languageClass 指定文本请求的语种 putonghua/cantonese/sichuanhua/shanghaihua/shandonghua
ttsParams.enableStreamURL speakUrl支持流式播放 true,false
ttsParams.enableStreamData 开启后不再返回speakUrl, nlg 音频直接通过 topic 在当前连接上返回, 返回报文格式见 2.11 tts nlg 音频流响应报文 true / false (默认)
ttsParams.returnPhone 合成播放连接(speakUrl)会返回音素信息,注意这个参数必须配合ttsParams.enableStreamURL:true使用 true,false
ttsParams.pitchChange 变声器功能(取值范围[-60,60],-60表示音量小,60表示音量大)  
ttsParams.speakingStyle 情感参数,默认值default,目前仅有两种音色支持情感参数ryzenm : night
kuayuf : angry/sad/happy情感参数支持自定义,可以跟思必驰项目经理沟通
 
ttsParams.domain 领域,可以加强某些领域的特定读法(推荐general)  
ttsParams.language 语种(目前支持cantonese|sichuanese)  
ttsParams.styleDegree 情感强度[0.0-2.0]  
ttsParams.rmargin 音频后置静音(取值范围(0,1000],单位毫秒,默认值350ms)  
context.skill.skillId 在非首轮中可能用到,用于指定调用端使用了上一轮nbest结果中的哪一个skill 0000000000000000
context.skill.task 在非首轮中可能用到,用于指定调用端使用了上一轮nbest结果中的哪一个task 查天气
context.attributes.$key string类型,请求级自定义属性key设置,用于通过dds透传给自定义服务 location
context.attributes.$value 支持string类型或json object,请求级自定义属性value设置,用于通过dds透传给自定义服务
{
    "latitude": 25.79952408587054,
    "longitude":110.92025591449065
}
aiType 指定云端服务的类型,asr表示识别结果,nlu表示语义结果,不设置该字段表示对话结果 asr,nlu
responseTemplate 设备端裁剪JSON回复 {
    "dm":{
        "shouldEndSession":false,
        "nlg":false
    }
,
    "speakUrl":false,
    "sessionId":false
}###zb私有云需求,调用端指定哪些字段保留
{
    "version":"2",
    "skillId":true,
    "sessionId":true,
    "dm":{
        "intentId":true,
        "shouldEndSession":true,
        "widget":{
            "content":[
                {
                    "linkUrl":true
                }
            ]
        },
        "input":true,
        "command":true
    },
    "speakUrl":true
}
responseFormat 控制云端回复的识别结果和NLG使用简体中文,还是繁体中文,默认使用简体中文 traditionalChinese
asrPlus.enableAsrPlus 是否开启声纹 true/false
asrPlus.users 开启声纹后users和groupId 二选一,用户ID列表,表示指定用户ID列表做声纹验证。users成员为声纹系统注册用户ID。 [ "user_id1","user_id2" ]
asrPlus.organization 开启声纹后必填,注册的声纹厂商、机构、组织 "aispeech"
asrPlus.groupId 开启声纹后users和groupId 二选一,分组ID,表示指定某分组做声纹验证,分组成员为与分组有关联关系的声纹系统注册用户ID。 "48182a"
asrPlus.enableVprPassThrough 开启声纹后生效,是否透传声纹信息给DSK技能,默认为false,开启后对话结果延迟会增加 true/false

 

2.3.2语音请求binary数据

调用端发送完opcode为text的报文之后,接着发送语音数据,opcode为binary, payload是语音数据;

语音数据建议分帧发送,每帧包含的语音时长是100毫秒;

语音数据发送完毕之后,需要再发送一个opcode为binary,payload是空,表示语音数据发送完毕;

2.3.3 全链路语音请求交互时序图

2.4 发送文本请求

2.4.1文本请求参数

参数名

含义

是否必须

取值示例

topic 直接使用文本的方式请求全链路获取对话结果 nlu.input.text
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
refText 请求的文本 苏州的天气
nluParams.enableCensor 对语义解析的输入做敏感词检查 true,false
nluParams.enableNBest 当指定aiType为nlu时,返回nbest语义结果 true,false
context.skill.skillId 在非首轮中可能用到,用于指定调用端使用了上一轮nbest结果中的哪一个skill 0000000000000000
context.skill.task 在非首轮中可能用到,用于指定调用端使用了上一轮nbest结果中的哪一个task 查天气
context.attributes.$key string类型,请求级自定义属性key设置,用于通过dds透传给自定义服务 location
context.attributes.$value 支持string类型或json object,请求级自定义属性value设置,用于通过dds透传给自定义服务
{
    "latitude": 25.79952408587054,
    "longitude":110.92025591449065,
	"enablePredict":true, // 开启预测
	"enableTextFilter":true // 开启文本请求拒识
}
aiType 指定云端服务的类型,asr表示识别结果,nlu表示语义结果,不设置该字段表示对话结果 asr,nlu

 

text请求报文示例

{
    "topic":"nlu.input.text",
    "recordId":"19557b26631c4c8ca397e685460addfe",
    "refText":"奶牛英文怎么说",
}

2.5 发送触发意图请求

2.5.1触发意图请求参数

参数名

含义

是否必须

取值示例

topic 主动触发某个意图的对话 dm.input.intent
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
input 识别文本 深圳的天气
intent 意图名称 查天气
task 任务名称 查天气
skillId 技能id,和skill两个字段中必须有一个 0000000000000000
skill 技能名称,和skillId两个字段中必须有一个 查天气
slots 语义槽名称,语义槽取值集合

[
    {
        "name":"city",
        "value":"深圳",
        "rawpinyin":"shen zhen",
        "rawvalue":"x",
        "pos":[
            4,
            5
        ]
    }

]

 

其中 slots[i].name 和 slots[i].value 是必须的

context.attributes.$key string类型,请求级自定义属性key设置,用于通过dds透传给自定义服务 location
context.attributes.$value 支持string类型或json object,请求级自定义属性value设置,用于通过dds透传给自定义服务
{
    "latitude": 25.79952408587054,
    "longitude":110.92025591449065
}

 

text请求报文示例

{
    "topic":"dm.input.intent"
    "recordId":"f0444b311c900bb18ab54d77deb1edbd",
    "sessionId":"c6e2eb99f0d87a4f27de09908b143132",
    "skill":"新版天气",
    "task":"天气",
    "intent":"天气数据后台获取",
    "slots":[
        {
            "name":"city",
            "value":"深圳",
        }
     ]
}

 

2.6 发送数据

包含native api查询数据、其他多模态数据

参数名

含义

是否必须

取值示例

topic 对话数据输入,客户端送数据给云端对话 dm.input.data
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
extra 自定义参数,透传给用户

{
"isKeepSingle":"true",
    "replaytype":"-1"
}

duiWidget 控件名称 list
count 列表长度 1
type 控件类型 list
content 控件内容

[
        {
            "title""忘情水",
            "subTitle""来生缘",
            "label":"刘德华",
            "imageUrl":"http://liu-de-hua.png",
            "linkUrl":"http://wang-qing-shui.mp3"
            "extra": {
                "resType""mp3"
            }
        },
        {
            "title""爱你一万年",
            "subTitle""来生缘",
            "label":"刘德华",
            "imageUrl":"http://liu-de-hua.png",
            "linkUrl":"http://ai-ni-yi-wan-nian.wav"
            "extra": {
                "resType""wav"
            }
        }
    ]

intent 意图名称 查城市天气
skillId 技能id 0000000000000000
task 任务名称 查天气

 

text请求报文示例

{
    "topic":"dm.input.data",
    "recordId":"b187d0a13ada41e8aea631f0475cf981",
    "sessionId":"389691adaa554d63b76d6737130cfd4b",
    "duiWidget":"list",
    "count":5,
    "type":"list",
    "content":[
        {
            "title":"NAERSILING(深圳宝安国际机场T3航站楼)",
            "subTitle":"深圳机场T3航站楼4楼6号门"
        },
        {
            "title":"麦当劳(T3航站楼二店)",
            "subTitle":"机场三道1001号T3航站楼5层"
        },
        {
            "title":"NiCE(深圳宝安国际机场T3航站楼)",
            "subTitle":"宝安国际机场t3航站楼4号门"
        },
        {
            "title":"泡泡玛特门店(深圳机场T3航站楼)",
            "subTitle":"宝安国际机场航站楼3C-04-07号铺"
        },
        {
            "title":"LANCOME(深圳宝安国际机场T3航站楼)",
            "subTitle":"宝安国际机场T3航站楼四楼"
        }
    ]
}

2.7 回复的对话结果(包括触发意图回复结果)

当请求的text报文没有aiType字段时,回复的是对话结果

2.7.1对话结果参数

参数名

含义

是否必须

取值示例

dm.intentName 意图名称 查天气
dm.input 识别结果或者客户端发送的文本  
dm.intentId 意图id 0000000000000000
dm.runSequence 本地执行command和播报nlg的先后顺序 nlgFirst / commandFirst
dm.widget 显示控件  
dm.widget.widgetName 控件名称,冗余为了兼容老字段 card
dm.widget.subTitle 副标题 好听的歌
dm.widget.name 控件名称 card
dm.widget.extra 用于透传webapi返回字段  
dm.widget.title 主标题 忘情水
dm.widget.buttons[].name 按钮显示提示 播放
dm.widget.duiWidget 控件类型,冗余为了兼容老字段 media
dm.widget.type 控件类型 media
dm.widget.count 列表控件内容数 1
dm.widget.content 列表控件内容  
dm.widget.currentPage 列表控件当前页 2
dm.widget.totalPages 列表总共页数 5
dm.widget.itemsPerPage 每页显示数 5
dm.widget.match 内容是否匹配 1
dm.nlg 系统生成的对话回复 今天的天气是晴
dm.task 任务名称 查天气
dm.taskId 任务id
5dde41305ce0a54ea7a8db3e
dm.shouldEndSession 表示对话是否结束 true,false
dm.status 对话状态1表示对话结束,0表示未结束 0 或 1
dm.speak 合成内容, 只会有list类型  
dm.speak.type 合成类型 list
dm.speak.$type 合成内容
list:
"list": [
    {
        "audioUrl":"https:\/\/cdn.caitun.com\/audio\/882eb9fc-23da-4c92-9f87-60acf3cbd80f.mp3",
        "type":"audio"
    },
    {
        "type":"text",
        "text":"狗狗开始睡觉了,你的狗狗活力指数现在为87.10。你的狗狗将在今天13点35分自动醒来。"
        "speakUrl": "https:\/\/dds-ack.dui.ai\/runtime\/v1\/cache\/1360b1e6af7fec84f73118ec4ed78568?productId=278586436"
    }
]
dm.ssml ssml合成内容 <?xml version=\"1.0\" encoding=\"utf8\"?><speak xml:lang=\"cn\"><sentence>音量已<phoneme py=\"tiao2 dao4\">调到<\/phoneme> 100 <\/sentence><\/speak>
dm.dataFrom 数据来源 native api 查询到数据后需要通过dm.input.data将数据传给ddsserver native
dm.api native api ais.scene
dm.param  

{
"scene":"上班模式",
"execute":"执行",
"duiWidget":"text",
"intent":"场景控制"
}

dm.command 本地命令,没有返回值  
dm.command.api 命令url nativecmd://cbzcommand
dm.command.param 命令参数

{
"donotinterrupt":"true"
}

dm.custom BA技能返回的自定义信息  
dm.custom.intent BA技能的通用意图  
dm.custom.intent.type 意图类型 半截
dm.custom.intent.sub_type 意图子类型 ""
dm.custom.sentiment BA技能的情绪意图  
dm.custom.sentiment.type 意图类型 惊讶
dm.inspireType inspireType和inspire 成对出现,表示inspire类型,端侧可以通过类型对inspire进行解析

recommend (推荐反问)/ multiIntent (一句话多意图) / groupCommand (组合指令)

dm.inspire 启发式对话列表  
dm.inspire[i].widget 控件,格式同dm.widget  
dm.inspire[i].speak 合成内容,格式同dm.speak  
dm.inspire[i].command 本地命令,格式同dm.command  
dm.inspire[i].dataFrom native api 时返回该字段 native
dm.inspire[i].api native api 时返回该字段 ais.scene
dm.inspire[i].param native api 时返回该字段 {
"scene":"上班模式",
"execute":"执行",
"duiWidget":"text",
"intent":"场景控制"
}
dm.inspire[i].runSequence 本地执行command和播报nlg的先后顺序 nlgFirst / commandFirst
dm.languageClass 语种信息 取值为 putonghua / cantonese / sichuanhua / shanghaihua / shandonghua
skillId 技能id 0000000000000000
skill 命中技能的名称 天气
speakUrl 语音播报nlg的链接 https://dds.dui.ai/xxx
error.errId 错误id 010400
error.errMsg 错误信息 It's time to do qa.
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
contextId

向前兼容(sessionId替代了)待废弃

 
topic 对话结果topic (v3 接口新增) dm.output

 

dm.ouput回复示例

{    
    "topic":"dm.output",
    "recordId":"1360b1e6af7fec84f73118ec4ed78568",
    "sessionId":"73ab6db6e09a47b6824088fd81e2c523",
    "contextId":"73ab6db6e09a47b6824088fd81e2c523",
    "skill":"天琴天气",
    "skillId":"2021050600000006"
    "speakUrl":"https:\/\/dds-ack.dui.ai\/runtime\/v1\/cache\/1360b1e6af7fec84f73118ec4ed78568?productId=278586436"
    "dm":{
        "input":"今天天气怎么样",
        "taskId":"5dde41305ce0a54ea7a8db3e",
        "task":"天气"
        "intentId":"617f5dfa08bda80001550cf5",
        "intentName":"天气",
        "shouldEndSession":false,
        "status":0,
        "nlg":"今天深圳市的天气晴,15~23℃,微风,1~2级。"
    }
}

2.7.2对话中间结果(全双工独有)

{
    "dm":{
        "context":{},
        "runSequence":"commandFirst",
        "command":{
            "api":"discardResponse"
			"params":{
				"type":"nluDiscard"					//  如果是 discardResponse,此时标示拒识类型,nluDiscard:语义拒识, asrDiscard:识别拒识,dmDiscard:对话拒识, dmModelDiscard:模型拒识
			}
        },
        "shouldEndSession":false
    },
    "topic":"dm.rt.output",                         //dm.rt.output,表示该消息为全双工对话中的中间反馈消息。
    "recordId":"b56305154f1d4fbc8af90b9b36cbbc90",
    "contextId":"5ce4918ace8c45279b24e0be6c848246",
	"recordList":{},
    "sessionId":"5ce4918ace8c45279b24e0be6c848246"
}


2.8 回复的语义结果

当请求的text报文有aiType字段,并且aiType字段为nlu时,回复的是语义结果

2.8.1语义结果参数

参数名 含义 取值示例
nbest[].nlu nbest语义结果  
skillId 技能id 0000000000000000
skill 技能名称 新版国学
recordId 请求id DUIddeeeeeeeeeeee88888888260c8ab
nlu.input 识别结果 播放西游记
nlu.skillId 技能id 0000000000000000
nlu.skill 技能名称 新版国学
nlu.skillVersion 技能版本号 16
nlu.semantics.request.slots[].name 语义解析的语义槽键名 intent
nlu.semantics.request.slots[].value 语义解析的语义槽键值 播放国学
nlu.semantics.request.slots[].pos 语义槽值在原文本中的起始位置和结束位置

2,4

nlu.semantics.request.slots[].rawvalue 语义解析的语义槽键值原始文本 西游记
nlu.semantics.request.slots[].rawpinyin 语义解析的语义槽键值拼音 xi you ji
nlu.semantics.request.task 任务名称 国学
nlu.semantics.request.slotcount 语义槽数量 3
nlu.semantics.request.confidence 语义解析到本技能的置信度 1
nlu.version 语义内核版本 2019.1.15.20:40:58
nlu.res taskId 5dde41305ce0a54ea7a8db3e
nlu.timestamp 语义计算结束时间戳 1637825187
nlu.loadtime 语义加载模型时间 (单位: ms) 29.94482421875
nlu.inittime 语义计算初始化时间 (单位: ms) 4.20166015625
nlu.systime 语义计算时间 (单位: ms) 301.86401367188
topic 语义结果topic (v3 接口新增) nlu.output

 

nlu.output回复示例

{
    "topic":"nlu.output",
    "recordId":"283765edd8fcf004d065879ed940c1a9",
    "skillId":"2021050600000006",
    "skill":"天琴天气"
    "nlu":{
        "input":"今天天气怎么样",
        "skillId":"2021050600000006",
        "skill":"天琴天气",
        "skillVersion":"5",
        "semantics":{
            "request":{
                "confidence":1,
                "slots":[
                    {
                        "pos":[
                            0,
                            1
                        ],
                        "value":"20211125",
                        "name":"日期",
                        "rawvalue":"今天",
                        "rawpinyin":"jin tian"
                    },
                    {
                        "value":"天气",
                        "name":"intent"
                    }
                ],
                "slotcount":2,
                "task":"天气"
            }
        }
        
        "version":"2019.1.15.20:40:58",
        "res":"5dde41305ce0a54ea7a8db3e",
        "timestamp":1637825187,
        "loadtime":29.94482421875,
        "inittime":4.20166015625,
        "systime":301.86401367188
    }
} 

2.9 回复的识别结果

当请求的text报文有aiType字段,并且aiType字段为asr时,回复的是识别结果

2.9.1识别结果参数

参数名 含义 取值示例
recordId 请求id DUIddeeeeeeeeeeee88888888260c8ab
eof 标识识别是否结束 1表示结束,0表示未结束
var 识别中间结果 播放
text 识别最终结果 播放西游记
conf 识别结果置信度 0.81
emotion 情感 happy [angry, happy, sad, neutral]
emotionScore 情感分类的分数 8.369701
age 年龄段  [child,adult, elder]
ageScore 分数 0.99844
gender 性别 [female, male]
genderScore 分数 0.999998
audioDetection

音频检测结果

开启enableAudioDetection后会和rec一起同步返回

1, 句子音频包含有效语音
0, 句子音频未包含有效语音
textLM1 识别一路结果 播放西游记
textLM2 识别二路结果 播放西游记
textLM3 识别三路结果 播放西游记
processedWavTime 已处理的有效音频时长,开启enableProcessedWavTime后才会返回 1880
nbest[].text nbest识别结果 播放西游
nbestComm[].text 一路nbest结果 播放一首my heart will go on
nbestAB[].text 二路nbest结果 播放一首my heart will go on
nbestC[].text 三路nbest结果 播放一首my heart will go on
nbestDomain[].text domain路nbest结果 播放一首my heart will go on
nbestConf[].pinyin nbest结果拼音,数组下标和nbest中每个text对应 bo fang yi shou MY HEART WILL GO ON
nbestConf[].conf nbest结果置信度 1
nbestConf[].wordConf[].word 字/词 播放
nbestConf[].wordConf[].pinyin 字/词拼音 bo fang
nbestConf[].wordConf[].conf 字/词置信度 1
alignment[i].word 识别结果的时间信息中的字/词 苏州
alignment[i].pinyin 识别结果的时间信息中的拼音 su1zhou1
alignment[i].start 字/词在音频的相对开始时间 360
alignment[i].end 字/词在音频的相对结束时间 640

注:在识别结果实时反馈的情景下,需要使用下述方法获取最终识别结果:

1.使用/dds/v3以下接口时,回复报文中没有topic字段,需要对json报文做如下逻辑:当eof为1并且有text时,这个text不表示最终的识别结果。

调用端需要缓存之前接收的eof为0,并且text不为空的结果,并且把这些text按接收的时间顺序做拼接,取拼接后的字符串作为最终的识别结果。

 

2.使用/dds/v3及以上接口时,回复报文中一定含有topic字段,调用端的判断逻辑是:当topic == "asr.speech.text" 时,缓存并拼接text字段;当topic == "asr.speech.result"时,此时的text字段表示最终识别结果,此时需要丢弃之前的缓存

 中间识别结果示例

{
    "topic":"asr.speech.text",
    "recordId":"e78a386a37bb8f1ca38c4d43689af5bb",
    "sessionId":"33022982c1324360828802e4bd1728f6"
    "var":"今天 天气",
    "eof":0  
}

 

最终识别结果示例

{
    "topic":"asr.speech.result",
    "recordId":"728d6b38c2b60fba7364acc21093d8bb",
    "sessionId":"66e14207b8a34386b7103bd8875d8242",
    "text":"今天天气怎么样?",
    "pinyin":"jin tian tian qi zen me yang",
    "eof":1,
    "conf":1,
    "emotion":"sad",
    "age":"adult",
    "gender":"female",
    "emotionScore":5.287,
    "genderScore":3.91,
    "ageScore":7.557
}

 

识别错误结果示例

{
    "topic":"asr.error",
    "recordId":"18e9d1dd9ebd8c30edcf265ade7ddc23",
    "text":"",
    "eof":1,
    "errId":"010307",
    "errMsg":"asr calc service close socket."
}

2.9.2 声纹结果

当请求参数携带asrPlus,并且开启时,会返回声纹结果,topic为 asrplus.voiceprint.result, 仅表示声纹验证有结果,即有确定的结果,验证出来说话人在和不在给定的用户列表里都属于声纹验证有结果

参数名 含义 类型 取值示例
topic topic string asrplus.voiceprint.result
recordId 请求id string DUIddeeeeeeeeeeee88888888260c8ab
sessionId 会话id string 96e446beee364ce4ab8fb7899609861b
speakerLabels

声纹结果

 

list

[
{
"bg": 160,
"ed": 4380,
"rec": "",
"speakerId": "100001",
"errno": 0,
"error": ""
},
{
"bg": 4380,
"ed": 8380,
"rec": "",
"speakerId": "100002",
"errno": 0,
"error": ""
}
]

speakerLabels[0].bg 音频开始时间 int 160
speakerLabels[0].ed 音频结束时间 int 4380
speakerLabels[0].rec 识别结果 string "今天天气怎么样"
speakerLabels[0].speakerId 说话人id string
"100001"
speakerLabels[0].errno 错误码 int 42001
speakerLabels[0].error 错误描述 string Speaker not in user list.

声纹结果示例

{
    "topic":"asrplus.voiceprint.result",
    "recordId":"92750db07cacaa94c4c22567bfa2b4a4",
    "sessionId":"03eb1dcb019341b8a6fe6aeca68afd90",
    "speakerLabels":[
        {
            "bg":240,
            "ed":1520,
            "speakerId":"9527110",
            "rec":"今天 星期天 明天 星期一",
            "errno":0,
            "error":""
        }
    ]
}

2.9.3 声纹错误

当请求参数携带asrPlus,并且开启时,会返回声纹结果,topic为 asrplus.voiceprint.error

参数名 含义 类型 取值示例
topic topic string asrplus.voiceprint.error
recordId 请求id string DUIddeeeeeeeeeeee88888888260c8ab
error.errId 错误码 string  
error.errMsg 错误信息 string  

声纹错误示例

{
    "topic":"asrplus.voiceprint.error",
    "recordId":"40b1fdd687d95183ecb2b67075f40c9f",
    "error":{
        "errId":"010363",
        "errMsg":"voiceprint server returns errno: 42203, error: 未找到匹配的注册声纹"
    }
}

2.9.4 vad结果

当请求中开启了enableCloudVAD后,服务会返回一条特定的响应,表示云端vad start, 报文如下:

参数名 含义 类型 取值示例
topic topic string asr.vad.start
recordId 请求id string DUIddeeeeeeeeeeee88888888260c8ab
sessionId 会话id string 96e446beee364ce4ab8fb7899609861b
vadState vad状态 int 1

vad结果示例

{
    "topic":"asr.vad.start",
    "recordId":"f05575e1086eec347646aaab36dd3759",
    "sessionId":"0ab50a8e46f04992b3c4c4931efc5e1f",
    "vadState":1
}

2.9.5 一句话识别结果(全双工独有)

当调用端触发vad end通知服务端,或者服务端主动触发vad end后,服务端会返回这条消息

参数名 含义 取值示例
topic 标明返回结果为实时识别结果 必须为 asr.speech.sentence.
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId uuid,服务端通过相同的sessionId关联多轮请求的上下文 DUIddeeeeeeeeeeee88888888260c8ab
requestId 请求级别 uuid DUIddeeeeeeeeeeee88888888260c8ab
sentence 识别结果文本 苏州的天气
pinyin 识别结果文本拼音 su zhou de tian qi
{
    "pinyin":"su zhou de tian qi",
    "recordId":"DUIAUTOTEST-05373b8c933238867924afffc82eb5dc:67efb0a443ef47cd8d2bea58adb8eba8:d92579b6db544f849d58b430f1982ff3",
    "topic":"asr.speech.sentence",
    "sessionId":"da2a433c49494406ad65826f81f560e8",
    "requestId":"d016df6b6151460ea5ba91fa06c7bb34",
    "sentence":"苏州的天气"
}

2.9.6 取消识别

用于调用端在某些场景下,触发vad start之后,又不想关心当前语音交互结果了,此时可以发送取消识别的报文,报文示例如下

{
    "topic": "recorder.stream.cancel",
    "recordId": "f988431eb2f74fbc97aa650b90d40e64"
}

3.0 多模态数据同步请求

参数名 含义 是否必须 取值示例
topic 指定多模态数据同步请求 dm.context.sync
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
async 具体内容需要放在这个字段下

{
    "dispatchEvent":{
        "playerState":"off"
    }

}

3.0.1同步合成音播放状态(全双工要求)

多模态同步接口,上传客户端状态给服务端;新添加 dispatchEvent字段,用于上传事件给中控,而不透传给技能服务,此消息对话中控无回复,报文示例如下

{
    "topic": "dm.context.sync",
    "sessionId":"123456",
	"skillId":"2017112800000011", 
    "async":{
        "dispatchEvent":{           //客户端上传事件给中控,该事件为中控消费,不会传给技能服务;该字段存在时,task,intent,skillid,slots,widget为非必选字段
            "playerState":"off",    //取值范围on/off,分别代表客户端开始/停止 提示音播报, 
									//on上传上来时,同样可以暂停当前会话超时统计,直到下次off上来开始统计
        },
        "task":"导航",
        "intent":"导航",
        "skillId":"2017112800000011",
        "slots":{

        },
        "widget":{

        }
    }
}

3.0.2同步当前对话状态(全双工要求)

多模态同步接口,上传客户端状态给服务端,报文示例如下

{
	"topic": "dm.context.sync",
	"skillId":"2017112800000011",	// 最新的skillId
    "sessionId":"123456",
    "async":{
        "task":"导航",			// 最新的task
        "intent":"导航",			// 最新的意图
		"skill":"xxx",			// 最新的skillName
        "skillId":"2017112800000011",	// 最新的skillId
        "slots":[{                  	// 既往的slots数据
                "name":"目的地",         // 必选         
                "value":"北京",          // 必选
                "rawpinyin":"bei jing", // 可选
                "rawvalue":"北京"        // 可选
            }
		],
        "widget":{
			"type":"xxx",           // 控件类型:"text", "content", "list", "media", "web", "custom"
            "name":"xxx",           // 控件名称,必须有,默认default
            #attributes#,           // 各个控件数据格式抽象,格式见上,格式参考https://wiki.aispeech.com.cn/pages/viewpage.action?pageId=1214998
        }
    }
}

可以一次性同步多个技能上下文,报文示例如下

{
	"topic": "dm.context.sync",
	"skillId":"2017112800000011",	// 最新的skillId
    "sessionId":"123456",	
	"async":[{                 // 多模态特性所需的状态同步, 一次性同步多个上下文 add 20230523 v2,一次性同步多个技能上下文,同时
            "intent":"导航",             // 最新的意图
            "task":"导航",               // 最新的task
            "skill":"xxx",              // 最新的skillName
            "slots":[{                  // 既往的slots数据
                "name":"目的地",         // 必选         
                "value":"北京",          // 必选
                "rawpinyin":"bei jing", // 可选
                "rawvalue":"北京"        // 可选
            }],
            "widget":{                  // 存在控件数据时上传,而且只上传更新后的数据
                "type":"xxx",           // 控件类型:"text", "content", "list", "media", "web", "custom"
                "name":"xxx",           // 控件名称,必须有,默认default
                #attributes#,           // 各个控件数据格式抽象,格式见上
            }
        }
        ,{                 // 多模态特性所需的状态同步, 同dm.context.sync
            "intent":"导航",             // 最新的意图
            "task":"导航",               // 最新的task
            "skill":"xxx",              // 最新的skillName
            "slots":[{                  // 既往的slots数据
                "name":"目的地",         // 必选         
                "value":"北京",          // 必选
                "rawpinyin":"bei jing", // 可选
                "rawvalue":"北京"        // 可选
            }],
            "widget":{                  // 存在控件数据时上传,而且只上传更新后的数据
                "type":"xxx",           // 控件类型:"text", "content", "list", "media", "web", "custom"
                "name":"xxx",           // 控件名称,必须有,默认default
                #attributes#,           // 各个控件数据格式抽象,格式见上
            }
        }]
}

3.0.3同步清除当前上下文状态(全双工独有)

多模态同步接口,清除当前会话上下文,此消息对话中控无回复

{
    "topic": "dm.context.sync",
    "sessionId":"DUIddeeeeeeeeeeee88888888260c8ab",
    "async":{
        "dispatchEvent":{           //客户端上传事件给中控,该事件为中控消费,不会传给技能服务;该字段存在时,task,intent,skillid,slots,widget为非必选字段
 			"endSkillEx":"true",    //取值范围"true",分别需要清除上下文信息
        }
    }
}

3.0.4同步更新会话超时时间(全双工独有)

多模态同步接口,增加或减少会话超时时间,此消息对话中控无回复

{
    "topic": "dm.context.sync",
    "sessionId":"DUIddeeeeeeeeeeee88888888260c8ab",
    "async":{
        "dispatchEvent":{           //客户端上传事件给中控,该事件为中控消费,不会传给技能服务;该字段存在时,task,intent,skillid,slots,widget为非必选字段
            "updateSessionTimeout":"5000",    //更新会话超时,更新后会话超时重新计时
        }
    }
}

3.1 重新加载连接级参数

在不重建ws连接的前提下,通过topic:connection.reload来完成服务端连接级变量的重置,这种参数的用途是干预后续的请求,如中控和对话使用context.attributes的场景

请求报文示例

{
    "topic":"connection.reload",
    "recordId":"xx",
    "sessionId":"xx",
    "context":{
        "attributes":{
            "key":"value"
        }
    }
}
context字段可以不携带,此时云端的行为是完成连接级变量的重置,如设备级热词,设备级tts发音人等
如果携带context字段,context.attributes下一级的字段是自定义的,云端的行为会merge上一次recorder.stream.start报文中上传的context.attributes,完成请求级参数的重置

下面给出一个merge行为的实际示例

1 调用端在t1时刻上传了recorder.stream.start报文,其中含有context.attributes信息,如下

{
    "context":{
        "attributes":{
            "pictureId":"123"
            "other":"abc"
        }
    }
}

2 调用端在t2时刻上传了connection.reload报文,其中含有context.attributes信息,如下

{
    "context":{
        "attributes":{
            "pictureId":"456"
        }
    }
}

3 dds在t3时刻收到上述报文,在t4时刻收到最终识别结果,此时,dds服务向中控服务传的报文如下

{
    "context":{
        "attributes":{
            "pictureId":"456"
            "other":"abc"
        }
    }
}

 

回复报文如下

成功

{
    "topic":"connection.reload.result",
    "recordId":"xx",
    "sessionId":"xx"
}

失败

{
    "topic":"connection.reload.result",
    "recordId":"xx",
    "sessionId":"xx",
    "error":{
        "errId":"010107",
        "errMsg":"reload connection context error"
    }
}

在设置失败的情况下会携带error字段

3.2 错误码列表

errId errMsg 含义
010104 product info error 产品id错误
010105 检测到敏感词 检测到敏感词
010302 text payload not ready. text报文错误
010304 asr calc service internal error. 请求识别服务错误
010305 asr result is null 识别结果为空
010306 asr calc service connect timeout. 连接识别服务超时
010307 asr calc service close socket. 识别服务关闭连接
010308 asr calc service socket send error. 发送识别报文错误
010309 server receive audio in wrong sequence. 服务收到识别报文乱序
010310 asr calc service server busy. 识别服务过载
010311 asr calc service audio too large. 服务收到音频过大
010312 asr calc service recv timeout. 未收到stop帧导致接收asr服务返回超时,需要客户端检查是否发送了stop帧
010316 connect asr service error. 连接识别服务错误
010360 voiceprint usage error 声纹参数使用错误
010361 voiceprint server internal error 声纹服务内部错误
010362 voiceprint server returns unknown error 声纹服务返回了无法解析的报文
010363 vpr info not found 未查到声纹注册信息
010370 vad silent timeout exceeded 长时间未检测到有效音频
010400 It's time to do qa. 说法未标注
010402 nlu service error. 请求语义服务出错
010403 meet exiting command. 说法命中退出词
010404 no dispatch status. 技能调度失败
010405 request cnluserver error. 请求语义服务错误
010406 request oliveserver error. 请求内置语义服务错误
010410 request body invalid. 请求中控的body非法
010411 Do not have product info. 获取不到对应产品信息
010412 Do not have bundle info, can not get skillId. 获取不到之前上下文信息(execute return信息没有找到之前上下文信息,查询数据返回理论上只出现在非首轮)
010413 Do not find this skillId. 未找到skillId对应技能配置信息(triggerIntent和sysnc接口)
010414 Do not contain sessionId. 请求中控时未携带sessionId
010415 Do not contain retry audio. 命中透传音频技能时,传输音频的body未携带audio数据
010501 connect dm service error. 请求cdmserver失败
010502 dm service error. 对话服务内部错误
010504 over max retry times 错误重试次数超过限制
010505 fallback skill respond ok. 命中兜底技能
010507 ba skill respond ok. 命中BA技能
010601 product in blacklist,refuse connect 产品被禁止连接
010602 ip in blacklist,refuse connect ip被禁止连接
010603 product in blacklist,refuse request 产品被禁止请求
010604 ip in blacklist,refuse request ip被禁止请求
010605 traffic limit, refuse request 触发流控
010801 RUYI service error. 请求RUYI服务错误
080002 webhook timeout. 请求web api超时
080003 webhook error. 请求web api错误
080004 Semantic parsing failure 首轮语义结果为空
080005 Do not support this task 不支持的技能任务
080007 The input sequence is incorrect 当前输入不在之前条件输入的下一轮对话列表中
080008 Do not hava asr result 首轮识别为空;对话中识别为空
080010 Do not hava any matching condition 定制的输出nlg条件出错
080012 响应超时,暂时不能为你提供服务 本地api调用超时
080013 Api can not be null 数据源未定义
080014 Retrytime up to maximum 到达错误重试次数退出
080015 ba timeout 请求自定义技能超时
080016 proxy invalid. 自定义技能未按协议返回
080017 proxy return empty. 自定义技能服务返回nlg为空
080018 proxy service error. 请求自定义技能服务错误
080019 Do not have this intent 不存在意图的对话资源
010700 request dm dispatcher error. 请求新中控对话服务错误
010701 format dm dispatcher input error. 格式化中控报文出错,需要客户端检查请求参数是否正确

ps:在调用端可以忽略下述错误码

010105 检测到敏感词
010305 识别结果为空

010400 说法未标注

010403 说法命中退出词

010504 错误重试次数超过限制

010505 命中兜底技能

010507 命中BA技能

080012 本地api调用超时

三、上传配置

3.1上传技能级配置

上传的数据仅在指定的技能中使用,如用户微信是否在登录状态。

参数名 含义 是否必须 取值示例
topic string类型,表示技能级配置topic

skill.settings

recordId string类型,uuid,标识一次请求,32字符

DUIddeeeeeeeeeeee88888888260c8ab

skillId string类型,技能ID标识

0000000000000000

option string类型,执行选项,设置或者删除

set(默认)/ delete / get

settings json数组类型,每个元素标识一组设置的k-v列表

[{"key":"key1","value":"value1"}]

settings[0].key string类型,自定义key名称

city

settings[0].value string类型,自定义key对应的取值,当option是delete不需要 否 

苏州

3.2上传系统级配置

上传的数据是公用的,有多个技能会关心并使用此类配置。如设备所在位置信息。

 

参数名 含义 是否必须 取值示例
topic string类型,表示系统级设置topic

system.settings

recordId string类型,uuid,标识一次请求,32字符

DUIddeeeeeeeeeeee88888888260c8ab

option string类型,执行选项,设置或者删除

set(默认)/ delete / get

settings json数组类型,每个元素标识一组设置的k-v列表

[{"key":"key1","value":"value1"}]

settings[0].key string类型,自定义key名称

city

settings[0].value string类型或者json,自定义key对应的取值,当option是delete不需要

苏州

3.3 上传配置回复

参数名 含义 取值示例
recordId 请求id DUIddeeeeeeeeeeee88888888260c8ab
topic 配置上传结果topic

skill.settings.result 技能级配置结果

system.settings.result 系统级配置结果

settings[0].key option是get 时返回, string类型,查询自定义key名称 city
settings[0].value option是get 时返回, string类型,查询到的value,如果没查到则返回一个null 苏州
error.errId 错误码 (设置失败时才有)

1 - 参数错误

2 - 服务内部错误

error.errMsg 错误信息描述 (设置失败时才有)

key error in settings.

3.4 指定技能调度黑名单

{
    "topic":"system.settings",
    "recordId":"xxxx",
    "settings":[
        {
            "key":"excludeDispatchSkillList",
            "value":"['skillid1', 'skillid2', 'skillid3']"
        }
    ]
}

 

3.5 指定技能调度白名单

{
    "topic":"system.settings",
    "recordId":"xxxx",
    "settings":[
        {
            "key":"dispatchSkillList",
            "value":"['skillid1', 'skillid2', 'skillid3']"
        }
    ]
}

四、特定的使用场景

4.1 半双工场景下使用云端vad的要求

  • 接收线程收到topic:asr.error后,要通知发送线程返回start状态,重新发送text报文
  • 接收线程收到topic:dm.output后,要通知发送线程返回start状态,重新发送text报文
  • 接收线程/协程收到topic:dm.output,并且结果中有shouldEndSession:true,此时表示多轮对话结束,要通知发送线程返回init状态,等待下一次唤醒