RASA1.x中的填槽处理
填槽指在会话中从用户处收集完成任务所需的信息。
如果需要连续收集多条信息,可以创建一个FormAction。FormAction中含有一个循环的逻辑来询问用户所需的槽值。
配置
Form在domain文件中定义:
使用Form则需要在config文件中引入FormPolicy。
FormPolicy是MemoizationPolicy的一个扩展,负责填槽。
当FormAction被调用后,FormPolicy会继续预测后序应该采取的FormAction,直至所有槽被填满。
基础的填槽方式
一个基础的填槽方式是在story中定义一个填槽的happy path,如下所示:
“happy path”指询问用户信息后,用户无打断的回复被问信息,此处则是无打断的完成填槽。
在上面的story配置中,意图request_restaurant对应的动作是restaurant_form.
form{“name”:”restaurant_form”}激活了定义好的表单,而form{“name”:”null”}关闭了表单。
关于动作restaurant_form,需要定义三个方法:
(1)def name(...) -> Text 用于get动作名称;
(2)def required_slots(...) -> List[Text] 用于get需要被填的槽名称列表
(3)def submit(…) -> List[Dist] 用于槽填满后进行后续处理,比如调用查询餐厅的API
在表单激活期间FormPolicy连续预测FormAction,每次FormAction被调用都会通过utter_ask_{slot_name}询问用户一个未填槽的信息。
每个槽都应当在domain文件中设置对应的utter_ask_{slot_name}。
以上就是最基础的填槽方式,更复杂的方式可以参照unhappy path的使用。
定制的槽映射
在默认的情况下,槽只会被用户输入里与其名称相同的实体所填充。
若我们想以其他方式(如用户选择或用户直接输入)来填槽,可以借助slot_mappings方法来实现。
例如下图中,在slot_mappings方法中使用from_entity和from_intent两种方式填充outdoor_seating。
槽值验证
从用户输入中提取到槽值后,会对值进行验证。默认情况下验证只发生在用户输入后执行form action的时候。
同时,可以通过定义validate_{slot-name}方法来实现自定义的槽值验证,默认只会验证槽值是否成功提取。
有条件的填槽逻辑
当我们不满足于简单的填槽逻辑时,可以借助required_slots()方法来实现自定义的条件逻辑,比如下图中根据cuisine槽的值是否时greek做了条件逻辑。
RASA2.x中的填槽处理
前面我介绍了RASA1.x中的填槽处理,在RASA2.x中填槽处理则主要有以下几点不同。
Policy配置
首先RASA2.x中填槽不再基于FormPolicy,取而代之的是RulePolicy,我们需要在config文件中启用它。
Form的激活和关闭
在RASA1.x中,表单的激活和关闭在story进行定义。而在RASA2.x中,还可以在rule中定义。
激活:
关闭:
槽值映射
RASA2.x可以在表单定义中配置槽值映射的方法。
这里的type指的是slot mapping的方式,在1.x中默认是from_entity。
from_entity是通过将用户输入中的实体赋予同名的槽来实现填槽的。
当实体和槽的对应关系不唯一时,会放弃该实体。
如果需要避免这种情况,可以使用附加role信息使若干重名的槽具有不同角色来加以区分。
除了按实体填槽的方法以外,还有按用户输入填槽(from_text)、按用户意图填槽(from_intent、from_trigger_intent)的方法。
处理打断
RASA2.x的RulePolicy可以定义active_loop,在active_loop中我们可以处理打断:
在上面的例子中展示了闲聊打断的处理。
放弃填槽
当用户在填槽过程中意图改变,不想再继续下去,可以利用action_deactivate_loop动作来停止表单并重置槽值。
总结
在2.x中一些1.x中需要通过函数定义的功能被简化成配置,使用起来更加方便灵活。