🚀 原文地址:
领域定义了机器人操作的宇宙,它指定了机器人应该知晓的意图、实体、插槽、响应、表单和操作。同样,它还定义了会话的配置信息。
以下是完整的域示例:
version: "3.0"intents:- affirm- deny- greet- thankyou- goodbye- search_concerts- search_venues- compare_reviews- bot_challenge- nlu_fallback- how_to_get_startedentities:- nameslots:concerts:type: listinfluence_conversation: falsemappings:- type: customvenues:type: listinfluence_conversation: falsemappings:- type: customlikes_music:type: boolinfluence_conversation: truemappings:- type: customresponses:utter_greet:- text: "Hey there!"utter_goodbye:- text: "Goodbye :("utter_default:- text: "Sorry, I didn't get that, can you rephrase?"utter_youarewelcome:- text: "You're very welcome."utter_iamabot:- text: "I am a bot, powered by Rasa."utter_get_started:- text: "I can help you find concerts and venues. Do you like music?"utter_awesome:- text: "Awesome! You can ask me things like \"Find me some concerts\" or \"What's a good venue\""actions:- action_search_concerts- action_search_venues- action_show_concert_reviews- action_show_venue_reviews- action_set_music_preferencesession_config:session_expiration_time: 60 # value in minutescarry_over_slots_to_new_session: true
1. 多个领域文件
领域可以定义在单个 YAML 文件中,也可以拆分为多个文件。当拆分为多个文件时,领域内容将会被自动读取并整合在一起,你可以通过以下命令行接口,来基于多个领域文件训练一个模型:
$ rasa train --domain path_to_domain_directory
2. 意图
在域文件中,intents 键下应该列出在 NLU 数据和对话训练数据中所有使用到的意图。
2.1 忽略某些意图的实体
如果需要忽略某些意图的所有实体,我们可以在域文件中添加 use_entities: [] 参数:
intents:- greet:use_entities: []
如果要忽略某些实体或者明确仅考虑某些实体,我们可以采用如下方式:
intents:- greet:use_entities:- name- first_nameignore_entities:- location- age
这些意图所排除的实体将不会被特征化,因为它们也不会影响下一个动作的预测。当存在这样一个意图,我们并不关心实体被提取时,使用 ignore_entities 非常有用。
如果我们所列出的意图并没有该参数时,实体将会正常特征化。
:::info
💡 如果不希望实体影响下个动作的预测,请为同名的插槽设置 influence_conversation: false。
:::
3. 实体
通过 NLU 管道中实体提取器所提取的实体,我们将其放置在 entities 部分。
例如:
entities:- PERSON # entity extracted by SpacyEntityExtractor- time # entity extracted by DucklingEntityExtractor- membership_type # custom entity extracted by DIETClassifier- priority # custom entity extracted by DIETClassifier
如果使用了实体角色和分组的功能,我们还需要列出实体的角色和分组:
entities:- city: # custom entity extracted by DIETClassifierroles:- from- to- topping: # custom entity extracted by DIETClassifiergroups:- 1- 2- size: # custom entity extracted by DIETClassifiergroups:- 1- 2
4. 插槽
插槽相当于机器人的记忆,将用户提供的信息通过键值对的方式来存储(例如家乡和城市),以及外部世界所收集到的信息(例如从数据中查询的结果)。
插槽是域文件中定义在 slots 部分,包含槽名、类型、是否影响以及如何影响机器人的行为。以下示例中,定义了 slot_name 的插槽,其类型为 text,以及预定义插槽映射 from_entity。
slots:slot_name:type: textmappings:- type: from_entityentity: entity_name
4.1 插槽和对话行为
可以设定 influence_conversation 属性来指定插槽是否会话产生影响。如果你想将信息存储在插槽内而不影响对话,在定义插槽时通过 influence_conversation: false 来设定。
下面的示例定义了一个用于存储用户年龄的 age 插槽,但是该插槽并不会影响对话的流程。这意味着机器人在预测下一次动作时,都将会忽略 age 槽中的值。
slots:age:type: text# this slot will not influence the predictions# of the dialogue policiesinfluence_conversation: false
当定一个插槽时,如果你省略了 influence_conversation 或者将其设置为 true,除非该插槽的类型为 any,否则将会影响下一个动作的预测。由此可知,插槽是否会影响对话将取决于其类型。
下面示例中定义了一个影响会话的插槽 home_city,文本类型的插槽将根据槽值影响机器人的行为。值得注意的是,文本插槽中的值不会有区别,例如 New York or Hong Kong 或者 Bangalore。
slots:# this slot will influence the conversation depending on# whether the slot is set or nothome_city:type: textinfluence_conversation: true
例如,考虑这两种输入:“What is the weather like?”和“What is the weather like in Bangalore?”,对话将基于 home_city 插槽是否设置,根据 NLU 自动决定产生分歧。
- 如果插槽已经设置,机器人将预测
action_forecast动作。 - 如果没有设置插槽,则需要在预测天气之前,获取到
home_city的信息。
slots:# this slot will influence the conversation depending on# whether the slot is set or nothome_city:type: textinfluence_conversation: true
4.2 插槽类型
1)文本类型
当插槽的类型为 text 时,它用于存储文本信息。示例如下:
slots:cuisine:type: textmappings:- type: from_entityentity: cuisine
如果 influence_conversation 设置为 true,机器人的行为是否会改变取决于插槽是否设置。不同的文本并不会进一步影响会话,这意味着下面示例中的两个故事是一样的:
stories:- story: French cuisinesteps:- intent: inform- slot_was_set:- cuisine: french- story: Vietnamese cuisinesteps:- intent: inform- slot_was_set:- cuisine: vietnamese
2)布尔类型
当插槽的类型为 bool 时,它用于存储 true 或者 false 值。示例如下:
slots:is_authenticated:type: boolmappings:- type: custom
如果 influence_conversation 设置为 true,机器人的行为是否会改变取决于插槽是否为空、true 或者 false。值得注意的是,如果 bool 插槽为空时,与插槽设置为 false 影响会话方式是不同的。
3)类别类型
当插槽的类型为 categorical 时,它用于存储 N 个选项中一个值。示例如下:
slots:risk_level:type: categoricalvalues:- low- medium- highmappings:- type: custom
如果 influence_conversation 设置为 true,机器人的行为是否会改变取决于插槽的值。这意味着上述示例中插槽中的值是 low、medium、high 哪一个,机器人的行为也会有所不同。
对于没有处在列表中的值,Rasa 会设置一个默认值 __other__ 来进行响应。值得注意的是,__other__ 并不需要我们去定义,如果定义了 __other__ 的话,所有未知的值都将映射到该值上。事实上,不设置也是相同的效果。
4)浮点类型
当插槽的类型为 float 时,它用于存储真实的数字,其中 max_value 默认值为 1.0,min_value 默认值为 0.0。示例如下:
slots:temperature:type: floatmin_value: -100.0max_value: 100.0mappings:- type: custom
如果 influence_conversation 设置为 true,机器人的行为是否会改变取决于插槽的值。如果槽值处于最大最小值中间,那么具体值将会被使用。所有小于最小值的值,将会被当做最小值来处理,所有大于最大值的值,将会被当做最大值来处理。因为,如果将最大值设置为 1,那么对于 2 和 3.5 的槽值将没有区别。
5)列表类型
当插槽的类型为 list 时,它用于存储列表值。示例如下:
slots:shopping_items:type: listmappings:- type: from_entityentity: shopping_item
如果 influence_conversation 设置为 true,机器人的行为是否会改变取决于插槽是否为空。槽值中列表的长度并不会影响对话,它仅仅与列表长度为 0 或者非 0 有关。
6)任何类型
当插槽的类型为 any 时,它用于存储任意值,也就是说可以是任意类型,例如字典或者列表。示例如下:
slots:shopping_items:type: anymappings:- type: custom
如果插槽的类型为 any,那么在会话过程中总是被忽略的,并且此类型的插槽并不能设置 influence_conversation 为 true。
7)自定义类型
可能你的订餐系统仅能处理最多 6 人的预定,我们通常希望槽值可以影响下一个选中的动作,而不仅仅是指定的操作,
这种情况下我们就可以通过自定义一个插槽类来实现次功能。
下面示例中我们定一个 NumberOfPeopleSlot 的插槽类,它的目的是将槽值转换为一个向量,以便 Rasa 机器学习模型可以对其进行处理。NumerOfPeopleSlot 有 3 种可能的值,均使用长度为 2 的向量来进行标识:
(0, 0):还未设置(1, 0):在 1 到 6 之间(0, 1):大于 6 人
from rasa.shared.core.slots import Slotclass NumberOfPeopleSlot(Slot):def feature_dimensionality(self):return 2def as_feature(self):r = [0.0] * self.feature_dimensionality()if self.value:if self.value <= 6:r[0] = 1.0else:r[1] = 1.0return r
通常我们会将自定义插槽类作为单独一个模块,还不是和自定义动作放在一起。
Rasa 通过 addons.my_custom_slots.NumberOfPeopleSlot 来引用自定义插槽,具体如下:
slots:people:type: addons.my_custom_slots.NumberOfPeopleSlotinfluence_conversation: truemappings:- type: custom
按照上述配置好之后,Rasa 就可以使用自定义插槽类了,接下来根据 people 插槽的值添加不同训练故事。下面示例中,我们添加了 2 个故事,一个是人数在 1-6之间,另一个是大于 6 人。我们可以在这些范围内选择任意值来放置在故事中,因为他们都采用相同的方式来特征化。
stories:- story: collecting table infosteps:# ... other story steps- intent: informentities:- people: 3- slot_was_set:- people: 3- action: action_book_table- story: too many people at the tablesteps:# ... other story steps- intent: informentities:- people: 9- slot_was_set:- people: 9- action: action_explain_table_limit
4.3 插槽映射
1)from_entity
2)from_entity的唯一映射匹配
3)from_text
from_text 映射将使用用户最后说的文本内容来填充 slot_name 插槽。如果 intent_name 为 None 的话,那么无论意图的名称如何,该插槽都会被填充。否则,只有当意图是 intent_name 时才会填充插槽。
如果消息的意图是 excluded_intent,则插槽映射将不会起作用。
slots:slot_name:type: textmappings:- type: from_textintent: intent_namenot_intent: excluded_intent
:::info
💡 如果在使用 from_text 插槽映射时希望保持 Rasa 2.x 表单的功能,我们必须使用定义了 active_loop 和 requested_slot 的映射条件。
:::
4)from_intent
如果用户的意图是 intent_name,那么 from_intent 映射将使用 my_value 来填充 slot_name 插槽。如果我们没有指定 intent 参数,那么如论消息的意图如何,只要意图未在 not_intent 参数下列出,插槽便会对其进行映射。
以为为常用的参数:
- value:必须提供,用来填充
slot_name插槽的值 - intent:可选项,只有在该预测意图时应用插槽映射
- not_intent:可选项,当在预测该意图时不应用插槽映射
slots:slot_name:type: anymappings:- type: from_intentvalue: my_valueintent: intent_namenot_intent: excluded_intent
5)from_trigger_intent
如果一个表单被带有 intent_name 意图的用户消息所激活,那么 from_trigger_intent 映射将使用 my_value 来填充 slot_name 插槽。如果消息的意图列在 excluded_intent 下,那么插槽映射将不会起作用。
slots:slot_name:type: anymappings:- type: from_trigger_intentvalue: my_valueintent: intent_namenot_intent: excluded_intent
4.4 映射条件
要在表单的上下文中应用插槽映射,请在插槽映射的 conditions 键中指定表单的名称,在 active_loop 键下列出条件映射所适用的表单名称。
条件映射也可以包含 requested_slot 的名称,如果 requesed_slot 并未有提及,无论表单请求的是哪个插槽,当相关信息被提取时插槽就会被设置。
slots:slot_name:type: textmappings:- type: from_textintent: intent_nameconditions:- active_loop: your_formrequested_slot: slot_name- active_loop: another_form
:::info
💡 如果插槽映射中并未包含 conditions,那么无论表单是否处于活跃状态,插槽映射都将起作用。只要插槽被列在表单的 requested_slot 中,当表单激活时,如果插槽为空的话,那么表单会提示输入该插槽。
:::
4.5 自定义插槽映射
当 Rasa 提供的预插槽映射都不适用于你的场景,我们通过插槽验证动作来自定义插槽映射。值得注意的是,插槽映射的类型必须为 custom,例如
slots:day_of_week:type: textmappings:- type: customaction: action_calculate_day_of_week
你还可以通过列出动作的类型而不必要指定具体动作,使用 custom 插槽映射来列出所有插槽,这些插槽将会被任意自定义动作所填充。例如:
slots:handoff_completed:type: booleanmappings:- type: custom
插槽并不会在每一个用户轮次进行更新,仅在自定义动作预测返回的时 SlotSet 事件时才会更新。
4.6 初始化插槽值
我们可以在域文件中给插槽提供一个初始值:
slots:num_fallbacks:type: floatinitial_value: 0mappings:- type: custom
5. 响应
6. 表单
7. 动作
8. 会话配置
会话表示的是机器人与用户之间的对话,通常它有 3 种开始形式:
- 用户开始与机器人进行对话
- 在可配置的非活动时间后,用户发送了信息
- 使用
/session_start意图消息来启动一次手动会话
我们可以在域文件中通过添加 session_config 键,来定义出发新会话时的非活动时长。
可配置的参数有:
session_expiration_time:定义了新会话开始后的非活动时间(单位:分钟)。carry_over_slots_to_new_session:决定是否将现有设置插槽转移到新会话。
默认 session 配置如下:
9. 配置
在领域文件中的 config 键可配置 store_entities_as_slots 参数,此参数仅在阅读故事时作为上下文使用,同时 Rasa 会将它们传递给跟踪器。如果该参数被设置为 true,且当前故事中存在适用的实体,该参数将从实体中隐式设置插槽。因此,此插槽将会跳过在故事中手动添加显式 slot_was_set 步骤。默认情况下,该特性是打开的。同样地,我们也可以通过将 store_entities_as_slots 参数设置为 false 来关闭此功能。
config:store_entities_as_slots: false
