那欢迎各位看我的贴子,我是Impulse. 大家好
本干货系列教程,所有最终的目的是与C#进行交互,而不是单纯使用UNIT,所以在以后的帖子中,可能会涉及到除UNIT以外的服务。
我在UNIT的摸索学习中,有一些小经验可以分享给大家
之后可能会时不时写干货给大家,如果能帮助到大家开发了,我也会感到很愉快
话不多说,我们开始吧
在这一篇,我会给各位看到我自己写的一部分封装代码,旨在传递一种思维,希望能和大家共勉(程序小白,大牛勿喷)
首先是发送给UNIT
如何发送在官方文档中都有写到,我就不再多述,直接上核心方法封装代码
以下为发送给UNIT并获取返回JSON对象的命令
大致分为3个方向,意图成功完成,将返回完整的json对象。意图未完成会将澄清话语进行打印。未知意图将走第3条路(可能是因为少配了对话集,做这条路为了方便完善意图)
这里使用到了以下几个第三方类库 可以在NuGet中下载到
Newtonsoft.Json;
Newtonsoft.Json.Linq;
这里提供意图完成与意图未完成的两种结果json对象样本,供大家代入代码进行学习
部分有备注
意图完成:
{
"log_id": 150237316846815,
"result": {
"action_list": [
{
"action_id": "open_satisfy",
"action_type": {
"act_target": "",
"act_target_detail": "",
"act_type": "satisfy", satisfy表示意图完成
"act_type_detail": ""
},
"arg_list": [],
"code_actions": {},
"confidence": 1,
"exe_status": [],
"hint_list": [],
"main_exe": "open", 该执行函数的名字
"say": ""
},
{
"action_id": "open_guide",
"action_type": {
"act_target": "",
"act_target_detail": "",
"act_type": "guide",
"act_type_detail": ""
},
"arg_list": [],
"code_actions": {},
"confidence": 1,
"exe_status": [],
"hint_list": [ 这里是引导的内容
{
"hint_query": "关闭"
},
{
"hint_query": "调整"
}
],
"main_exe": "",
"say": "好的" 这里是UNIT bot说的话
}
],
"qu_res": {
"intent_candidates": [
{
"extra_info": null,
"from_who": "ml_qu",
"func_slot": "",
"intent": "OPEN",
"intent_confidence": 99.60952758789062,
"intent_need_clarify": false,
"match_info": "",
"slots": [
{
"confidence": 99.77851104736328,
"length": 4,
"need_clarify": false,
"normalized_word": "灯光",
"offset": 6,
"original_word": "灯光",
"type": "user_target",
"word_type": ""
}
]
}
],
"log_id": "openapi_150237316846815_9161",
"raw_query": ",打开灯光,", 用户进入时的完整句子,因为我接入了百度的语音识别,所以会有两个逗号
"status": 0,
"timestamp": 1
},
"schema": {
"bot_merged_slots": [
{
"begin": 0,
"confidence": 0,
"length": 0,
"merge_method": "update",
"normalized_word": "灯光", 这里是归一后的词
"original_word": "灯光", 这里是用户进入的词
"session_offset": 0,
"type": "user_target", 词槽名称
"word_type": ""
}
],
"current_qu_intent": "OPEN",
"intent_confidence": 99.60952758789062
},
"session_id": "a47fba40a0cf4dfb900466d4e91d84551" 多轮会话需要把这个暂时写入static变量,以方便下次调用
}
}
意图未完成:
{
"log_id": 150237384639821,
"result": {
"action_list": [
{
"action_id": "open_user_target_clarify",
"action_type": {
"act_target": "slot",
"act_target_detail": "user_target",
"act_type": "clarify", clarify表示意图未完成
"act_type_detail": ""
},
"arg_list": [],
"code_actions": {},
"confidence": 1,
"exe_status": [],
"hint_list": [],
"main_exe": "",
"say": "打开什么?" 缺词槽会返回澄清话语
}
],
"qu_res": {
"intent_candidates": [
{
"extra_info": null,
"from_who": "ml_qu",
"func_slot": "",
"intent": "OPEN",
"intent_confidence": 99.08135223388672,
"intent_need_clarify": false,
"match_info": "",
"slots": []
}
],
"log_id": "openapi_150237384639821_9161",
"raw_query": ",打开,", 用户说的话
"status": 0,
"timestamp": 1
},
"schema": {
"bot_merged_slots": [],
"current_qu_intent": "OPEN",
"intent_confidence": 99.08135223388672
},
"session_id": "4215dc84ec1240b0a4fd7773b012daaf1" 补充词槽需要重复调用这个sessionID
}
}
那到上一步我们只是完成了意图分析,有后续的补充词槽和意图错误的可能。请各位根据自己的环境去定义之后的路该怎么走
在获取到了完整的json对象后,我将它的返回值抛给了DoSth函数进行所谓的
意图执行
使用json对象可以很方便的去foreach,然后匹配它们的词槽,填入我相应的变量中。 这里我就是以归一化设计去写的
各位请先判断一下这个normalized_word是否为空,我这里忘写了
最后是获取对象,我在c#中暂时使用了枚举,如果归一做的好的话,完全不需要枚举,可以将设备类型定义在设备的实体类中使用linq抓取。
这里代码有用到Linq知识,不过多作讲解,如果有需要可自行百度了解
这里是意图执行的核心代码。包含了如何查找对象,如何查找函数,及执行函数
由于函数签名千变万化,我觉得各位可能有更好的办法解决这种问题。这里我使用了泛型和根据函数签名走不同指向的方式来解决。
MethodInfo为Reflection下的类型。请引入System.Reflection
反射可通过函数名定位函数,并传参执行
如果使用得当,MethodInfo将获取到确切的函数对象
那针对这一块根据函数名找函数执行,我觉得各门语言大同小异,理解一下思路总是好的。
那上头的代码是我根据我自己的系统进行定制化开发的。
关于C#中如何根据函数名执行函数,详情请参考:http://blog.csdn.net/u011045710/article/details/9102775
那通过我三个章节的介绍,相信你对UNIT的用途、开发过程、接入过程有了一个进阶的了解。
我也非常感谢各位可以坚持看完我所有的UNIT干货系列
希望对各位有所帮助和启发。如果有更好的建议,随时欢迎跟贴喔!!!
你们又开始刷屏了的感觉.
嗯嗯,就这道理
授人以鱼不如授人以渔~哈哈~
其实我是想教思想的。代码直接给你们,可能会因为环境的问题跑不起来的
论坛支持代码块就好了...现在能把代码放git上面大家好伸手吗...大神.
嗯,关注楼主,有好多不错的分享~
干货越来越多...好神奇
没有说问题,goJhou也不好帮呀~
大神,帮帮我!
不客气
谢谢分享,大佬
慢慢的都是干货呀,进来学习啦~
谢谢分享
好人