目录
完整示例:
version: "3.1"
intents:
- affirm
- deny
- greet
- thankyou
- goodbye
- search_concerts
- search_venues
- compare_reviews
- bot_challenge
- nlu_fallback
- how_to_get_started
entities:
- name
slots:
concerts:
type: list
influence_conversation: false
mappings:
- type: custom
venues:
type: list
influence_conversation: false
mappings:
- type: custom
likes_music:
type: bool
influence_conversation: true
mappings:
- type: custom
responses:
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_preference
session_config:
session_expiration_time: 60 # value in minutes
carry_over_slots_to_new_session: true
多个 Domain 文件
Domain 可以定义为单个 YAML 文件,也可以分割成一个目录中的多个文件。当分割成多个文件时,Domain 内容会被读取并自动合并在一起。
通过命令行界面,可以使用以下命令来训练训练具有拆分域文件的模型:
rasa train --domain path_to_domain_directory
Intents
Domain 文件中的 intents 键列出了 NLU 数据和对话训练数据中使用的所有意图
忽略某些意图的实体
如果要忽略某些意图的所有实体,可以在域文件中的意图中添加 use_entities: [] 参数,例如:
intents:
- greet:
use_entities: []
要忽略某些实体或明确仅考虑某些实体,您可以使用以下语法:
intents:
- greet:
use_entities:
- name
- first_name
- farewell:
ignore_entities:
- location
- age
- last_name
每个意图只能使用 use_entities 或 ignore_entities 两个中的一个。
被排除的实体将不会被特征化(可以理解为如果为指定的 intent 设置 ignore_entities,那么 ignore_entities 下面列出来的实体无论是否提取出来,都不会被特征化,不会影响意图分类的结果,也不会影响下一个动作的预测结果),当有一个意图,不关心某个被识别的实体,这非常有用。
如果你在 domain 文件中的意图列表中没有使用 use_entities 或 ignore_entities 参数,则实体将像平常一样被特征化。
你也可以通过将实体自身的 influence_conversation 标志设置为 false 来忽略所有意图的实体。
如果你在意图列表中没有使用该参数,并且没有为任何实体设置 influence_conversation 标志为 false,那么所有实体都将像平常一样被特征化。
如果您希望这些实体也不通过插槽影响动作预测,请为具有相同名称的插槽设置 influence_conversation: false 参数。
实体 entities
从 3.1 开始,可以在实体下使用 influence_conversation 标志。该标志可以设置为 false 以声明不应出于任何目的对实体进行特征化。它是一种简写语法,用于将实体添加到域中每个意图的 ignore_entities 列表中。该标志是可选的,默认行为保持不变。
entities 部分列出了 NLU pipeline 中任何实体提取器可以提取的所有实体。
例如:
entities:
- PERSON # entity extracted by SpacyEntityExtractor
- time # entity extracted by DucklingEntityExtractor
- membership_type # custom entity extracted by DIETClassifier
- priority # custom entity extracted by DIETClassifier
当使用多个 domain 文件时,实体可以在任何 domain 文件中指定,并且可以被任何 domain 文件中的任何意图使用或忽略。
如果您正在使用实体角色和组功能,您还需要在此部分中列出实体的角色和组。
例如:
entities:
- city: # custom entity extracted by DIETClassifier
roles:
- from
- to
- topping: # custom entity extracted by DIETClassifier
groups:
- 1
- 2
- size: # custom entity extracted by DIETClassifier
groups:
- 1
- 2
默认情况下,实体会影响动作预测。为了防止提取的实体影响特定意图的对话,您可以忽略特定意图的实体。要忽略所有意图的实体,而不必将其列在每个意图的 ignore_entities 标志下,您可以在实体下将标志 influence_conversation 设置为 false:
entities:
- location:
influence_conversation: false
此语法与将实体添加到 Domain 中每个意图的 ignore_entities 列表具有相同的效果。
显式设置 influence_conversation: true 不会改变任何行为。这是默认设置。
词槽 slots
slot 是你机器人的内存记忆。它们充当键值存储,可用于存储用户提供的信息(例如: city)以及收集的有关外部世界的信息(例如数据库查询的结果)。
插槽在 Domain 的 slots 部分中定义,包括它们的名称 name, 类型 type 以及它们是否影响助手的行为。以下示例定义了一个名称为“slot_name”的槽,类型为文本,预定义槽映射为 from_entity。
slots:
slot_name:
type: text
mappings:
- type: from_entity
entity: entity_name
词槽和对话行为
您可以使用 influence_conversation 属性指定一个 slot 是否影响对话的进行
如果您想在不影响对话的情况下将信息存储在槽中,请在定义槽时设置 influence_conversation: false。
以下示例定义了一个插槽 age,它将存储有关用户年龄的信息,但不会影响对话的流程。这意味着助手每次预测下一个动作时都会忽略槽的值。
slots:
age:
type: text
# this slot will not influence the predictions
# of the dialogue policies
influence_conversation: false
定义 slot 时,如果你省略 influence_conversation 或将其设置为 true,则该槽将影响下一个动作预测,除非它的槽类型为 any。插槽影响对话的方式将取决于其插槽类型。
以下示例定义了一个影响对话的插槽 home_city。text 类型的槽,将根据槽是否有值来影响助手的行为,文本槽的值是什么并不重要
slots:
# this slot will influence the conversation depending on
# whether the slot is set or not
home_city:
type: text
influence_conversation: true
槽类型 Slot Types
slot 类型 | 存储值的类型 | 例子 | 描述 |
text | 存储文本值 | slots: cuisine: type: text mappings: - type: from_entity entity: cuisine | 如果 influence_conversation 设置为 true,bot 的行为将根据 slot 是否设置而改变。不同的文本不会进一步影响对话。这意味着以下两个故事是相等的: stories: - story: French cuisine steps: - intent: inform - slot_was_set: - cuisine: french - story: Vietnamese cuisine steps: - intent: inform - slot_was_set: - cuisine: vietnamese |
bool | 存储 true 和 false | slots: is_authenticated: type: bool mappings: - type: custom | 如果 influence_conversation 属性设置为 true,则 bot 的行为将取决于 Slot 是否为空、设置为 true 或设置为 false。请注意,空的布尔类型 Slot 影响对话的方式与将 Slot 设置为 false 不同。 可以理解为 slot 有三种情况: null 表示空、值为 true、值为 false |
categorical | 分类槽,可以采用 N 个值之一的存储槽,也可以理解为是枚举槽 | slots: risk_level: type: categorical values: - low - medium - high mappings: - type: custom | 如果 influence_conversation 设置为 true,bot 的行为将根据槽的具体值而改变。这意味着 bot 的行为会根据 risk_level 这个 slot 的值而有所不同,具体取决于上例中插槽的值是 low、medium 还是high。 默认值 __other__ 会自动添加到用户定义的值中。所有遇到的未在插槽值中明确定义的值都映射到 __other__。 __other__ 不应用作用户定义的值;如果是,它仍将作为所有未见值映射到的默认值。 |
float | 用来存储实数 | slots: temperature: type: float min_value: -100.0 max_value: 100.0 mappings: - type: custom | 如果 influence_conversation 设置为 true,助手的行为将根据槽的值而改变。如果该值介于 min_value 和 max_value 之间,则使用数字的特定值。所有低于 min_value 的值都将被视为 min_value,所有高于 max_value 的值都将被视为 max_value。因此,如果 max_value 设置为 1,则插槽值 2 和 3.5 之间没有区别。 |
list | 存储列表 | slots: shopping_items: type: list mappings: - type: from_entity entity: shopping_item | 如果 influence_conversation 设置为 true,助手的行为将根据列表是否为空而改变。存储在槽中的列表的长度不影响对话。列表长度是零还是非零才重要。 应该在 NLU 示例中标记每个实体,例如: 我今天想买 [手机](shopping_items)、[口红](shopping_items)和 [杯子](shopping_items)餐厅。 |
any | 存储任意值 | slots: shopping_items: type: any mappings: - type: custom | any 类型的插槽在对话期间总是被忽略。不能将此插槽类型的属性 influence_conversation 设置为 true。如果要存储影响对话的自定义数据结构,请使用自定义插槽类型。 |
自定义插槽类型
在餐厅预订系统中,如果最多只能处理 6 人的预订。在这种情况下,希望插槽的值影响下一个选定的操作(而不仅仅是它是否已指定)。可以通过定义一个自定义槽类来做到这一点。
下面的代码定义了一个名为 NumberOfPeopleSlot 的自定义插槽类。特征化定义了这个插槽的值如何转换为向量,以便 Rasa 机器学习模型可以处理它。 NumberOfPeopleSlot 具有三个可能的“值”,可以用长度为 2 的向量表示。
from rasa.shared.core.slots import Slot
class NumberOfPeopleSlot(Slot):
def feature_dimensionality(self):
return 2
def as_feature(self):
r = [0.0] * self.feature_dimensionality()
if self.value:
if self.value <= 6:
r[0] = 1.0
else:
r[1] = 1.0
return r
您可以将自定义插槽类实现 为独立的 Python 模块,与自定义 action 代码分开。将自定义插槽的代码保存在名为“__init__.py”的空文件旁边的目录中,以便将其识别为 python 模块。然后,您可以通过模块路径引用自定义插槽类。
例如,假设您已将上面的代码保存在“addons/my_custom_slots.py”中,这是一个与您的机器人项目相关的目录:
└── rasa_bot
├── addons
│ ├── __init__.py
│ └── my_custom_slots.py
├── config.yml
├── credentials.yml
├── data
├── domain.yml
├── endpoints.yml
您的自定义插槽类型的模块路径是 addons.my_custom_slots.NumberOfPeopleSlot。 domain 文件中, 使用模块路径引用自定义插槽类型:
slots:
people:
type: addons.my_custom_slots.NumberOfPeopleSlot
influence_conversation: true
mappings:
- type: custom
现在您的自定义插槽类可以被 Rasa 使用,可以根据 people 插槽的 value 值, 写不同的故事。你可以为 people 的 value 在 1 到 6 之间的情况写一个故事,value 大于 6 写一个故事。您可以选择这些范围内的任何值来放入您的故事中,因为它们都以相同的方式进行特征化(请参阅上面的特征化表)
插槽映射 Slot Mappings
插槽映射是指的槽位通过何种渠道去填充,定义在 Domain 文件中的 slots 下面, slots 会列出所有的槽位,在每个对应的槽位下面,可以配置该槽位的 slot mapping, Rasa 预定义了四种 slot mapping, 除了 Rasa 预定义的,还可以自定义 slot mapping, 需要指定 slot mapping 的 type 指定为 custom。slot mapping 是可以指定多个的,按照在 Domain 中列出的顺序排优先级,顺序在前的优先填充
默认情况下, slot mapping 应用于每个用户消息,如果要使 slot mapping 仅在表单上下文使用,可以用 Mapping Conditions 来限制,下面会详细介绍。
也可以为插槽定义意图列表,使用 intent 和 not_intent (可选)
from_entity
从提取的实体中来填槽,需要的参数:
- entity: 表示填充该槽的实体
以下参数是可选的,可用于进一步指定何时应用映射:
- intent:仅在预测到此意图时才应用映射
- not_intent:预测到此意图时不应用映射
- role:仅当提取的实体具有此角色时才应用映射
- group:仅当提取的实体属于该组时才应用映射
entities:
- entity_name
slots:
slot_name:
type: any
mappings:
- type: from_entity
entity: entity_name
role: role_name
group: group name
intent: intent_name
not_intent: excluded_intent
唯一的 from_entity 映射匹配 Unique from_entity mapping matching
在表单上下文中,应用 from_entity 槽映射存在有意的限制。当表单处于活动状态时,仅当满足以下条件之一或多个时,才会应用 from_entity 槽映射:
- 具有 from_entity 映射的插槽刚刚被表单请求
- 当前活动表单的 required_slots 具有特定的 from_entity 映射,包括提取实体的所有属性(即实体名称、角色、组)。这称为表单的唯一实体映射。如果映射在 required_slots 列表中不唯一,则提取的实体将被忽略。
存在此限制是为了防止表单使用相同的提取实体值填充多个必需的槽。
例如,在下面的示例中,一个实体 date 唯一地设置槽 arrival_date,一个实体 city 具有 role : from 唯一地设置槽 departure_city 和一个具有 role: to 的实体 city 唯一地设置槽 arrival_city,因此它们可以用来拟合相应的插槽,即使没有请求这些插槽。
但是,没有 role 的实体 city 可以填充 departure_city 和 arrival_city 槽,具体取决于请求哪个槽,因此如果在请求槽 arrival_date 时提取实体 city ,表单将忽略它
slots:
departure_city:
type: text
mappings:
- type: from_entity
entity: city
role: from
- type: from_entity
entity: city
arrival_city:
type: text
mappings:
- type: from_entity
entity: city
role: to
- type: from_entity
entity: city
arrival_date:
type: any
mappings:
- type: from_entity
entity: date
forms:
your_form:
required_slots:
- departure_city
- arrival_city
- arrival_date
注意,唯一的 from_entity 映射约束不会阻止填充不在活动表单的 required_slots 中的插槽;这些映射将照常应用,无论映射的唯一性如何
from_text
from_text 映射将使用最后一个用户的文本来填充插槽 slot_name。如果 intent_name 为 None,则无论意图名称如何,都会填充槽。否则,只有当用户的意图是 intent_name 时才会填充槽。
如果用户的输入文本的意图是 excluded_intent,则 slot mapping 不生效,不会填充 slot_name 的槽值
slots:
slot_name:
type: text
mappings:
- type: from_text
intent: intent_name
not_intent: excluded_intent
from_intent
如果用户意图是 intent_name,则 from_intent 映射将使用值 my_value 填充插槽 slot_name。如果您选择不指定参数意图,则无论消息的意图如何,只要意图未在 not_intent 参数下列出,槽映射都将应用。
需要以下参数:
- value:填充槽slot_name的值
以下参数是可选的,可用于进一步指定何时应用映射:
- intent:仅在预测到此意图时才应用映射
- not_intent:预测到此意图时不应用映射
请注意,如果您选择不定义参数意图,则无论消息的意图如何,只要意图未在 not_intent 参数下列出,槽映射都将应用。
slots:
slot_name:
type: any
mappings:
- type: from_intent
value: my_value
intent: intent_name
not_intent: excluded_intent
from_trigger_intent
如果 form 表单由意图 intent_name 激活,则 from_trigger_intent 映射将使用值 my_value 填充插槽 slot_name。如果消息的意图是 excluded_intent,则槽映射将不适用
slots:
slot_name:
type: any
mappings:
- type: from_trigger_intent
value: my_value
intent: intent_name
not_intent: excluded_intent
Mapping Conditions
如果只想在 form 表单中应用 slot mapping (可以理解为填槽),请在 slot mapping 的 conditions 键中指定表单的名称。conditions 下面 active_loop 键是表单名称。
conditions 还可以包括 requested_slot 的名称。如果未提及 requested_slot,则在提取相关信息后将设置插槽,而不管表单请求的是哪个插槽。
slots:
slot_name:
type: text
mappings:
- type: from_text
intent: intent_name
conditions:
- active_loop: your_form
requested_slot: slot_name
- active_loop: another_form
如果 slot mapping 中不包含 conditions ,无论是否有任何表格处于活动状态,插槽映射都将适用。只要在表单的 required_slots 中列出了一个插槽,当表单被激活时,如果插槽为空,表单就会提示输入插槽。
Custom Slot Mappings
当没有预定义的slot mapping适用于您的用例时,您可以使用 slot validation actions 定义自定义slot mapping。您必须将此槽位映射定义为 custom 类型,例如:
slots:
day_of_week:
type: text
mappings:
- type: custom
action: action_calculate_day_of_week
您还可以使用自定义 slot mapping 来列出在对话过程中由任意自定义操作填充的插槽,方法是列出类型而不是特定操作。 例如:
slots:
handoff_completed:
type: boolean
mappings:
- type: custom
意思是任何自定义的 action 里面都可以指定该槽值,该槽位不会在每个用户轮次中更新,而是只有在预测到返回该槽位设置事件的自定义操作时才会更新。
设置初始槽值
您可以为域文件中的插槽提供初始值:
slots:
num_fallbacks:
type: float
initial_value: 0
mappings:
- type: custom
Responses
Responses 是发送消息给用户的操作,而不运行任何自定义代码或返回事件。这些响应可以直接在Domain 文件中的responses下定义,并可以包含诸如 buttons 和 attachments 附件等丰富的内容。
Forms
Forms 是一种特殊类型的操作,旨在帮助您的助手从用户那里收集信息。在 domain 文件中的 forms 下定义表单。如何定义,参考表单章节
Actions
action 是您的机器人实际可以执行的任务。例如,一个动作可以:
- 回复用户,
- 进行外部API调用,
- 查询数据库,或者
- 几乎任何任务!
所有自定义 action 都应列在您的 domain 文件中,除了Responses,Responses无需在actions下列出:因为它们已经在responses下列出:
选择哪些动作接受 Domain
需要再 endpoints.yml 中的 action_endpoint 启用 selective domain
# endpoints.yml
action_endpoint:
url: "http://localhost:5055/webhook" # URL to your action server
enable_selective_domain: true
启用自定义动作的 enable_selective_domain 后,Domain 将仅发送到明确声明需要 Domain 的自定义动作。继承自 rasa-sdk FormValidationAction 父类的自定义动作是此规则的例外,因为它们始终会收到 domain 。要指定一个动作是否需要 domain,请在domain.yml中的动作列表中添加{send_domain: true}到自定义动作中:
# domain.yml
actions:
- action_hello_world: {send_domain: True} # will receive domain
- action_calculate_mass_of_sun # will not receive domain
- validate_my_form # will receive domain
在这个例子中,我理解的应该是,如果 enable_selective_domain 设置为 true,那么只有 action_hello_world这个 action 能收到 domain 相关的信息,其他自定义 action 收不到, FormValidationAction 除外
Session configuration
会话表示助手和用户之间的对话。会话可以通过以下三种方式开始:
- 用户开始与助手交谈
- 在用户不活动一段时间后发送一条消息
- 使用/session_start触发手动会话开始
您可以在 Domain 文件中的 session_config 键下定义触发新会话的不活动时间。可用参数包括:
session_expiration_time定义在多少分钟的不活动时间后会开始一个新的会话。
carry_over_slots_to_new_session确定是否应将现有的设置槽位带入新会话。
默认的会话配置如下所示:
session_config:
session_expiration_time: 60 # value in minutes, 0 means infinitely long
carry_over_slots_to_new_session: true # set to false to forget slots between sessions
这意味着如果用户在60分钟的不活动时间后发送他们的第一条消息,则会触发一个新的会话,并且任何现有的槽位都将带入新会话。将session_expiration_time的值设置为0表示会话将不会结束(请注意,action_session_start动作仍将在对话的开始时触发)。
Config
在 Domain 文件中的 config 配置下,维护 store_entities_as_slots 参数。此参数仅在读取故事并将其转换为跟踪器的上下文中使用。如果将参数设置为True,则会导致如果故事中存在适用的实体,则会隐式设置槽位。当实体匹配 from_entity 槽位映射时,store_entities_as_slots 定义了实体值是否应放置在该槽位中。因此,此参数跳过了在故事中手动添加显式的slot_was_set步骤。默认情况下,此行为已开启。
您可以通过将store_entities_as_slots参数设置为false来关闭此功能:
config:
store_entities_as_slots: false
举个例子:
当 store_entities_as_slots: true 时,以下代码中的slot_was_set可以省略,Rasa 会自动的把 name实体 填充到 name槽位中:
- story: set name
steps:
- intent: ask_name
- action: utter_ask_name
- intent: inform_name
entities:
- name: "John"
- slot_was_set:
- name: "John"
- action: utter_confirm_name