2. Rasa2.0 学习笔记:版本迁移指南(上):1.10 to 2.0

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

如果使用 formsresponse selectors,则需要按照其各自的部分中的说明进行一些其他更改。

3. Policies

通过引入rulesRulePolicy,不推荐使用以下策略:

rasa data convert config

该命令将负责更新config.ymldomain.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_namedeny_suggestion_intent_name不再可配置,并且具有固定值action_default_fallbackout_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文档。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355