Rasa 入门教程 Core 系列(六)
Rasa 入门教程 Core 系列包括十一个部分,前面介绍了 Rasa 框架 Core 系列的第五部分:策略。本文主要介绍 Rasa 框架 Core 系列的第六部分:槽位。
本文的目录结构:
- 什么是槽位?
- Rasa 如何使用槽位
- 如何设置槽位
- 槽位类型
- 自定义槽位类型
1. 什么是槽位?
槽位是机器人的内存。它们以键值对存储,可用于存储用户提供的信息(例如:他们的家乡)以及有关外界的信息(例如:数据库查询的结果)。
在大多数情况下,你希望槽位能够影响对话流程。对于不同的行为,有不同类型的槽位。
例如:如果你的用户提供了他们的居住城市,则可能有一个名为 text
的槽位叫 home_city
。如果用户询问天气,而你不知道他们的家乡,则必须向他们询问什么城市。一个 text
槽位仅仅告诉 Rasa 是否有槽位值。text
槽位的具体值(例如:班加罗尔、纽约或香港)没有任何区别。
如果该值本身很重要,请使用 categorical
或 bool
槽位,也有 float
和 list
槽位。如果你只想存储一些数据,但又不想影响对话的流程,请使用 unfeaturized
槽位。
2. Rasa 如何使用槽位
在 Policy
没有访问槽位值,它接收一个特征化表示。如上所述,对于 text
槽位,该值无关紧要。该策略只会通过 1
或 0
来判断它是否设置。请仔细选择槽位类型!
3. 如何设置槽位
你可以在 domain 文件中的槽位初始化值:
slots:
name:
type: text
initial_value: "human"
对话期间可以使用多种方式设置槽位:
3.1 使用 NLU 设置槽位
如果你的 NLU 模型要提取实体,并且在 domain 文件中配置了一个相同名称的槽位,则该槽位将自动设置。例如:
# story_01
* greet{"name": "Ali"}
- slot{"name": "Ali"}
- utter_greet
在上述情况下,你不需要在 stories 文件中包括 - slot{}
,因为它是自动提取的。
要为特定槽位禁用此行为,可以在 domain 文件中将 auto_fill
属性设置为 False
:
slots:
name:
type: text
auto_fill: False
3.2 使用点击按钮设置槽位
你可以将按钮用作快捷方式。Rasa Core 以 /
开头将消息发送给 RegexInterpreter
,要求 NLU 输入的格式与 stories 文件中的格式相同,例如:/intent{entities}
。比如:如果让用户通过单击按钮来选择颜色,则按钮的装载量可能是 /choose{"color": "blue"}
和 /choose{"color": "red"}
。
你可以在 domain 文件中指定以下内容:(详细信息请参阅:Rasa 框架 Core 系列的第二部分:Domains)
utter_ask_color:
- text: "what color would you like?"
buttons:
- title: "blue"
payload: '/choose{"color": "blue"}'
- title: "red"
payload: '/choose{"color": "red"}'
3.3 使用动作设置槽位
你也可以通过在自定义动作中返回事件来设置槽位,在这种情况下,你的 stories 需要包含槽位。例如:你有一个自定义动作来获取用户的个人信息,并且有一个名为 account_type
的 categorical
槽位,当 fetch_profile
动作运行时,它返回一个 rasa.core.events.SlotSet
事件:
slots:
account_type:
type: categorical
values:
- premium
- basic
from rasa_sdk.actions import Action
from rasa_sdk.events import SlotSet
import requests
class FetchProfileAction(Action):
def name(self):
return "fetch_profile"
def run(self, dispatcher, tracker, domain):
url = "http://myprofileurl.com"
data = requests.get(url).json
return [SlotSet("account_type", data["account_type"])]
# story_01
* greet
- action_fetch_profile
- slot{"account_type" : "premium"}
- utter_welcome_premium
# story_02
* greet
- action_fetch_profile
- slot{"account_type" : "basic"}
- utter_welcome_basic
在这种情况下,你必须将 - slot()
包括在你的 stories 文件中。Rasa Core 将学习使用这些信息来决定要采取的正确措施(例如上例中:utter_welcome_premium
或 utter_welcome_basic
)。
4. 槽位类型
4.1 text 槽位
-
用途:是否指定用户首选项
-
示例:
slots: cuisine: type: text
-
描述:如果设置任何值,则槽位的特征化为
1
;否则特征化为0
(未设置任何值)。
4.2 bool 槽位
-
用途:
True
或False
-
示例:
slots: is_authenticated: type: bool
-
描述:检查是否设置了槽位以及是否为
True
。
4.3 categorical 槽位
-
用途:槽位可以采用 N 个值中的一个
-
示例:
slots: risk_level: type: categorical values: - low - medium - high
-
描述:创建一个
one-hot
编码用来描述与哪个values
匹配。
4.4 float 槽位
-
用途:连续值
-
示例:
slots: temperature: type: float min_value: -100.0 # 默认值 0.0 max_value: 100.0 # 默认值 1.0
-
描述:小于
min_value
的所有值将作为min_value
处理,同理max_value
。因此,如果max_value
被设置为1
,则槽位值2
和3.5
在特征化时没有区别(例如:两个值以相同的方式影响对话,并且模型无法学习到它们之间的区别)。
4.5 list 槽位
-
用途:值的清单列表
-
示例:
slots: shopping_items: type: list
-
描述:如果设置了带有列表的值(列表不为空),则设置此槽位的特征化值为
1
。如果未设置任何值或者空白列表,则该特征化值为0
。存储在槽位中的列表长度不影响对话。
4.6 unfeaturized 槽位
-
用途:存储不影响对话流程的数据
-
示例:
slots: internal_user_id: type: unfeaturized
-
描述:该槽位不具有任何特征化,因此其值不会影响对话流程,在预测机器人应执行下一个动作时会被忽略。
5. 自定义槽位类型
假设你的餐厅预订系统最多只能处理 6 个人的预订。在这种情况下,你希望槽位值影响下一个选定的动作(而不只是影响是否已指定),你可以通过自定义槽位类来实现。
在下面的代码中,我们定义了一个名为 NumberOfPeopleSlot
的槽位类。特征化定义了如何将此槽位值转换为向量,以供机器学习模型进行处理。我们的槽位有三个可能的“值”,我们可以用长度为 2 的矢量来表示。
矢量表示 | 描述 |
---|---|
(0,0) |
尚未设定 |
(1,0) |
1至6之间 |
(0,1) |
超过6 |
from rasa.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
现在我们还需要一些训练数据,以便 Rasa Core 可以从中学习如何处理不同情况:
# story1
...
* inform{"people": "3"}
- action_book_table
...
# story2
* inform{"people": "9"}
- action_explain_table_limit
作者:关于我
备注:转载请注明出处。
如发现错误,欢迎留言指正。