前言
最近在看一些基于如bot framework这样的平台搭建个性化的聊天机器人的资料,看的不多也不深,写下来谈一点自己的理解,主要是关于整个流程尤其是上下文设计的一些思考。这里尤其想感谢下一位作者的分享,我也是在看过他对bot framework的一些阐述后才能不那么肤浅的去看这个话题,所以也参考了许多他文章中的见解。参考链接如下:
谈 Bot Framework(以Facebook的wit.ai为例)
谈 Bot Framework 中的上下文(Contexts)设计
概述
1. Bot Framework
Bot Framework是微软开发的一款可让任何人制作自己的聊天机器人,按其自己的说法,或者说更深入的应该理解为“一个用于搭建、链接、测试、和部署智能机器人的平台”。用户可以在这个平台上,在模式上通过其定义好的规范和组件来搭建聊天(或会话)机器人,在内容上可以个性化的定制,面向个性化应用提供服务。
目前国内国外有很多这种聊天机器人搭建平台,比如微软的Bot Framework、Facebook的wit.ai、Google的api.ai、阿里的云小蜜和百度的dueros等等。
2. Frame-based chatbot
解释frame-based chatbot之前,先提两个概念:QA system和Dialog system/chatbot。
按照阿里对问题的分类,可以分为三类:
问答型:特点是依托结构化程度高且关联性高的领域知识,针对问题,返回知识作为答案。
任务型:特点是面向具体任务,同样依托领域知识的概念,每个任务负责独立的业务流程,任务之间相对互斥性强
闲聊型:特点是不是面向具体目标,语义意图不明确,领域不局限
两种system概念根据具体的目标和问题分类进行区分。QA system(问答系统)主要针对解决问答型问题,而Dialog system/chatbot(对话系统/聊天机器人)针对解决任务型和闲聊型问题。再具体的说,QA system关注单轮系统对用户query的response,而相比之下chatbot更加关注单轮的上下文以及多轮对话的需求。
在两种系统内,又分别按技术路线细分。比如QA system可分为ir-based(基于检索)和knowledge-based(基于大规模结构化知识库,比如知识图谱);Dialog system/chatbot也可分为rule-based(基于规则)、ir-based和frame-based等。
frame-based直译过来是基于框架,其实指的是主要通过槽位填充的方式理解intent(用户意图),然后解决会话需求的会话机器人。它针对每个intent定义一个frame,作为以槽位填充为主要目的的会话流程的模式,如针对用户订机票这个intent的frame样例:
frame主要内容为field和prompt。field定义了该intent需要填充的slot(比如订机票的slot为origin、destination和departdate)和每个slot对应的prompt;prompt为提示话术,主要是系统为了填充slot的提示语句,具体可分为针对每一个slot的提问prompt、对识别的slot值追加的confirm prompt以及在用户无输入或系统无法识别时的系统默认prompt。当用户intent产生时,系统可以根据frame定义的模式执行操作。
对整个流程尤其是context的一些理解
frame-based chatbot在会话流程中按顺序主要完成三个任务:识别domain→识别intent→填充slot
识别domain指识别识别会话所在领域,使用相应领域的知识做知识库,比如订机票这个任务属于“出行助手”(打个比方)领域;识别intent指用户意图的识别,具体做什么任务,比如“订机票”;填充slot不用解释,对origin、destination和departdate三个slot通过会话进行填充,最终按识别的意图执行任务。他们几个的关系可以表示为:
一个domain对应多个intent,每个intent对应一个frame
同一domain下或者是可继承(上下文可继承)的intent间有时会共享相同的slot,比如订飞机票和订火车票共享“出发地”、“目的地”和“出发时间”,所以intent和slot是多对多的关系。
本文有一些不同于参考文章的在于对context和lifespan的理解:
上图展示了整个会话从识别domain到execute的流程。对于context的意义,我很认同参考文章中“作为信号,影响 Intent 的识别”和“作为载体,存储已填写的 Parameter Value”两个作用。但我认为,可以将整个会话的context细分为两种,一种是父context,即图中红框表示的,从识别了domain开始,父context即开始生命周期,存储所有的intent的slot和value信息,无论是在同一个intent下对slot的删改还是在可继承的intent之间的场景转换,同名slot的value是共享的;另一种是子context,即通常framework平台中所描述的intent之间的inputContext和outputContext,用于识别intent或者是slot的继承,我认为,子context中存储的实际上是slot的key信息,即在intent下所需要填充的slot列表,在场景切换时,不断更新或继承列表中的key,在确认了所有intent后直接去读取存储在父context中的value值即可。这样的话,我们不需要事先定义context的生效轮数(lifespan),只要在父context下,所有场景都可以访问或者说继承到已填充过的slot value。当遇到不可继承的场景切换或更改domain时,直接清空父context信息。这种intent间共享slot值也对应了之前所说的intent和slot多对多的关系。
总之,对应于context的两种意义,父context作为载体,存储已填写的slot value;子context(input/output)有时作为信号,影响intent的识别,有时作为载体,存储intent所需的slot的key。
基于dueros搭建样例
笔者尝试了下利用dueros搭建一个简单的聊天机器人demo。具体的操作不赘述,dueros官方文档写得很详细,主要介绍下整个流程和之前讲的会话流程对应信息。
定义技能名称:即定义domain
定义意图:定义domain下的intent
定义槽位:其实是在定义intent的frame,包括slot和prompt。
至于词典和常用表达的训练是用于slot信息识别
定义意图确认话术(补全frame中的reimport,confirmImport)
以上就是基本的定义流程,然后当会话开始时,按照模式进行slot填充最后执行
以上只是个人的一些理解,望批评指正。