2021-10-9
Domian
domian定义了机器人助手可操作的领域。在domain中可指定意图、实体、词槽、响应、表单和机器人应该知道的操作。并且还定义了会话session的配置。
下面是一个完整的domain示例
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
venues:
type: list
influence_conversation: false
likes_music:
type: bool
influence_conversation: true
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
Multiple Domian Files
domain可以定义为单个YAML文件,也可以跨目录中的多个文件进行分割。当跨越多个文件时,域内容将被读取并自动合并在一起。
使用命令行界面,你可以通过运行以下命令来训练模型:
rasa train --domain path_to_domain_directory
Intents
domain中的intent键列出了在NLU数据和会话训练数据中使用的所有intent
Ignoring Entities for Certain Intents
为了忽略某些意图的特定实体,可以增加use_entities:[]参数添加到你的domain文件的意图中:
intents:
- greet:
use_entities: []
要忽略某些实体或显式地只考虑某些实体,你可以使用下面的语法:
intents:
- greet:
use_entities:
- name
- first_name
ignore_entities:
- location
- age
被意图排除的实体将不具有特征,因此不会影响下一个action预测。当您有一个意图,而您并不关心抽取的实体时,这是非常有用的。
如果你列出你的意图没有这个参数,实体将作为正常的特征。
注意:如果希望这些实体不影响动作预测,请为同名的词槽设置influence_conversation: false参数。
Entities
实体部分列出了NLU pipline中任何实体提取器都可以提取的所有实体。
例如:
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 DIETClassifier
roles:
- from
- to
- topping: # custom entity extracted by DIETClassifier
groups:
- 1
- 2
- size: # custom entity extracted by DIETClassifier
groups:
- 1
- 2
注意:实体角色和组需要在domain中列出
Slots
Slots是机器人的内存。存储为键值对的形式,可用于存储用户提供的信息(例如他们所在的城市)以及收集的关于外部世界的信息(例如数据库查询的结果)。
Slots在domian中定义,包括它们的名称、类型以及它们是否以及如何影响助手的行为。下面的示例定义了一个名为“slot_name”和类型text的槽。
slots:
slot_name:
type: text
Slots and Conversation Behavior
您可以使用influence_conversation属性指定词槽是否影响会话。
如果希望在词槽中存储信息而不影响会话,则在定义槽时设置influence_conversation: false。
下面的示例定义了一个词槽age,它将存储有关用户年龄的信息,但不会影响对话流。这意味着助手每次预测下一个动作时都会忽略槽的值。
slots:
age:
type: text
# this slot will not influence the predictions
# of the dialogue policies
influence_conversation: false
在定义词槽时,如果您没有设置influence_conversation或将其设置为true,该槽将影响下一个动作预测,除非它的槽类型为any。词槽影响对话的方式将取决于它的词槽类型。
下面的示例定义了一个影响会话的词槽home_city。文本槽将根据槽是否具有值影响助手的行为。文本槽的具体值(例如Bangalore or New York or Hong Kong)没有任何影响。
slots:
# this slot will influence the conversation depending on
# whether the slot is set or not
home_city:
type: text
influence_conversation: true
例如,考虑两个输入“天气怎么样?”和“班加罗尔的天气怎么样?”根据NLU是否自动设置home_city槽位,会话应该会发生分歧。如果槽已经设置,机器人可以预测action_forecast动作。如果词槽未设置,则需要获取home_city信息,然后才能预测天气。
Slot 类型
Text Slot
Type text
User For 保存文本值
示例
slots:
cuisine:
type: text
influence_conversation: true
- 描述
如果influence_conversation 设置为
true,机器人会根据词槽是否填充改变自身的行为。不同的文本不会进一步影响对话。
以下两个故事是一致的
stories:
- story: French cuisine
steps:
- intent: inform
- slot_was_set:
- cuisine: french
- story: Vietnamese cuisine
steps:
- intent: inform
- slot_was_set:
- cuisine: vietnamese
Boolean Slot
Type bool
User For 保存true 或false值
示例
slots:
is_authenticated:
type: bool
- 描述
如果将influence_conversation设置为true,机器人的行为将根据词槽是空,为true还是为false而改变。请注意,空的bool词槽和设置为false的词槽对会话的影响不同。
Categorical Slot
Type categorical
User For 存储槽,可以取N个值中的一个。
示例
slots:
risk_level:
type: categorical
values:
- low
- medium
- high
- 描述
如果将influence_conversation设置为true,助理的行为将根据插槽的具体值而改变。这意味着根据上面示例中的槽的值是低、中还是高,助手的行为是不同的。
默认值other会自动添加到用户定义的值中。所有遇到的没有明确定义在槽值中的值都映射到other。other不应该用作用户定义的值;如果是,它仍将作为所有未见值映射到的默认值行事。
Float Slot
Type float
User For 存储数值
示例
slots:
temperature:
type: float
min_value: -100.0
max_value: 100.0
默认
max_value=1.0, min_value=0.0描述
如果influence_conversation设置为true,助理的行为将根据词槽的值而改变。如果值在min_value和max_value之间,则使用具体的数值。所有低于min_value的值将被视为min_value,所有高于max_value的值将被视为max_value。因此,如果max_value设置为1,则槽值2和3.5之间没有区别。
List Slot
Type list
User For 保存列表
示例
slots:
shopping_items:
type: list
- 描述
如果将influence_conversation设置为true,助理的行为将根据列表是否为空而改变。存储在词槽中的列表的长度不会影响对话框。它只与列表长度是否为零或非零有关。
Any Slot
Type any
User For 存储任意值(它们可以是任何类型,如字典或列表)
示例
slots:
shopping_items:
type: any
- 描述
任何类型的槽在对话中总是被忽略。此词槽类型的属性influence_conversation不能设置为true。如果要存储应该影响会话的自定义数据结构,请使用自定义槽类型。
Custom Slot 类型
也许你的餐厅预订系统最多只能处理6个人的预订。在本例中,您希望槽的值影响下一个选择的操作(而不仅仅是是否指定了它)。您可以通过定义一个自定义槽类来实现这一点。
下面的代码定义了一个名为NumberOfPeopleSlot的自定义槽类。特征定义如何将这个槽的值转换为向量,以便Rasa开源机器学习模型可以处理它。NumberOfPeopleSlot有三个可能的“值”,可以用长度为2的向量表示。
(0,0) |
not yet set |
---|---|
(1,0) |
between 1 and 6 |
(0,1) |
more than 6 |
# my_custom_slots.py
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模块,与自定义操作代码分离。将自定义槽的代码保存在一个名为"init.py"的空文件旁边的目录中,以便它将被识别为python模块。然后,您可以通过自定义槽类的模块路径来引用它。
例如,假设你将上面的代码保存在"addons/my_custom_slots.py"中,这是一个相对于你的bot项目的目录:
└── rasa_bot
├── addons
│ ├── __init__.py
│ └── my_custom_slots.py
├── config.yml
├── credentials.yml
├── data
├── domain.yml
├── endpoints.yml
自定义槽类型的模块路径是addons.my_custom_slots.NumberOfPeopleSlot。在domian文件中使用模块路径来引用自定义槽类型:
slots:
people:
type: addons.my_custom_slots.NumberOfPeopleSlot
influence_conversation: true
既然Rasa Open Source可以使用您的定制槽类,那么您可以根据people不同的值增加训练故事。你可以为people的值在1到6之间的情景写一个故事,为值大于6的情景写一个故事。您可以在这些范围内选择任何值放入您的故事中,因为它们的功能都是相同的(参见上面的功能表)。
stories:
- story: collecting table info
steps:
# ... other story steps
- intent: inform
entities:
- people: 3
- slot_was_set:
- people: 3
- action: action_book_table
- story: too many people at the table
steps:
# ... other story steps
- intent: inform
entities:
- people: 9
- slot_was_set:
- people: 9
- action: action_explain_table_limit
Slot Auto-fill
如果NLU模型抽取了一个实体,并且domian包含了一个同名的slot,那么这个slot将被自动设置,前提是满足以下条件:
1、Store_entities_as_slots设置为true
2、 槽的auto_fill属性设置为true
示例
stories:
- story: entity slot-filling
steps:
- intent: greet
entities:
- name: Ali
- slot_was_set:
- name: Ali
- action: utter_greet_by_name
在这种情况下,你不需要在故事中包含slot_was_set部分,因为它是自动选取的:
stories:
- story: entity slot-filling
steps:
- intent: greet
entities:
- name: Ali
- action: utter_greet_by_name
注意:AUTO-FILLED SLOTS & INFLUENCE_CONVERSATION
用influence_conversation: true定义的auto-filled slot将以与其他槽相同的方式影响会话。
在上面的例子中,如果 词槽name的类型是text,那么只需要检测到某个名称就可以了,但是是哪个名称并不重要。如果词槽name是categorical类型,那么行为将根据您为槽定义的类别而变化。
明确地在你的故事中包含slot_was_set步骤可以让auto-filled slot的行为更清晰地影响对话,而不会改变你的故事的行为。
要禁用特定槽位的自动填充,可以在domain文件中将auto_fill属性设置为false:
slots:
name:
type: text
auto_fill: false
Initial slot values
你可以在你的domain文件中提供一个槽的初始值:
slots:
num_fallbacks:
type: float
initial_value: 0
Responses
Session 配置
一个会话session表示用户和机器人之间的对话。会话重启有以下三种方式:
用户首次开启新的会话
用户间隔一段时间(可配置的时间)之后开启新的会话
-
发送/session_start意图
可以通过在session_config中配置间隔时间
-
session_expiration_time
定义了多长时间不活跃就重启新的session, 单位是分钟
原文: defines the time of inactivity in minutes after which a new session will begin
-
carry_over_slots_to_new_session
决定了是否将词槽传递到新的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, 并且会将当前的词槽传递给新的session.
如果session_expiration_time
to 0
表示当前会话session永远不会结束,只有在首次进入会话是才会激活action_session_start
NOTE
一个新的会话会触发默认actionaction_session_start
.
它默认将所有已有的slots传递给新的session。需要注意的是所有的会话都需要以action_session_start
开始.
action_session_start可以自定义。
系统内建的一些Action
session_start
action_restart
此操作将重置整个对话历史记录,包括在此过程中设置的所有轮次,槽位等信息。
如果模型配置中包含RulePolicy,则可以由用户在会话中通过发送“ /restart”消息来触发它。如果您utter_restart
在domain中定义了一个响应,则该响应也将发送给用户。
action_session_start
该操作将启动一个新的会话。在以下情况下该操作自动执行:
在每次新对话开始时
用户处于非活动状态超过
session_expiration_time
这个参数后当用户在对话期间发送“ / session_start”消息时
该操作将重置对话跟踪器,但默认情况下不会清除已设置的任何插槽。
会话开始操作的默认行为是将所有现有的插槽带入下一个会话。假设不想保留所有插槽或者只保留一个部分插槽,可以重写action_session_start
函数。