6.1.云端对话


对话管理(Dialog Management, DM)

对话管理控制着人机对话的过程,DM 根据对话历史信息,决定此刻用户的反应。最常见的应用还是任务驱动的多轮对话,用户带着明确的目的如订餐、订票等,用户需求比较复杂,有很多限制条件,可能需要分多轮进行陈述,一方面,用户在对话过程中可以不断修改或完善自己的需求,另一方面,当用户的陈述的需求不够具体或明确的时候,机器也可以通过询问、澄清或确认来帮助用户找到满意的结果。SDK 方案提供了云端对话管理的能力,配合DUI平台强大的在线更新能力,可以做到云端对话技能秒级更新。开发者在接入AICloudDMEngine之前需要先在DUI平台配置云端技能,则AICloudDMEngine会按照云端对话内容的配置进行对话内容的分发。

对话配置

需开发者自行前往DUI平台创建产品、申请授权、添加技能,文档参见 : https://www.duiopen.com/docs/ct_skill ,方便开发者快速对接DUI,车载团队也提供一套标准的车载技能可供开发者直接继承使用,具体使用可直接与思必驰车载技术支持联系。

内置录音机

语音识别SDK按平台内置有录音机,可完成识别过程中的音频采集任务。

音频压缩

支持符合16Khz采样率、16bit数据位宽的PCM音频识别,SDK内部会对音频进行压缩。

VAD功能

VAD (语音活动检测)功能为可选项,开启后可启用本地的语音活动检测功能。关闭后,只能通过实体按键结束语音输入。
允许设置VAD后端点检测超时时间,开启后若说话停顿时长超过阈值,则主动结束本次识别的输入。

实时反馈识别结果

支持流式返回识别结果。当用户开口说话时,部分识别结果就绪后,能立即展示该部分结果。

初始化

AICloudDMEngine mEngine = AICloudDMEngine.createInstance();
 mEngine.init(new AICloudDMConfig.Builder()
         .setUseVad(true)
         .setVadRes(SampleConstants.VAD_RES)
         .setAliasKey("test") //设置请求的产品分支
         .setUseFullDuplex(true)//开启全双工,默认为false
         .build(), new AICloudDMListener() {

     @Override
     public void onQuery(NativeApi nativeApi) { //native api 回调

     }

     @Override
     public void onCall(Command command) {  //command 回调

     }

     @Override
     public void onPlay(Speaker speaker) { // nlg 播报内容

     }

     @Override
     public void onDisplay(CallbackWidgetType callbackWidgetType, CallbackWidget callbackWidget) {
         //控件展示
     }  

     @Override
     public void onAsr(boolean b, String s) {
         //实时识别结果
     }

     @Override
     public void onEnd(String s) {
         //对话结束
     }

     @Override
     public void onRmsChanged(float v) {
         //vad 音量
     }

     @Override
     public void onBeginningOfSpeech() {

     }

     @Override
     public void onEndOfSpeech() {

     }

     @Override
     public void onInit(int i) {

     }

     @Override
     public void onError(AIError aiError) {

     }

     @Override
     public void onReadyForSpeech() {

     }

     @Override
     public void onResultDataReceived(byte[] bytes, int i, int i1) {

     }

     @Override
     public void onRawDataReceived(byte[] bytes, int i) {

     }
 });

启动对话

mEngine.start();//创建对话,使用默认的对话配置

//自定义对话配置
//  AICloudDMIntent intent = new AICloudDMIntent();
//  intent.setWakeupWords(new String[]{"你好小驰","小驰你好"});
//  intent.setEnableEmotion(true);
//  mEngine.start(intent);

结束对话

mEngine.stop();

回复对话结果

对话下发native api 内容后,待客户端完成查询后,需将查询内容同步云端对话。

mEngine.feedback(new ListFeedbackWidget()
                            .addContentWidget(new ContentFeedbackWidget().setTitle("世界之窗1号").setSubTitle("世界之窗")));

主动触发意图

常见用户手动触发某个UI 页面,对话需进入对应的技能内。

  SkillIntent intent = new SkillIntent();
  intent.setIntentName("设置提醒");
  intent.setSkillId("2018061500000026");
  intent.setTaskName("提醒");
  mEngine.triggerIntent(intent);

通知引擎播报完成

因为对话配置可能是多轮的,下一轮对话内容的分发之前需要等待上一轮nlg内容播报完成后,故需要外部主动通知引擎播报完成

mEngine.notifyNlgEnd()

更新词库

设备级内容词库上传接口,常见联系人、app信息上传,影响识别融合后的结果。

mEngine.updateVocabs(new AIUpdateListener() {
                                     @Override
                                     public void success() {
                                         Log.d(TAG, "update success");
                                     }

                                     @Override
                                     public void failed() {
                                         Log.d(TAG, "update failed");
                                     }
                                 }, new Vocab.Builder()
                            .setContents(Arrays.asList(new String[]{"刘","关","张"}))
                            .setAction(Vocab.ACTION_CLEAR_AND_INSERT)
                            .setName("sys.联系人")
                            .build()
            );

更新设备状态

设备状态接口同步接口,常见定位数据上报,主要用作技能内信息引用和查询使用。

mEngine.updateProductContext(new AIUpdateListener() {
                @Override
                public void success() {
                    Log.d(TAG , "update success");
                }

                @Override
                public void failed() {
                    Log.d(TAG , "update failed");
                }
            }, new ProductContext.Builder()
                    .setSetting(new Setting("location", "{\"city\":\"上海市\"}"))
                    .setOption(ProductContext.OPTION_SET)
                    .build());

更新技能配置

设备级动态调整技能优先级,影响语义融合后的结果。

           mEngine.updateProductContext(new AIUpdateListener() {
                @Override
                public void success() {

                }

                @Override
                public void failed() {

                }
            } , new ProductContext.Builder()
                    .setSetting(new Setting( "skillPriority" , "['skillid1', 'skillid2', 'skillid3']"))
                    .build());

全双工,锁定技能调度列表

            mEngine.updateProductContext(new AIUpdateListener() {

                @Override
                public void success() {

                }

                @Override
                public void failed() {

                }
            } , new ProductContext.Builder()
                    .setOption(ProductContext.OPTION_SET)
                    .setSetting(new Setting(Setting.DISPATCH_SKILL_LIST , new JSONArray().put("2018112000000006")))//锁定车控技能
                    .build());

全双工,过滤技能列表

            mEngine.updateProductContext(new AIUpdateListener() {
                @Override
                public void success() {

                }

                @Override
                public void failed() {

                }
            } , new ProductContext.Builder()
                    .setOption(ProductContext.OPTION_SET)
                    .setSetting(new Setting(Setting.FILTER_SKILL_LIST , new JSONArray().put("2018050400000026")))//过滤闲聊技能
                    .build());

更新全双工超时时间

            mEngine.updateProductContext(new AIUpdateListener() {
                @Override
                public void success() {

                }

                @Override
                public void failed() {

                }
            } , new ProductContext.Builder()
                    .setOption(ProductContext.OPTION_SET)
                    .setSetting(new Setting(Setting.FULL_DUPLEX_SESSION_TIMEOUT , "5000")) //5s对话超时
                    .build());

全双工返回结果差异

全双工和半双工一样,都会返回dm.output消息,该消息为对话结果;全双工模式下,会增加dm.rt.output消息,该消息会携带全双工的状态和事件 给客户端,实现全双工特性。

//jsontopicdm.rt.output
//dm.command.api
{
    "dm": {
        "command": {
            "api": "interrupt"
        },
        "status": 0,
        "runSequence": "commandFirst",
        "shouldEndSession": false
    },
    "topic": "dm.rt.output",
    "contextId": "5b82ff0f9e4448c891a282d64dcf2500",
    "recordList": {
        "beginTime": 1380,
        "endTime": 3000,
        "expireTime": 2000,
        "recordIdList": [{
            "beginTime": 1380,
            "recordId": "b917dd4c0fcc4fb69c2a10a25abbae12",
            "endTime": 0
        }]
    },
    "sessionId": "5b82ff0f9e4448c891a282d64dcf2500",
    "requestId": "5b49fc73b81f4944b71dc63c48780629"
}
参数 说明
topic
sessionId 对话上下文ID,对话过程中,服务端会返回该ID,如果客户端没有生成,则服务端会自动生成该ID。
recordList 对应recordId列表
command.api interrupt:客户端收到该事件,可以打断正在播报的tts;discardResponse:说明该句输入,没有命中任何语义,被服务端拒识,当作噪声处理,客户端不需要做出响应;backchannel:服务端返回的接话响应。比如:用户说 '我想听' ... '一首歌',在‘我想听’后短暂犹豫一会,服务端会给一个短回复如‘嗯’,使对话过程更流畅自然

results matching ""

    No results matching ""