领域¶
领域定义了对话机器人运行的领域。
在 Rasa 中,domain
定义了对话机器人运行的领域。具体来说,它列出了:
- 可用作模板消息发送给用户的
responses
。 - 可以通过对话策略预测的自定义
actions
。 - 在整个对话过程中充当对话机器人记忆的
slots
。 - 会话配置参数,包括不活动超时。
如果你正在构建基于 NLU 的对话机器人,请参阅领域文档以了解如何在领域中配置意图、实体、槽映射和槽特征化。
多领域文件¶
领域可以定义为单个 YAML 文件,也可以拆分为目录中的多个文件。拆分为多个文件时,领域内容将被读取并自动合并在一起。你还可以在 Rasa Studio 中管理响应、槽和自定义动作。
使用命令行界面,可以通过运行以下命令来训练具有拆分领域文件的模型:
响应¶
响应是对话机器人可以发送给用户的模板消息。响应可以包含丰富的内容,如按钮、图像和自定义 json 负载。每个响应也是一个动作,这意味着它可以直接在流中的 action
步骤中使用。响应可以直接在领域文件中的 responses
键下定义。有关响应及其定义方法的更多信息,请参阅响应。
动作¶
动作是对话机器人可以做的事情。例如,动作可以:
- 响应用户。
- 进行外部 API 调用。
- 查询数据库。
- 几乎任何事情!
所有自定义动作都应列在领域中。
Rasa 还具有默认动作,你无需将其列在领域中。
槽¶
槽是对话机器人的记忆。它们充当键值存储,可用于存储用户提供的信息(例如他们的家乡)以及收集的有关外部世界的信息(例如数据库查询的结果)。
槽在领域的 slots
部分中定义,包括其名称、类型和默认值。存在不同的槽类型来限制槽可以采用的可能值。
槽类型¶
文本类型槽¶
文本类型槽可以使用任何字符串值。
-
示例
-
允许值
任意字符串。
布尔类型槽¶
布尔类型槽只能取 true
或 false
值。当你想要存储二进制值时,这很有用。
-
示例
-
允许值
true
或false
。
分类槽¶
分类槽只能从预定义集合中取值。当你想要限制槽可以取的可能值时,这很有用。
如果用户提供的值的大小写与领域中定义的值的大小写不匹配,则该值将被强制转换为正确的大小写。例如,如果用户为具有 low
、medium
、high
的值的槽提供值 LOW
,则该值将转换为 low
并存储在槽中。
如果你使用值列表定义分类槽,其中多个值为同一值,则会发出警告,你应该从领域中的集合中删除其中一个值。例如,如果你使用值 low
、medium
、high
和 Low
定义分类槽,则值 Low
将被强制转换为 low
并发出警告。
-
示例
浮点类型槽¶
浮点类型槽只接受浮点值。当你想要存储带有小数点的数字时,这很有用。
-
示例
任意类型槽¶
此类型槽可以接受任何值。当你想要存储任何类型的信息(包括字典等结构化数据)时,这很有用。
-
示例
列表类型槽¶
列表类型槽可以接受列表值。请注意,在使用 CALM 构建对话机器人时,列表类型槽仅在自定义动作中受支持。列表类型槽不能用流中的 collect
或 set_slots
流步骤类型填充。
CALM 槽映射¶
3.9.0 版本新特性
使用 CALM 构建对话机器人时,你可以配置槽填充以使用基于 NLU 的预定义槽映射或新引入的 from_llm
槽映射类型。
基于 NLU 的预定义槽映射¶
在使用 CALM 构建对话机器人时,你可以继续使用基于 NLU 的预定义槽映射,例如 from_entity
或 from_intent
。除了将分词器、特征化器、意图分类器和实体提取器添加到管道之外,还必须将 NLUCommandAdapter
添加到 config.yml
文件中。NLUCommandAdapter
会将 NLU 管道的输出(意图和实体)与领域文件中定义的槽映射进行匹配。如果槽映射得到满足,NLUCommandAdapter
将发出 set slot
命令来填充槽。
如果在消息处理期间,NLUCommandAdapter
发出命令,则管道中的以下命令生成器(例如基于 LLM 的命令生成器)将被完全绕过。因此,基于 LLM 的命令生成器将无法通过在对话流中的任何点发出 set slot
命令来填充槽。如果基于 LLM 的命令生成器发出命令以使用基于 NLU 的预定义映射填充槽,则这些来自基于 LLM 的命令生成器的 set slot
命令将被忽略。如果在同一回合没有预测到其他命令,则对话机器人将触发 cannot_handle
对话修复模式。
有时,用户消息可能包含超出设置槽范围的意图。例如,用户消息可能包含填充槽的实体,但也包含流必须处理的离题。在这种情况下,我们建议使用 NLU 触发器来处理流中的这些特定意图。有关更多详细信息,请参阅不同场景中槽映射的影响部分。
注意
在使用流构建并使用 NLU 组件处理消息的 CALM 对话机器人中,默认动作 action_extract_slots
将不会运行,因为在命令执行期间,槽填充事件会应用于对话跟踪器。这可确保此默认动作不会覆盖 CALM set slot
命令,也不会重复已应用于对话跟踪器的 SlotSet
事件。
在共存的情况下,仅当基于 NLU 的系统处于活动状态时,才会执行 action_extract_slots
动作。
from_llm
¶
可以使用 from_llm
槽映射类型,用基于 LLM 的命令生成器生成的值填充槽。如果领域文件中未明确定义映射,则这是默认槽映射类型。
以下是示例:
在此示例中,user_name
槽将由基于 LLM 的命令生成器生成的值填充。基于 LLM 的命令生成器可以在对话流中的任何点填充此槽位,而不仅仅是在此槽位的相应 collect
步骤中。
如果你在 config.yml
管道中定义了其他基于 NLU 的组件,这些组件将继续处理用户消息,但它们将无法填充槽。NLUCommandAdapter
将跳过任何具有 from_llm
映射的槽,并且不会发出 set slot
命令来填充这些槽。有关更多详细信息,请参阅不同场景中槽映射的影响部分。
请注意,槽不能同时具有 from_llm
和基于 NLU 的预定义映射或自定义槽映射。如果使用 from_llm
映射定义槽,则不能为该槽定义任何其他映射类型。
映射条件¶
你可以定义在填充槽之前要满足的槽映射条件。条件定义为 conditions
键下的条件列表。每个条件都可以将必须处于活动状态的流 ID 指定为 active_flow
属性。
如果你定义了映射到同一实体的多个槽,但不想在提取实体时填充所有槽,则这特别有用。
例如:
entities:
- person
slots:
first_name:
type: text
mappings:
- type: from_entity
entity: person
conditions:
- active_flow: greet_user
last_name:
type: text
mappings:
- type: from_entity
entity: person
conditions:
- active_flow: issue_invoice
自定义插槽映射¶
你可以使用 custom
映射类型来定义应由自定义动作填充的槽的自定义槽映射。必须在槽映射的 action
属性中指定自定义动作。你还必须在领域文件中的 operations
键下列出该动作。
例如:
actions:
- action_fill_user_name
slots:
user_name:
type: text
mappings:
- type: custom
action: action_fill_user_name
在此示例中,user_name
槽将由 action_fill_user_name
自定义动作填充。自定义动作必须返回带有槽名称和值的 SlotSet
事件才能填充槽。
请注意,如果你使用 action_ask_<slot_name>
命名约定通过自定义动作请求用户输入,但该槽由基于 LLM 的命令生成器生成的值填充,则不应为该槽定义自定义槽映射。相反,请使用 from_llm
映射类型,因为自定义映射类型是为由返回 SlotSet
事件的自定义动作设置的槽保留的(例如,由外部源设置的槽)。你可以继续使用 action_ask_<slot_name>
约定来请求由基于 LLM 的命令生成器填充的槽的用户输入。
如果你使用自定义验证动作(使用 validate_<slot_name>
命名约定)来验证由基于 LLM 的生成器从最终用户的输入中提取的槽值,则也不应该为这些槽定义自定义槽映射。相反,请为这些槽使用 from_llm
映射类型来。
警告
如果你使用 --skip-validation
标志进行训练,并且已定义具有自定义槽映射的槽,这些槽未在领域文件中指定 action
属性,也没有相应的 action_ask_<slot_name>
自定义动作来请求这些槽,则将不会在训练时收到错误。但是,在运行时,FlowPolicy
将首先取消正在进行的用户流,然后触发 pattern_internal_error
。
你也可以通过 rasa data verify
命令运行此检查。
不同场景中槽映射的影响¶
本节阐明了当流处于 name
槽的 collect
步骤或任何其他步骤时,使用流和 NLU 管道构建的 CALM 对话机器人中的哪些组件在不同场景中填充槽。
假设 name
槽使用 from_llm
映射类型定义。
功能 | name 槽的收集步骤 |
任何其他不收集槽的步骤 |
---|---|---|
基于 LLM 的生成器处于活动状态 | ✅ | ✅ |
NLU 组件(例如意图分类器、实体提取器)处于活动状态 | ✅ | ✅ |
基于 LLM 的生成器是否可以填充 name 槽 |
✅ | ✅ |
NLUCommandAdapter 是否可以填充 name 槽 |
❌ | ❌ |
要点是 NLUCommandAdapter
无法在对话的任何阶段用 from_llm
映射填充槽。
假设 name
槽是使用基于 NLU 的预定义映射之一(例如 from_entity
)定义的。
功能 | name 槽的收集步骤 |
任何其他不收集槽的步骤 |
---|---|---|
基于 LLM 的生成器处于活动状态 | ❌ | ✅ |
NLU 组件(例如意图分类器、实体提取器)处于活动状态 | ✅ | ✅ |
基于 LLM 的生成器是否可以填充 name 槽 |
❌ | ❌ |
NLUCommandAdapter 是否可以填充 name 槽 |
✅ | ✅ |
要点:
- 基于 LLM 的生成器无法在对话的任何阶段用基于 NLU 的预定义映射填充槽。
- 基于 LLM 的生成器在
name
槽的收集步骤中不会处于活动状态。如果预计用户话语包含离题或其他意图,超出了设置槽的信息,则应使用 NLU 触发器来处理流中的这些特定意图。 - 基于 LLM 的生成器可以在未收集
name
槽且具有from_llm
映射类型的步骤中填充其他槽。
初始化槽值¶
你可以为领域文件中的任何槽提供初始值:
共存期间槽的持久性¶
在基于 NLU 的系统和 CALM 系统的共存中,action_reset_routing
动作会重置所有槽并隐藏基于 NLU 的系统策略的特征化事件,以防止它们看到 CALM 处于活动状态时发生的事件。但是,你可能希望共享一些 CALM 和基于 NLU 的系统都应该能够使用的槽。这些槽的一个用例是基本用户配置文件槽。基于 NLU 的系统和 CALM 都应该能够知道用户是否登录、他们的用户名是什么或他们正在使用哪个频道。如果你将此类数据存储在槽中,则可以使用选项 shared_for_coexistence: True
注释这些槽定义。
version: "3.1"
slots:
user_channel:
type: categorical
values:
- web
- teams
shared_for_coexistence: True
user_name:
type: text
shared_for_coexistence: True
在共存模式下,如果未将选项 shared_for_coexistence
设置为 true
,则会使流定义中的 reset_after_flow_ends: False
属性无效。为了在整个对话过程中保留槽值,必须将 shared_for_coexistence
设置为 true
。
会话配置¶
对话会话代表对话机器人与用户之间的对话。对话会话可以通过三种方式开始:
- 用户开始与对话机器人对话。
- 用户在可配置的不活动期后发送第一条消息。
- 使用
/session_start
意图消息触发会话手动启动。
你可以在领域中 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
动作仍会在对话开始时触发)。
注意
会话启动会触发默认动作 action_session_start
。其默认实现会将所有现有槽移至新会话中。请注意,所有对话都以 action_session_start
开头。例如,覆盖此动作可用于使用来自外部 API 调用的槽初始化追踪器,或使用机器人消息启动对话。有关自定义会话启动动作的文档展示了如何执行此动作。
选择哪些动作应该接收领域¶
3.4.3 新特性
你可以控制某个动作是否应该接收领域。
为此,你必须首先在 endpoints.yml
中为 action_endpoint
启用 API 配置中的选择性领域。
action_endpoint:
url: "http://localhost:5055/webhook" # URL to your action server
enable_selective_domain: true
启用自定义动作的选择性领域后,领域将仅发送给明确声明需要的自定义动作。从 rasa-sdk FormValidationAction
父类继承的自定义动作是此规则的一个例外,因为它们始终会将领域发送给它们。要指定动作是否需要领域,请在 domain.yml
中的动作列表中将 {send_domain: true}
添加到自定义动作: