1. 概述
2.0版发生了很多变化。 确保通读本指南,以确保机器人的所有部分都已更新。 内置命令可以自动完成很多更新,其他更新则需要手动进行转换。 如果对这些更新或迁移过程有任何反馈,可以在论坛中发布。
2. 训练数据文件
从2.0版开始,新的默认训练数据格式为yaml。 仍支持Markdown,但在将来的版本中将不再使用。
可以使用以下命令将Markdown格式的现有NLU,Stories和NLG(即Response.md)训练数据文件转换为新的YAML格式:
rasa data convert nlu -f yaml --data={SOURCE_DIR} --out={TARGET_DIR}
rasa data convert nlg -f yaml --data={SOURCE_DIR} --out={TARGET_DIR}
rasa data convert core -f yaml --data={SOURCE_DIR} --out={TARGET_DIR}
转换后的文件将具有与原始文件相同的名称,但后缀为_converted.yml
。
如果使用 forms或response selectors,则需要按照其各自的部分中的说明进行一些其他更改。
3. Policies
通过引入rules和RulePolicy,不推荐使用以下策略:
- Mapping Policy
- Fallback Policy
- Two-Stage-Fallback Policy
-
Form Policy
要自动迁移策略,可以运行以下命令:
rasa data convert config
该命令将负责更新config.yml
和domain.yml
,同时使用.bak
后缀备份现有文件。 如有必要,还将添加rules.yml
。此更新后,forms仍将以旧格式正常运行,但是此命令不会自动将它们转换为新格式。 如forms部分所述,这应该手动完成。
如果不想使用自动转换命令,也可以手动迁移单个策略。
3.1 Manually migrating from the Mapping Policy
如果以前使用过Mapping Policy,则可以按照 FAQs上的文档将映射的意图转换为规则。 假设以前按如下方式映射了一个意图Ask_is_bot
:
domain.yml
intents:
- ask_is_bot:
triggers: action_is_bot
变成规则就是下面这个样子:
rules.yml
rules:
- rule: Rule to map `ask_is_bot` intent
steps:
- intent: ask_is_bot
- action: action_is_bot
而且,我们可以安全地从domain中删除所有触发器(triggers):
domain.yml
intents:
- ask_is_bot
最后,可以在模型配置中将Mapping Policy替换为 Rule Policy:
config.yml
policies:
# Other policies
- name: RulePolicy
3.2 Manually migrating from the Fallback Policy
如果先前使用了Fallback Policy,则给定之前的配置,模型配置将转换为以下内容:
config.yml
policies:
- name: "FallbackPolicy"
nlu_threshold: 0.4
core_threshold: 0.3
fallback_action_name: "action_default_fallback"
ambiguity_threshold: 0.1
新配置如下所示:
config.yml
policies:
# Other policies
- name: RulePolicy
core_fallback_threshold: 0.3
core_fallback_action_name: "action_default_fallback"
pipeline:
# Other components
- name: FallbackClassifier
threshold: 0.4
ambiguity_threshold: 0.1
此外,需要添加一条 rule来指定在NLU置信度较低的情况下要执行哪个操作:
rules.yml
rules:
- rule: Ask the user to rephrase whenever they send a message with low NLU confidence
steps:
- intent: nlu_fallback
- action: utter_please_rephrase
有关更多信息,请参见fallback文档。
3.3 Manually migrating from the Two-Stage-Fallback Policy
如果以前使用[Two-Stage-Fallback Policy(https://rasa.com/docs/rasa/policies#two-stage-fallback-policy),例如这样的配置:
config.yml
policies:
- name: TwoStageFallbackPolicy
nlu_threshold: 0.4
ambiguity_threshold: 0.1
core_threshold: 0.3
fallback_core_action_name: "action_default_fallback"
fallback_nlu_action_name: "action_default_fallback"
deny_suggestion_intent_name: "out_of_scope"
新的配置如下所示:
config.yml
policies:
# Other policies
- name: RulePolicy
core_fallback_threshold: 0.3
core_fallback_action_name: "action_default_fallback"
pipeline:
# Other components
- name: FallbackClassifier
threshold: 0.4
ambiguity_threshold: 0.1
此外,还需要添加一条 rule以针对NLU置信度较低的消息激活Two-Stage Fallback。
rules.yml
rules:
- rule: Implementation of the TwoStageFallbackPolicy
steps:
# This intent is automatically triggered by the `FallbackClassifier` in the NLU
# pipeline in case the intent confidence was below the specified threshold.
- intent: nlu_fallback
# The Fallback is now implemented as a form.
- action: action_two_stage_fallback
- active_loop: action_two_stage_fallback
请注意,先前的参数fallback_nlu_action_name
和deny_suggestion_intent_name
不再可配置,并且具有固定值action_default_fallback
和out_of_scope
。
有关更多信息,请参见fallback文档。
4. Forms
从2.0版开始, forms的逻辑已从Rasa SDK移至Rasa Open Source,以简化实现并使其更容易用其他语言编写action servers。
这意味着Forms不再使用FormAction来实现,而是在domain中定义。 可以使用FormValidationAction处理有关请求槽值或slot validation的任何自定义设置。
考虑来自1.x的自定义Forms操作,如下所示:
from typing import Text, List, Any, Dict, Union
from rasa_sdk import Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction
class RestaurantForm(FormAction):
def name(self) -> Text:
return "restaurant_form"
@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
return ["cuisine"]
def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
return {
"cuisine": self.from_entity(entity="cuisine", not_intent="chitchat"),
}
@staticmethod
def cuisine_db() -> List[Text]:
"""Database of supported cuisines"""
return ["caribbean", "chinese", "french"]
def validate_cuisine(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate cuisine value."""
if value.lower() in self.cuisine_db():
# validation succeeded, set the value of the "cuisine" slot to value
return {"cuisine": value}
else:
dispatcher.utter_message(template="utter_wrong_cuisine")
# validation failed, set this slot to None, meaning the
# user will be asked for the slot again
return {"cuisine": None}
def submit(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[Dict]:
"""Define what the form has to do
after all required slots are filled"""
# utter submit template
dispatcher.utter_message(template="utter_submit")
return []
通过删除FormPolicy并将 RulePolicy(如果尚未添加)添加到模型配置中,开始迁移:
config.yml
policies:
# Other policies
# ...
- name: RulePolicy
然后,需要按照form文档中的描述在domain中定义form,所需的slots及其slot映射:
domain.yml
forms:
restaurant_form:
cuisine:
- type: cuisine
entity: cuisine
not_intent: chitchat
如果通过运行命令来 convert your stories,那么我们将拥有一个可以处理form activation 和deactivation的story,如下所示:
stories.yml
stories:
- story: cuisine form
steps:
- intent: request_restaurant
- action: restaurant_form
- active_loop: restaurant_form
- active_loop: null
- action: utter_submit
这可以很好地工作,但是处理form behavior的最佳方法是删除这个story,并且为form activation 和 submission定义两个单独的规则:
rules.yml
rules:
- rule: Activate form
steps:
- intent: request_restaurant
- action: restaurant_form
- active_loop: restaurant_form
- rule: Submit form
condition:
# Condition that form is active.
- active_loop: restaurant_form
steps:
- action: restaurant_form
- active_loop: null
# The action we want to run when the form is submitted.
- action: utter_submit
最后一步是实施custom action以验证form slots。 首先将custom action添加到domain中:
domain.yml
actions:
# Other actions
# ...
- validate_restaurant_form
然后添加一个custom action,以验证cuisine
slot:
from typing import Text, List, Any, Dict, Union
from rasa_sdk import Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk import FormValidationAction
from rasa_sdk.types import DomainDict
class RestaurantFormValidator(FormValidationAction):
def name(self) -> Text:
return "validate_restaurant_form"
@staticmethod
def cuisine_db() -> List[Text]:
"""Database of supported cuisines"""
return ["caribbean", "chinese", "french"]
def validate_cuisine(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
"""Validate cuisine value."""
if slot_value.lower() in self.cuisine_db():
# validation succeeded, set the value of the "cuisine" slot to value
return {"cuisine": slot_value}
else:
# validation failed, set this slot to None, meaning the
# user will be asked for the slot again
return {"cuisine": None}
有关更多详细信息,请参见 forms文档。
网友评论