本文继续围绕工业级业务对话平台和框架Rasa 的Interactive Learning来阐述如何定位bug,以及如何解决bug,结合实际案例进行详细分析。
一、通过Rasa Interactive Learning发现及解决对话机器人的Bugs案例实战
- Rasa对话流程可视化及动态更新(Rasa Visualization)
首先看一下这个自定义action,它的用途是当用户输入一个地点时,会把这个地点存在一个slot里,后面再和用户输入的新地点比较时间差异(时区不同引起的差异),在run方法里首先获取entity “place”的值:
如果没有获取到当前输入的地点(current_place)或者根据输入的地点不能获取到时区(tz_string),则对话机器人发消息提示用户:
接下来提示用户对话机器人会记住用户输入的地点,需要注意的是从用户输入中提取的entity “place”的值是通过触发event SlotSet来设置到slot “location”中的,而不是通过domain文件里定义的slot mapping这种方式来把entity的值映射为slot的值。在企业级对话机器人开发场景中,大多数情况都是使用事件驱动的自定义代码的方式来设置slot的值。
ActionTimeDifference的代码如下,在方法run中,首先会从tracker中获取从最新用户输入中提取的entity “place”的值,即”amsterdam”来赋值给”timezone_to”,然后再从tracker中获取slot “location”的值,即前面执行ActionRememberWhere的run方法所设置的slot的值”seattle”来赋值给”timezone_in”:
对两个时间值根据时区进行比较,计算出差值:
启动rasa action server,action endpoint的配置是在endpoints.yml文件里:
启动interactive learning模式,可以看到Rasa server成功启动并运行:
点击上面显示的visualization.html链接可以跳转到这个可视化页面:
这时可以看到触发了action_session_start事件,对话机器人等待用户输入。
输入:Hello,根据对话机器人反馈回答”Yes”,获得如下对话信息,当前的slot “location”没有值:
继续回答”Yes”来触发action “utter_greet”,获得的信息如下:
这时再次刷新可视化页面,内容已经被动态更新:
2. Rasa Interactive Learning定位Slot的Bug及解决方案
继续输入对话信息:I live in seattle,然后对话机器人解析intent为”where_i_live”并且提取了entity信息,确认正确后输入”Yes”,产出以下对话信息,这时可以看到slot “location”的值已经被设置为”seattle”:
再次刷新可视化页面,内容已经动态更新:
这时等待执行的action为”action_remember_where”,输入”Yes”执行后输出信息如下,需要注意的是有两条slot设置信息,第1条来自于domain文件里的slot mapping引发的设置,第2条则是由run方法执行后返回的SlotSet事件触发引起的slot设置:
这时再次刷新可视化页面,可以看到内容已经动态更新:
继续输入对话信息:what is the time difference between amsterdam,然后对话机器人给出intent “inquire_time_difference”和entity提取信息,然后输入”Yes”继续:
这时输出下面的对话信息,可以看到slot “location”的值已经被设置为” amsterdam”,表示之前的slot值”seattle”已经被覆盖,但是后续action “action_time_difference”还没有被执行,这显然是不符合逻辑,这就是bug:
再次刷新可视化页面,内容动态更新如下:
继续输入”Yes”来执行action “action_time_difference”,由于在action被执行前tracker中slot “location”的值已经覆写原先的”seattle”而变成了”amsterdam”,当这个action执行时用户输入了”amsterdam”,这就造成了两个slot的值都为” amsterdam”,所以进行时间比较时必然不会有差异,可以看到下面系统返回的结果显示”There is a 0H time difference”:
为了解决这个bug,一种方案是针对特定的intent禁用自动slot mapping机制。首先看一下Rasa官方文档提供的slot mapping的样例,可以看到有”not_intent”这样的设置,这个设置表示包含在”not_intent”里面的intents所相关的entities不会通过slot mapping的方式被自动映射到slots:
修改domain文件里对应的slot mapping设置,添加”not_intent”:
CTRL+C之后选择”Start Fresh”来退出当前对话并启动一个新的对话:
再次输入信息:I live in seattle:
输入”Yes”继续对话,则输出以下信息,这时slot “location”的值为”seattle”:
再次刷新可视化页面,内容更新如下:
再次输入信息:what is the time difference between amsterdam,然后对话机器人给出intent “inquire_time_difference”和entity提取信息:
然后输入”Yes”继续,这时slot “location”的值被设置为”amsterdam”:
说明刚才在slot mapping中添加的”not_intent”设置没有生效,这是因为没有进行训练,所以首先需要退出对话并运行命令rasa train进行训练:
训练完成后再次进入interactive learning模式:
再次输入信息:what is the time difference between amsterdam,然后对话机器人给出intent “inquire_time_difference”和entity提取信息:
这时slot “location”的值仍然是”seattle”,表明slot mapping的配置修改生效了。
再次运行action后得到了期望的两个地点的时间差异结果: