从 3.0 开始,插槽映射slot mappings在域domain部分中定义。 此更改允许在多个表单中重复使用相同的插槽映射,从而消除任何不必要的重复。
https://rasa.com/docs/rasa/migration-guide/#slot-mappings
Form 最常见的对话模式之一是从用户那里收集一些信息,以便做某事(预订餐厅、调用 API、搜索数据库等)。这也称为插槽填充。
2.0的例子代码
https://learning.rasa.com/archive/rasa-forms-2/rasa-forms/
config.yml 启用form
policies:
- name: RulePolicy
通过将表单forms添加到域(domain)中的部分来定义表单。 表单的名称也是可在故事stories或规则rules中用于处理表单执行action的操作的名称。
您需要强制指定插槽名称列表required_slots
entities:
- cuisine
- number
slots:
cuisine:
type: text
mappings:
- type: from_entity
entity: cuisine
num_people:
type: any
mappings:
- type: from_entity
entity: number
forms:
restaurant_form:
required_slots:
- cuisine
- num_people
如果您不希望在以下情况下填写表单的任何必需插槽 目的是 ,那么您需要定义以下内容(在表单之后:chitchat ignored_intents)
entities:
- cuisine
- number
slots:
cuisine:
type: text
mappings:
- type: from_entity
entity: cuisine
num_people:
type: any
mappings:
- type: from_entity
entity: number
forms:
restaurant_form:
ignored_intents:
- chitchat
required_slots:
- cuisine
- num_people
rules:
- rule: Activate form
steps:
- intent: request_restaurant
- action: restaurant_form
- active_loop: restaurant_form
rules:
- rule: Submit form
condition:
# 表单处于活动状态的条件.
- active_loop: restaurant_form
steps:
# 表单停用
- action: restaurant_form
- active_loop: null
- slot_was_set:
- requested_slot: null
# 提交表单时要运行的操作
- action: utter_submit
- action: utter_slots_values
默认情况下,Rasa 会从插槽中请求下一个空插槽 在域文件中列出您的表单。
如果使用自定义插槽映射 , 它将请求该方法返回的第一个空插槽。如果插槽全部填充的插槽将停用表单。FormValidationActionrequired_slotsrequired_slots
您可以动态更新表单的所需槽位。
例如: 当您需要根据如何填充其他插槽时,这很有用 上一个插槽已填满,或者当您想要更改请求插槽的顺序时。
如果您使用的是 Rasa SDK,我们强烈建议您使用 和 覆盖以适合您的动态行为。您必须实现 每个不使用预定义映射的插槽的方法, 如自定义插槽映射中所述。 下面的示例将询问用户是否要坐在 阴凉处或阳光下,以防他们说他们想坐在外面。FormValidationActionrequiredslotsextract<slot name>
from typing import Text, List, Optional
from rasa_sdk.forms import FormValidationAction
class ValidateRestaurantForm(FormValidationAction):
def name(self) -> Text:
return "validate_restaurant_form"
async def required_slots(
self,
domain_slots: List[Text],
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: "DomainDict",
) -> List[Text]:
additional_slots = ["outdoor_seating"]
if tracker.slots.get("outdoor_seating") is True:
# 如果用户想坐在外面,请询问
# 如果他们想坐在阴凉处或阳光下。
additional_slots.append("shade_or_sun")
return additional_slots + domain_slots
from typing import Text, List, Optional
from rasa_sdk.forms import FormValidationAction
class ValidateBookingForm(FormValidationAction):
def name(self) -> Text:
return "validate_booking_form"
async def required_slots(
self,
domain_slots: List[Text],
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: "DomainDict",
) -> List[Text]:
updated_slots = domain_slots.copy()
if tracker.slots.get("existing_customer") is True:
updated_slots.remove("email_address")
return updated_slots
一旦表单确定用户接下来必须填写哪个插槽,它就会 执行操作或要求用户提供必要的信息。
如果常规话语不是 足够了,您还可以使用自定义操作或请求下一个插槽
from typing import Dict, Text, List
from rasa_sdk import Tracker
from rasa_sdk.events import EventType
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk import Action
class AskForSlotAction(Action):
def name(self) -> Text:
return "action_ask_cuisine"
def run(
self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
) -> List[EventType]:
dispatcher.utter_message(text="What cuisine?")
return []
如果插槽有多个请求选项,Rasa 将按以下顺序确定优先级:
1.actionask<form_name><slot_name>
2.utter_ask<form_name><slot_name>
3.action_ask<slot_name>
4.utterask<slot_name>