Java接入UNIT文本对话处理源码详解
荒墨丶迷失 发布于2017-11-22 15:41 浏览:10571 回复:40
4
收藏

应邀一位网友的想法,想实现调用UNIT接口,实现文字对话功能,特整理一下内容分享给大家。

此功能对于大神来说非常简单,但是对于新手理解代码处理逻辑,并且如何解析UNIT返回参数的处理,还是有一定的帮助的

嘿嘿~文章最下方有源码下载地址哟~

如果您还不了解UNIT的使用,请移步到UNIT文档,请认真阅读~

http://ai.baidu.com/docs#/UNIT-sample/top

并且能够训练出该场景的机器人,本文例子就是利用这个天气机器来做对接的。

 

接下来看下对话交互的页面效果,请看下方图片

以上是整体的交互效果,那么现在简单的来说说怎么搭建这个项目的步骤:

1.训练出UNIT场景模型(此处为天气查询场景)

2.导入此例子的源码项目(java开发)

3.修改token配置

4.启动项目即可

按照以上步骤一步一步进行,先看看该项目的包结构

注意:获取token类之后,把token复制到UNIT核心类中,并且还需要记得修改场景ID,以下是核心类的作用:解析UNIT返回的JSON数据,获取我们需要的数据

此处能力有限,只能一步一步利用JSON解析,hhhh~

  //获得返回的json数据
	        String str = HttpUtil.post(talkUrl, accessToken, "application/json", params);
	     	System.out.println(str);
	     	//获得result
	     	JSONObject jsonobject = JSONObject.fromObject(str);
	     	String result = jsonobject.getString("result");
	     	System.out.println(result);
	     	//获得会话session_id
	    	JSONObject jsonobject2 = JSONObject.fromObject(result);
			session_id = jsonobject2.getString("session_id");
			map.put("session_id", session_id);
			//获得动作列表
			String action_list =jsonobject2.getString("action_list");
			JSONArray json = JSONArray.fromObject(action_list); // 首先把字符串转成 JSONArray  对象
			if(json.size()>0){
			    for(int i=0;i<json.size();i++){
			        JSONObject job = json.getJSONObject(i);  // 遍历 jsonarray 数组,把每一个对象转成 json 对象
			        String say = (String) job.get("say");//机器bot返回的话术
			        map.put("say", say);
			        System.out.println(say);
				    String action_id = (String) job.get("action_id");//动作名称,当为fail_action时表示未能命中任何意图
				    map.put("action_id", action_id);
				    if(!"fail_action".equals(action_id)){//命中意图
					    Object object = job.get("action_type");//获得action_type对象  动作详细
				        JSONObject jsona = JSONObject.fromObject(object);//转成json对象
				        String act_type = jsona.getString("act_type");//动作类型,取值clarify/satisfy/guide
		//				    clarify: 澄清 ; satisfy: 满足 ; guide: 引导 ;faqguide: faq引导
		//			    info.setAct_type(act_type);
				        map.put("act_type", act_type);
				        if("satisfy".equals(act_type)){
				    	    //解析意图概要
				    	    String schema =jsonobject2.getString("schema");//获得意图概要
				    	    JSONObject jsonObect = JSONObject.fromObject(schema);
				    	    String current_qu_intent = jsonObect.getString("current_qu_intent");//获得当前意图
				    	    String bot_merged_slots = jsonObect.getString("bot_merged_slots");//词槽列表  
				    	    map.put("current_qu_intent", current_qu_intent);
				    	    map.put("bot_merged_slots", bot_merged_slots);
				        }else{
				        	map.put("mapSchema", null);
				        }
				    }else{
				    	map.put("act_type", null);
				    }
			    }

然后在分享控制层的作用:

1.首先用一个Map接收解析的数据,传到控制层,然后

2.判断是否命中意图,

3.如果命中意图,该意图是否完成还是未完成,

4.既然是命中意图,那么命中的是那个意图,需要做什么样的逻辑处理.

//调用unit分析语音
					Map<String, String> map = UnitService.utterance(session_id, msg);
					//判断是否命中意图
					if(!"fail_action".equals(map.get("action_id"))){
						//判断是否意图结束
						if("satisfy".equals(map.get("act_type"))){
							session_id="";//意图结束,清空session_id
							/**
							 * 以下是意图处理逻辑,根据命中的意图,判断进入当前意图的对话处理  current_qu_intent字段为意图
							 */
							switch (map.get("current_qu_intent")) {
								case "RAIN": //查询是否下雨
									//解析是否刮风的词槽列表
									String companyParams = getCompany(map.get("bot_merged_slots"));
									if(!companyParams.equals("")){
										modelMap.put("companyParams", companyParams);
									}else{
										modelMap.put("companyParams", map.get("raw_query"));
									}
									modelMap.put("queryType", "COMPANY");
									break;
								case "WIND": //查询是否刮风
									//解析是否刮风的词槽列表
									String companyParams2 = getCompany(map.get("bot_merged_slots"));
									if(!companyParams2.equals("")){
										modelMap.put("companyParams", companyParams2);
									}else{
										modelMap.put("companyParams", map.get("raw_query"));
									}
									modelMap.put("queryType", "COMPANY");
									break;
								default:
									break;
								}
						}else{
							//意图未完成 需要传入session_id 用户下一次对话
							session_id = map.get("session_id");
						}
						//返回机器人说的bot  不管意图有没有命中
						modelMap.put("msg", map.get("say"));
					}else{
						modelMap.put("msg", "我好像不太明白");
					}

接下来咋们看前台的一个处理,这是页面上的发送消息的一个函数,作用:

1.获取文本消息,加载到聊天页面样式中

2.ajax调用后台控制层,然后判断是否正常返回数据

3.加载机器回复消息样式

//发送消息
function sendMessage(event, from_name){
	//获得发送的消息
    var msg = $("#message").val();
// 	alert(msg);
    //自己回复的样式加载
	var htmlData =   '<div class="msg_item fn-clear">'
                   + '   <div class="uface"><img src="../images/hetu.jpg" width="40" height="40"  alt=""/></div>'
			       + '   <div class="item_right">'
			       + '     <div class="msg own">' + msg + '</div>'
			       + '     <div class="name_time">' + from_name + ' · 30秒前</div>'
			       + '   </div>'
			       + '</div>';
	$("#message_box").append(htmlData);
	$('#message_box').scrollTop($("#message_box")[0].scrollHeight + 20);
	$("#message").val('');
	
	var session_id = $("#session_id").val();
	$.ajax({
   		type:"POST",
   		url:"${pageContext.request.contextPath}/unit/common.do",
//    	datatype: "json",
   		data:{
   			"session_id":session_id,
   			"msg":msg
   		},
   		success:function(data){
	   		var mes = eval(data);
	   		if (mes.success) {
	   			var msg = data.msg;
	   			var session_id = data.session_id;
	   			$("#session_id").val(session_id);
	   		 	//机器人回复样式加载
	   			var htmlData =   '<div class="msg_item fn-clear">'
	   		                   + '   <div class="uface"><img src="../images/53f442834079a.jpg" width="40" height="40"  alt=""/></div>'
	   					       + '   <div class="item_right">'
	   					       + '     <div class="msg">' + msg + '</div>'
	   					       + '     <div class="name_time">' + '机器人 ' + '· 30秒前</div>'
	   					       + '   </div>'
	   					       + '</div>';
	   			$("#message_box").append(htmlData);
	   			$('#message_box').scrollTop($("#message_box")[0].scrollHeight + 20);
	   			$("#message").val('');
	   			
	   		} else {
	   			alert("返回数据失败");
	   		}
   		},
   		error: function(){
    		//请求出错处理
    		alert("出情况了");
    		}         
  		});
}

经过前台和后台的一些讲解,不知道大家清楚不,如果有任何问题,可以在下方回复我

感谢支持~

附加源码下载:https://gitee.com/liyingming/unitTest

收藏
点赞
4
个赞
共40条回复 最后由人人心人土土回复于2018-04-20 14:12
#2荒墨丶迷失回复于2017-11-22

0
#3荒墨丶迷失回复于2017-11-22

当然如果是对话式机器人,只需要在UNIT处理前,通过录音获取音频,调用语音识别接口,拿到识别文本,传入UNIT还是做以上处理,最后,把返回的say或者其他,利用语音合成技术,播放机器人回复的话语即可~

1
#4756665228回复于2017-11-22

厉害了 分享的不错。让管理给你加个鸡腿

1
#5goJhou回复于2017-11-22

给你加鸡腿

1
#6kohakuarc回复于2017-11-22
#5 goJhou回复
给你加鸡腿

路过,支持一下~~

1
#7卡农LLLL回复于2017-11-23

如果再把DuerOS的闲聊.音乐.新闻等接入进来就更好了.希望能有人一起研究研究.

0
#8goJhou回复于2017-11-23
#7 卡农LLLL回复
如果再把DuerOS的闲聊.音乐.新闻等接入进来就更好了.希望能有人一起研究研究.
展开

有开放平台哇

0
#9荒墨丶迷失回复于2017-11-23
#7 卡农LLLL回复
如果再把DuerOS的闲聊.音乐.新闻等接入进来就更好了.希望能有人一起研究研究.
展开

这个写的新手贴.....

0
#10荒墨丶迷失回复于2017-11-23
#8 goJhou回复
有开放平台哇

这么快就回到家了呀,hhhh~

0
#11goJhou回复于2017-11-23
#10 荒墨丶迷失回复
这么快就回到家了呀,hhhh~

刚到 那个用手机回你的

0
#12卡农LLLL回复于2017-11-23
#8 goJhou回复
有开放平台哇

什么开放平台?

0
#13goJhou回复于2017-11-24
#12 卡农LLLL回复
什么开放平台?

DuerOS 开放平台

0
#14卡农LLLL回复于2017-11-24
#13 goJhou回复
DuerOS 开放平台

现在迭代很快.这周又更新了.Dueros

0
#15goJhou回复于2017-11-25
#14 卡农LLLL回复
现在迭代很快.这周又更新了.Dueros

我已经玩不过来了。。。

0
#16卡农LLLL回复于2017-11-25
#15 goJhou回复
我已经玩不过来了。。。

躁起来.不要停.要像海绵一样吸收每一滴精华.

0
#17goJhou回复于2017-11-26
#16 卡农LLLL回复
躁起来.不要停.要像海绵一样吸收每一滴精华.

叫你一声海绵宝宝你敢不敢答应

0
#18卡农LLLL回复于2017-11-26
#17 goJhou回复
叫你一声海绵宝宝你敢不敢答应

吸吸吸.我要把太平洋吸干.

0
#19荒墨丶迷失回复于2017-11-26
#14 卡农LLLL回复
现在迭代很快.这周又更新了.Dueros

我的板子还没到怎么玩hhhh~

0
#20goJhou回复于2017-11-27
#19 荒墨丶迷失回复
我的板子还没到怎么玩hhhh~

等你板到了,板子2.0就出了

0
#21荒墨丶迷失回复于2017-11-27
#20 goJhou回复
等你板到了,板子2.0就出了

这....迭代真快~

0
TOP
切换版块