🚀 原文地址:
故事是训练数据中的一种,它用于训练机器人的对话管理模型,并在未知对话场景下进行回复。
1. 格式化
故事是用户和机器人之间会话的一种特定格式表示,在故事中用户的输入将被表征为意图或实体,而机器人的回复和动作则被表示为动作的名称。
Rasa 中故事采用以下格式来表示对话:
stories:
- story: collect restaurant booking info # name of the story - just for debugging
steps:
- intent: greet # user message with no entities
- action: utter_ask_howcanhelp
- intent: inform # user message with entities
entities:
- location: "rome"
- price: "cheap"
- action: utter_on_it # action that the bot should execute
- action: utter_ask_cuisine
- intent: inform
entities:
- cuisine: "spanish"
- action: utter_ask_num_people
1.1 用户消息
在编写故事时,你不必要处理用户发送消息中的特定内容。相反地,我们可以充分利用 NLU 管道的输出,它支持仅仅使用意图和实体来表示所有用户可能发送表示相同事情的消息。
这里包含实体非常重要,因为策略将基于意图和实体的组合来学习预测下一个动作,当然你也可以在 Rasa 中使用 use_entities
属性来改变这一行为。
1.2 动作
机器人执行的操作以及响应都应该列在故事中 action
键下,同时我们也可以在领域的谷故事中所定义的响应来作为动作。同样地,你也可以在领域文件中向 actions
列表添加自定义动作的名称,从而让故事调用自定义动作。
1.3 事件
在训练过程中,Rasa 并不会调用 Action Server,这意味着机器人对话管理模型并不知道自定义动作将返回哪些事件。因此,故事(例如,设置插槽或者激活/停用表单)不得不被明确地被编写在故事中。
1)插槽事件
插槽事件是在定义故事中 slot_was_set
下,如果插槽设置在自定义动作内,请在自定义动作被调用之后,立即添加 slot_was_set
事件。
如果你的自定义操作将槽值重置为 None
,那么对应的事件将如下所示:
stories:
- story: set slot to none
steps:
# ... other story steps
- action: my_custom_action
- slot_was_set:
- my_slot: null
2)表单事件
在处理故事中的表单时,有三种类型的事件还请牢记:
- 表单操作事件(例如,
action: restaurant_from
)是在第一次启用表单时的开头,同时也用于处于活跃状态的表单恢复操作时发挥作用。 - 表单激活事件(例如,
action_loop: restaurant_from
)是在第一个表单操作事件之后起效。 - 表单停用事件(例如,
action_loop: null
)用于停用表单。
:::info 💡 为了避免忘记添加事件的缺点,推荐使用交互式学习的方式来编写故事 :::
2. 检查点和“或”语句
之前有提到过,关于检查点和“或”语句应该谨慎使用,还有一个更好的方式来达到你想要的目的,那就是使用 Rules
或者 ResponseSelector
。
2.1 检查点
我们可以使用检查点来模块化或简化训练数据,但是不要过度使用它们。使用大量检查点会使得示例故事变得难以理解,并且会减慢训练速度。
以下是包含检查点的故事示例:
stories:
- story: beginning of flow
steps:
- intent: greet
- action: action_ask_user_question
- checkpoint: check_asked_question
- story: handle user affirm
steps:
- checkpoint: check_asked_question
- intent: affirm
- action: action_handle_affirmation
- checkpoint: check_flow_finished
- story: handle user deny
steps:
- checkpoint: check_asked_question
- intent: deny
- action: action_handle_denial
- checkpoint: check_flow_finished
- story: finish flow
steps:
- checkpoint: check_flow_finished
- intent: goodbye
- action: utter_goodbye
:::info
📑 注意
——————————
与常规故事不同,检查点不限于从用户输入开始。只要在主要故事的正确点插入检查点,第一个事件也可以是自定义操作或响应。
:::
2.2 或语句
另外一种编写较短故事或以相同方式处理多个意图或插槽的方法是使用or
语句。例如,如果要求用户确认某事,并且希望以相同的方式对待affirm
和thankyou
意图。下面的故事会在训练时转换成 2 个故事:
stories:
- story:
steps:
- action: utter_ask_confirm
- or:
- intent: affirm
- intent: thankyou
- action: action_handle_affirmation
我们还可以将or
语句与插槽事件一起使用,下面示例表示故事需要设置name
插槽,并且槽值需要为joe
或bob
:
stories:
- story:
steps:
- intent: greet
- action: utter_greet
- intent: tell_name
- or:
- slot_was_set:
- name: joe
- slot_was_set:
- name: bob
or
语句可能很有用,但如果使用很多,我们最好重构领域或意图。过度使用or
语句会减慢训练速度。
3. 测试对话
测试对话格式是一种将 NLU 数据和故事合并到一个文件中进行评估的格式。
:::warning
😈 仅测试
————————
这种格式仅用于测试,不能用于训练。
:::
4. 端到端训练
:::info
💡 2.2版本新特性
——————————
端到端训练目前还是一项实验性功能。
:::
通过端到端训练,我们不必处理由 NLU 管道中所提取消息的特定意图,或领域文件中单独的utter_
响应。相反地,我们可以直接在故事中包含用户消息或机器人响应的文本。
我们可以将端到端格式的训练数据与具有特定意图和操作的标记数据进行混合:故事可以具备一些由意图或操作定义的步骤,以及由用户或机器人话语直接定义的直接步骤。
我们称其为端到端训练,因为策略可以1使用和预测实际文本。对于端到端的用户输入,由 NLU 管道分类的意图和提取的实体将被忽略。
目前只有RulePolicy
和TEDPolicy
允许端到端训练:
RulePolicy
在预测期间使用简单的字符串匹配,也就是说,基于用户文本的规则只有在用户文本字符串和预测期间输入相同时才会匹配。TEDPolicy
通过额外的神经网络传递用户文本,从而创建文本的隐藏表示。为了获得稳健的性能,我们需要提供足够的训练故事,来为任何端到端对话轮次捕获各种用户文本。
训练 Rasa 策略来选择下一次话语,创建utter_
响应唯一区别是TEDPolicy
如何对机器人话语进行特征化。在utter_
动作的情况下,TEDPolicy
只看到动作的名称,而如果使用bot
键提供的实际话语,TEDPolicy
将根据 NLU 配置将其特征化为文本输入。如果在稍有不同的情况下出现了累死的话语,这会很有帮助。然而,这也会使得事情变得更难学习,因为不同的话语具有相似的文本,这一事实将使得TEDPolicy更容易混淆这些话语。