天天看點

Rasa 文檔 中英文翻譯版本 3 - Tutorial: Building AssistantsRasa 文檔 中英文翻譯版本 3 - Tutorial: Building Assistants Tutorial: Building Assistants  建立對話機器人助理Rasa 文檔 中英文翻譯版本 3 - Tutorial: Building Assistants Tutorial: Building Assistants  建立對話機器人助理

Rasa 文檔 中英文翻譯版本 3 - Tutorial: Building Assistants

https://rasa.com/docs/rasa/user-guide/building-assistants/

T by yi 

Tutorial: Building Assistants  建立對話機器人助理

After following the basics of setting up an assistant in the Rasa Tutorial, we’ll now walk through building a basic FAQ chatbot and then build a bot that can handle contextual conversations.

FAQ是英文Frequently Asked Questions的縮寫

在學完了前面的教程基礎知識後,我們現在将演練建構一個基本的常見問題聊天機器人,然後建構一個可以處理上下文對話的機器人。

目錄

Building a simple FAQ assistant 建立FAQ 常見問題機器人助理

Memoization Policy 記憶政策

Response Selectors  響應選擇器

Building a contextual assistant   建構上下文助理

Handling business logic 處理業務邏輯

Handling unexpected user input 處理意外使用者輸入

Generic interjections 通用插話

Contextual questions 上下文問題

Failing gracefully 優雅地回複失敗問題

Fallback policy 回退政策

Out of scope intent 範圍外意圖處理

More complex contextual conversations 更複雜的上下文對話

AugmentedMemoizationPolicy 增強記憶政策

Using ML to generalise 使用ML機器學習來生成

Building a simple FAQ assistant 建立FAQ 常見問題機器人助手

FAQ assistants are the simplest assistants to build and a good place to get started. These assistants allow the user to ask a simple question and get a response. We’re going to build a basic FAQ assistant using features of Rasa designed specifically for this type of assistant.

常見問題助理是最簡單的助手,也是好的入門教程。這些助手允許使用者提出一個簡單的問題并得到答複。我們将使用 Rasa 專為此類助手設計的功能建構一個基本的常見問題解答助手。

In this section we’re going to cover the following topics:

這個章節我們覆寫一下内容

Responding to simple intents with the MemoizationPolicy

使用MemoizationPolicy回應簡單意圖對話

Handling FAQs using the ResponseSelector

使用ResponseSelector處理常見問題

We’re going to use content from Sara, the Rasa assistant that, amongst other things, helps the user get started with the Rasa products. You should first install Rasa using the Step-by-step Installation Guide and then follow the Rasa Tutorial to make sure you know the basics.

我們将使用來自Rasa機器人助手示例Sara 的内容和其他一些内容,幫助使用者開始使用 Rasa 産品。您應該首先使用分步安裝指南安裝 Rasa,然後按照 Rasa 教程操作,以確定了解基礎知識。

To prepare for this tutorial, we’re going to create a new directory and start a new Rasa project.

為了準備本教程,我們将建立一個新目錄,并開始一個新的 Rasa 項目。

mkdir rasa-assistant

rasa init

Let’s remove the default content from this bot, so that the nlu.md, stories.md and domain.yml files are empty.

我們需要删除預設生成的檔案内容,是以 nlu.md, stories.md domain.yml三個檔案是空的

Memoization Policy 記憶政策

The MemoizationPolicy remembers examples from training stories for up to a max_history of turns. The number of “turns” includes messages the user sent, and actions the assistant performed. For the purpose of a simple, context-less FAQ bot, we only need to pay attention to the last message the user sent, and therefore we’ll set that to 1.

MemoizationPolicy 記憶政策可以設定用幾輪對話的内容來進行訓練進行。

配置中用max_history标記來标記輪次(turns) 。

對話輪次的數量包括使用者發送的消息以及助手執行的操作。為了簡單、無上下文的常見問題程式,我們隻需要注意使用者發送的最後一條消息,是以我們将它設定為 1。

You can do this by editing your config.yml file as follows (you can remove TEDPolicy for now):

你可以修改config.yml來配置。(現在可以删除TEDPolicy )

policies:- name: MemoizationPolicy

  max_history: 1- name: MappingPolicy

Note

The MappingPolicy is there because it handles the logic of the /restart intent, which allows you to clear the conversation history and start fresh.

MappingPolicy 政策之是以存在,是因為它處理 /restart 意圖的邏輯,它允許您清除對話曆史記錄并開始重新開始。

Now that we’ve defined our policies, we can add some stories for the goodbye, thank and greet intents to the stories.md file:

現在,我們已經定義了我們的政策,我們可以添加一些故事的goodbye,thank 和greet 的意圖在stories.md檔案:

## greet* greet

  - utter_greet

## thank* thank

  - utter_noworries

## goodbye* bye

  - utter_bye

We’ll also need to add the intents, actions and responses to our domain.yml file in the following sections:

我們還需要在以下部分中向域.yml 檔案添加intents, actions and responses:

intents:

  - greet

  - bye

  - thank

responses:

  utter_noworries:

    - text: No worries!

  utter_greet:

    - text: Hi

  utter_bye:

    - text: Bye!

Finally, we’ll copy over some NLU data from Sara into our nlu.md file (more can be found here):

最後,我們将從 Sara 複制一些 NLU 資料到我們的nlu.md檔案:

## intent:greet- Hi- Hey- Hi bot- Hey bot- Hello- Good morning- hi again- hi folks

## intent:bye- goodbye- goodnight- good bye- good night- see ya- toodle-oo- bye bye- gotta go- farewell

## intent:thank- Thanks- Thank you- Thank you so much- Thanks bot- Thanks for that- cheers

You can now train a first model and test the bot, by running the following commands:

現在,您可以通過運作以下指令來訓練第一個模型并測試自動程式:

rasa train

rasa shell

This bot should now be able to reply to the intents we defined consistently, and in any order.

此機器人現在應該能夠以任何順序回複我們定義的意圖。

For example:

While it’s good to test the bot interactively, we should also add end to end test cases that can later be included as part of a CI/CD system. End-to-end test conversations include NLU data, so that both components of Rasa can be tested. The file tests/conversation_tests.md contains example test conversations. Delete all the test conversations and replace them with some test conversations for your assistant so far:

雖然以互動方式測試自動程式是好事,但我們還應添加可稍後作為 CI/CD 系統一部分的端到端測試用例。端到端測試對話包括 NLU 資料,以便可以測試 Rasa 的兩個元件。tests/conversation_tests.md 包含示例測試會話。删除之前所有測試對話,并将其替換為新的一些測試對話:

## greet + goodbye* greet: Hi!

  - utter_greet* bye: Bye

  - utter_bye

## greet + thanks* greet: Hello there

  - utter_greet* thank: thanks a bunch

  - utter_noworries

## greet + thanks + goodbye* greet: Hey

  - utter_greet* thank: thank you

  - utter_noworries* bye: bye bye

  - utter_bye

To test our model against the test file, run the command:

要針對測試檔案測試我們的模型,請運作以下指令:

rasa test --stories tests/conversation_tests.md

The test command will produce a directory named results. It should contain a file called failed_stories.md, where any test cases that failed will be printed. It will also specify whether it was an NLU or Core prediction that went wrong. As part of a CI/CD pipeline, the test option --fail-on-prediction-errors can be used to throw an exception that stops the pipeline.

test指令将生成一個名為results的目錄。它應該包含一個名為 failed_stories.md 的檔案,其中将列印任何對話失敗的測試用例。它還将指出出錯的是 NLU 還是 Core 預測出錯。作為 CI/CD 管道的一部分,測試選項 --fail-on-prediction-errors 可用于抛出停止管道的異常。

Response Selectors 響應選擇器

The ResponseSelector NLU component is designed to make it easier to handle dialogue elements like Small Talk and FAQ messages in a simple manner. By using the ResponseSelector, you only need one story to handle all FAQs, instead of adding new stories every time you want to increase your bot’s scope.

ResponseSelector  NLU 元件旨在更輕松地以簡單的方式處理對話元素,如小談話和常見問題消息。通過使用響應程式,您隻需要一個故事來處理所有常見問題解答,而不是每次增加機器人範圍的時候還需要添加新故事。

People often ask Sara different questions surrounding the Rasa products, so let’s start with three intents: ask_channels, ask_languages, and ask_rasax. We’re going to copy over some NLU data from the Sara training data into our nlu.md. It’s important that these intents have an faq/ prefix, so they’re recognised as the faq intent by the ResponseSelector:

人們經常問Sara圍繞Rasa産品的不同問題,是以讓我們從三個意圖開始:ask_channels,ask_languages和ask_rasax。我們将從 Sara 教育訓練資料中複制一些 NLU 資料導入到nlu.md。具有 faq/字首非常重要,ResponseSelector  将它們識别為 faq 意圖:

## intent: faq/ask_channels- What channels of communication does rasa support?- what channels do you support?- what chat channels does rasa uses- channels supported by Rasa- which messaging channels does rasa support?

## intent: faq/ask_languages- what language does rasa support?- which language do you support?- which languages supports rasa- can I use rasa also for another laguage?- languages supported

## intent: faq/ask_rasax- I want information about rasa x- i want to learn more about Rasa X- what is rasa x?- Can you tell me about rasa x?- Tell me about rasa x- tell me what is rasa x

Next, we’ll need to define the responses associated with these FAQs in a new file called responses.md in the data/ directory:

接下來,我們需要在data/ 目錄中responses.md中定義常見問題相關的響應回複:

## ask channels* faq/ask_channels

  - We have a comprehensive list of [supported connectors](https://rasa.com/docs/core/connectors/), but if

    you don't see the one you're looking for, you can always create a custom connector by following

    [this guide](https://rasa.com/docs/rasa/user-guide/connectors/custom-connectors/).

## ask languages* faq/ask_languages

  - You can use Rasa to build assistants in any language you want!

## ask rasa x* faq/ask_rasax

 - Rasa X is a tool to learn from real conversations and improve your assistant. Read more [here](https://rasa.com/docs/rasa-x/)

The ResponseSelector should already be at the end of the NLU pipeline in our config.yml:

ResponseSelector 應該配置在 config.yml中的 NLU 管道的末尾:

language: enpipeline:

  - name: WhitespaceTokenizer

  - name: RegexFeaturizer

  - name: LexicalSyntacticFeaturizer

  - name: CountVectorsFeaturizer

  - name: CountVectorsFeaturizer

    analyzer: "char_wb"

    min_ngram: 1

    max_ngram: 4

  - name: DIETClassifier

    epochs: 100

  - name: EntitySynonymMapper

  - name: ResponseSelector

    epochs: 100

Now that we’ve defined the NLU side, we need to make Core aware of these changes. Open your domain.yml file and add the faq intent:

現在,我們已經定義了 NLU 端的内容,我們需要讓 Core 意識到這些更改。打domain.yml 檔案并添加 faq 意圖:

intents:

  - greet

  - bye

  - thank

  - faq

We’ll also need to add a retrieval action, which takes care of sending the response predicted from the ResponseSelector back to the user, to the list of actions. These actions always have to start with the respond_ prefix:

我們還需要添加一個retrieval action檢索操作,該操作負責将來自響應ResponseSelector 的響應發送回使用者,并将其發送到操作清單中。這些操作始終必須從字首respond_開始:

actions:

  - respond_faq

Next we’ll write a story so that Core knows which action to predict:

接下來,我們将寫一個story ,以便 Core 知道要預測的操作:

## Some question from FAQ* faq

    - respond_faq

This prediction is handled by the MemoizationPolicy, as we described earlier.

After all of the changes are done, train a new model and test the modified FAQs:

正如我們前面描述的那樣此預測由MemoizationPolicy處理。

完成所有更改後,訓練新模型并測試修改後的常見問題解答:

rasa train

rasa shell

At this stage it makes sense to add a few test cases to your test_stories.md file again:

在此階段,可以再次向 test_stories.md 檔案添加一些測試用例:

## ask channels* faq: What messaging channels does Rasa support?

  - respond_faq

## ask languages* faq: Which languages can I build assistants in?

  - respond_faq

## ask rasa x* faq: What’s Rasa X?

  - respond_faq

You can read more in this blog post and the Retrieval Actions page.

Using the features we described in this tutorial, you can easily build a context-less assistant. When you’re ready to enhance your assistant with context, check out Building a contextual assistant.

使用本教程中介紹的功能,您可以輕松地建構無上下文助手。當您準備好使用上下文增強助手時,請檢視Building a contextual assistant.。

Note

Here’s a minimal checklist of files we modified to build a basic FAQ assistant:

以下是我們建構基本常見問題助手所需要檔案的最小清單:

data/nlu.md: Add NLU training data for faq/ intents

為faq/ 意圖增加NLU訓練資料

data/responses.md: Add responses associated with faq/ intents

 faq/ intents關聯回複

config.yml: Add ReponseSelector in your NLU pipeline

為NLU通道增加ReponseSelector 

domain.yml: Add a retrieval action respond_faq and intent faq

增加一個檢索respond_faq 和意圖faq

data/stories.md: Add a simple story for FAQs

FAQs增加一個簡單的story

test_stories.md: Add E2E test stories for your FAQs

FAQs增加E2E的測試story

Building a contextual assistant 建構上下文助理

Whether you’ve just created an FAQ bot or are starting from scratch, the next step is to expand your bot to handle contextual conversations.

無論您是剛剛建立了FAQ機器人還是從頭開始,下一步是擴充自動程式以處理上下文對話。

In this tutorial we’re going to cover a variety of topics:

在本教程中,我們将介紹以下的幾個主題:

Handling business logic

Handling unexpected user input

Failing gracefully

More complex contextual conversations

處理業務邏輯

處理意外使用者輸入

優雅地處理失敗

更複雜的上下文對話

Please make sure you’ve got all the data from the Building a simple FAQ assistant section before starting this part. You will need to make some adjustments to your configuration file, since we now need to pay attention to context:

在開始此部分之前,請確定你已經從"建構一個簡單的FAQ助理"章節中獲得所需要的資料和代碼。因為我們現在需要注意上下文的部分,您需要對配置檔案進行一些調整,:

policies:- name: MemoizationPolicy- name: MappingPolicy

We removed the max_history: 1 configuration. The default is 5, meaning Core will pay attention to the past 5 turns when making a prediction (see explanation of max history).

我們删除了max_history:1 配置。預設值為 5,這意味着 Core 在進行預測時将注意過去 5 個對話輪次(請參閱max history最大曆史記錄的解釋)。

Handling business logic 處理業務邏輯

A lot of conversational assistants have user goals that involve collecting a bunch of information from the user before being able to do something for them. This is called slot filling. For example, in the banking industry you may have a user goal of transferring money, where you need to collect information about which account to transfer from, whom to transfer to and the amount to transfer. This type of behavior can and should be handled in a rule based way, as it is clear how this information should be collected.

許多會話助理都有使用者目标,這些目标涉及在能夠為他們執行某一操作之前,先從使用者那裡收集大量資訊。這稱為插槽填充。例如,在銀行業中,您可能有一個使用者轉賬的目标,即您需要收集有關要從哪個賬戶轉移、向誰轉賬以及轉賬金額的資訊。這種類型的行為可以而且應該以基于規則的方式處理,因為應該如何收集此資訊。

For this type of use case, we can use Forms and our FormPolicy. The FormPolicy works by predicting the form as the next action until all information is gathered from the user.

對于這種類型的用例,我們可以使用窗體Forms 和表單政策FormPolicy。FormPolicy 的工作原理是用表單内容來預測為下一個操作,直到從使用者那裡收集所有所需要的資訊。

As an example, we will build out the SalesForm from Sara. The user wants to contact our sales team, and for this we need to gather the following pieces of information:

例如,我們将從 Sara 建構銷售表單SalesForm 。使用者希望聯系我們的銷售團隊,為此我們需要收集以下資訊:

Their job

Their bot use case

Their name

Their email

Their budget

Their company

他們的工作

他們的機器人用例

他們的名字

他們的電子郵件

他們的預算

他們的公司

We will start by defining the SalesForm as a new class in the file called actions.py. The first method we need to define is the name, which like in a regular Action returns the name that will be used in our stories:

我們将首先将 SalesForm 定義為一個新的類class,名為"actions.py"。SalesForm這個類我們需要定義的第一個方法是名稱name,就像在正常操作中一樣,它傳回将在我們的故事中使用的名稱:

from rasa_sdk.forms import FormAction

class SalesForm(FormAction):

    """Collects sales information and adds it to the spreadsheet"""

    def name(self):

        return "sales_form"

Next we have to define the required_slots method which specifies which pieces of information to ask for, i.e. which slots to fill.

接下來,我們必須定義required_slots(必填詞槽),該方法指定要請求哪些資訊,即要填充哪些詞槽。

@staticmethoddef required_slots(tracker):

    return [

        "job_function",

        "use_case",

        "budget",

        "person_name",

        "company",

        "business_email",

        ]

Note: you can customise the required slots function not to be static. E.g. if the job_function is a developer, you could add a required_slot about the users experience level with Rasa

注意:您可以自定義所需的詞槽slots 功能,詞槽slots 可以不是一個靜态變量。例如,如果job_function的值是開發者developer,您可以添加一個required_slot,用來增加了解 使用者對Rasa 的體驗級别

Once you’ve done that, you’ll need to specify how the bot should ask for this information. This is done by specifying utter_ask_{slotname} responses in your domain.yml file. For the above we’ll need to specify the following:

完成此工作後,您需要指定自動程式應如何請求此資訊。這是通過在domain.yml 中utter_ask_{slotname} 來指定響應。對于上面例子,我們需要指定以下内容:

utter_ask_business_email:

  - text: What's your business email?utter_ask_company:

  - text: What company do you work for?utter_ask_budget:

  - text: "What's your annual budget for conversational AI? utter_ask_job_function:

  - text: "What's your job? utter_ask_person_name:

  - text: What's your name?utter_ask_use_case:

  - text: What's your use case?

We’ll also need to define all these slots in our domain.yml file:

我們同僚需要在domain.yml檔案中定義這些詞槽

slots:

  company:

    type: unfeaturized

  job_function:

    type: unfeaturized

  person_name:

    type: unfeaturized

  budget:

    type: unfeaturized

  business_email:

    type: unfeaturized

  use_case:

    type: unfeaturized

Going back to our Form definition, we need to define the submit method as well, which will do something with the information the user has provided once the form is complete:

回到我們的表單定義,我們還需要定義submit 方法,該方法将在表單完成後對使用者提供的資訊執行一些操作:

def submit(

        self,

        dispatcher: CollectingDispatcher,

        tracker: Tracker,

        domain: Dict[Text, Any],

    ) -> List[Dict]:

    dispatcher.utter_message("Thanks for getting in touch, we’ll contact you soon")

    return []

In this case, we only tell the user that we’ll be in touch with them, however usually you would send this information to an API or a database. See the rasa-demo for an example of how to store this information in a spreadsheet.

在這個情景中,我們會回複告訴使用者我們将與他們聯系,同時我們會将此資訊發送到 API 或資料庫。有關如何在電子表格中存儲此資訊的示例,請參閱 rasa-demo 。

We’ll need to add the form we just created to a new section in our domain.yml file:

我們需要将剛建立的表單定義添加到domain.yml檔案:

forms:

  - sales_form

We also need to create an intent to activate the form, as well as an intent for providing all the information the form asks the user for. For the form activation intent, we can create an intent called contact_sales. Add the following training data to your nlu file:

我們還需要建立一個意圖intent 來激活表單,以及提供表單要求使用者提供的所有資訊的意圖。對于表單激活意圖,我們可以建立一個名為"contact_sales。将以下訓練資料添加到 nlu 檔案中:

## intent:contact_sales- I wanna talk to your sales people.- I want to talk to your sales people- I want to speak with sales- Sales- Please schedule a sales call- Please connect me to someone from sales- I want to get in touch with your sales guys- I would like to talk to someone from your sales team- sales please

You can view the full intent here)

你可以點選檢視完整的意圖

We will also create an intent called inform which covers any sort of information the user provides to the bot. The reason we put all this under one intent, is because there is no real intent behind providing information, only the entity is important. Add the following data to your NLU file:

我們還将建立一個名為"inform 通知"的意圖,它涵蓋了使用者向機器人提供的任何類型的資訊。我們之是以把這一切放在一個意圖下,是因為這些提供資訊背後沒有真正的意圖,隻有實體(【】裡面的内容)才是重要的。将以下資料添加到 NLU 檔案中:

## intent:inform- [100k](budget)- [100k](budget)- [240k/year](budget)- [150,000 USD](budget)- I work for [Rasa](company)- The name of the company is [ACME](company)- company: [Rasa Technologies](company)- it's a small company from the US, the name is [Hooli](company)- it's a tech company, [Rasa](company)- [ACME](company)- [Rasa Technologies](company)- [[email protected]](business_email)- [[email protected]](business_email)- [[email protected]](business_email)- [[email protected]](business_email)- [my email is [email protected]](business_email)- [engineer](job_function)- [brand manager](job_function)- [marketing](job_function)- [sales manager](job_function)- [growth manager](job_function)- [CTO](job_function)- [CEO](job_function)- [COO](job_function)- [John Doe](person_name)- [Jane Doe](person_name)- [Max Mustermann](person_name)- [Max Meier](person_name)- We plan to build a [sales bot](use_case) to increase our sales by 500%.- we plan to build a [sales bot](use_case) to increase our revenue by 100%.- a [insurance tool](use_case) that consults potential customers on the best life insurance to choose.- we're building a [conversational assistant](use_case) for our employees to book meeting rooms.

Note

Entities like business_email and budget would usually be handled by pretrained entity extractors (e.g. DucklingHTTPExtractor or SpacyEntityExtractor), but for this tutorial we want to avoid any additional setup.

像 business_email 和budget 這樣的實體通常由預先訓練的實體提取器(例如DucklingHTTPExtractor或 SpacyEntityExtractor)處理,但對于本教程,我們希望避免任何其他設定。

The intents and entities will need to be added to your domain.yml file as well:

意圖和實體也需要添加到您的domain.yml  檔案中:

intents:

  - greet

  - bye

  - thank

  - faq

  - contact_sales

  - inform

entities:

  - company

  - job_function

  - person_name

  - budget

  - business_email

  - use_case

A story for a form is very simple, as all the slot collection form happens inside the form, and therefore doesn’t need to be covered in your stories. You just need to write a single story showing when the form should be activated. For the sales form, add this story to your stories.md file:

form表單的的story非常簡單,因為所有詞槽slot的集合都發生在表單中,是以不需要在story中介紹。您隻需要寫一個story,顯示何時應激活表單。現在把sales form的story添加到stories.md中:

## sales form* contact_sales

    - sales_form                   <!--Run the sales_form action-->

    - form{"name": "sales_form"}   <!--Activate the form-->

    - form{"name": null}           <!--Deactivate the form-->

As a final step, let’s add the FormPolicy to our config file:

最後,我們在配置檔案中加入FormPolicy

policies:

  - name: MemoizationPolicy

  - name: KerasPolicy

  - name: MappingPolicy

  - name: FormPolicy

At this point, you already have a working form, so let’s try it out. Make sure to uncomment the action_endpoint in your endpoints.yml to make Rasa aware of the action server that will run our form:

此時,您已經有一個工作表單,是以讓我們嘗試一下。確定取消了action_endpoint.yml檔案中action_endpoint的注釋,確定 Rasa 能夠在運作表單的時候能夠觸發服務。

action_endpoint:

 url: "http://localhost:5055/webhook"

Then start the action server in a new terminal window:

啟動服務

rasa run actions

Then you can retrain and talk to your bot:

你可以重新訓練并跟機器人對話

rasa train

rasa shell

This simple form will work out of the box, however you will likely want to add a bit more capability to handle different situations. One example of this is validating slots, to make sure the user provided information correctly (read more about it here).

這個簡單的表單将開箱即用,但你可能想要添加更多的能力來處理不同的情況。其中一個示例是詞槽Slots驗證,以確定使用者正确提供資訊(在此處閱讀有關它的資訊) 。

Another example is that you may want to fill slots from things other than entities of the same name. E.g. for the “use case” situation in our Form, we would expect the user to type a full sentence and not something that you could necessarily extract as an entity. In this case we can make use of the slot_mappings method, where you can describe what your entities should be extracted from. Here we can use the from_text method to extract the users whole message:

另一個示例是,您可能希望從同名實體以外的其他事物中填充詞槽。例如,對于表單中的"use case"情況,我們希望使用者鍵入完整的句子,而不是一些簡單的實體單詞。在這種情況下,我們可以使用 slot_mappings方法,其中您可以描述應從中提取哪些實體。在這裡,我們可以from_text提取使用者的全部消息:

def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict[Text, Any]]]]:

    """A dictionary to map required slots to    - an extracted entity    - intent: value pairs    - a whole message    or a list of them, where a first match will be picked"""

    return {"use_case": self.from_text(intent="inform")}

Now our bot will extract the full user message when asking for the use case slot, and we don’t need to use the use_case entity defined before.

現在,我們的機器人将在請求用例詞槽時提取完整的使用者消息,我們不需要使用以前定義的use_case實體。

All of the methods within a form can be customized to handle different branches in your business logic. Read more about this here. However, you should make sure not to handle any unhappy paths inside the form. These should be handled by writing regular stories, so your model can learn this behavior.

form表單中的所有方法都可以根據業務邏輯定義成不同的分支。在此處閱讀有關此内容的更多資訊。但是,您應該確定不要處理表單中任何不正确的路徑(非監督式學習),這些應該通過編寫正常stories來處理,這樣您的模型就可以學習此行為。

Note

Here’s a minimal checklist of files we modified to handle business logic using a form action:

我們使用表單定義業務邏輯所需要的最小檔案清單:

actions.py:

Define the form action, including the required_slots, slot_mappings and submit methods

定義表單動作,包含required_slots, slot_mappings and submit 方法

data/nlu.md:

Add examples for an intent to activate the form

為意圖增加用例來啟動form

Add examples for an inform intent to fill the form

為意圖增加用例來填寫表單

domain.yml:

Add all slots required by the form

增加必填詞槽

Add utter_ask_{slot} responses for all required slots

增加必填詞槽的utter_ask_{slot} 響應

Add your form action to the forms section

增加form動作

Add all intents and entities from your NLU training data

增加所有意圖和實體到NLU訓練資料

data/stories.md:

Add a story for the form

為form增加story

config.yml:

Add the FormPolicy to your policies

增加FormPolicy 

Add entity extractors to your pipeline

在通道定義裡增加實體分析器entity extractors

endpoints.yml: Define the action_endpoint

定義action_endpoint

Handling unexpected user input 處理意外使用者輸入

All expected user inputs should be handled by the form we defined above, i.e. if the user provides the information the bot asks for. However, in real situations, the user will often behave differently. In this section we’ll go through various forms of “interjections” and how to handle them within Rasa.

如果使用者按照機器人要求的資訊提供資訊,那所有預期的使用者輸入都應由我們上面定義的表單處理。但是在實際情況下,使用者的行為通常會不同。在本節中,我們将介紹各種形式的"插話interjections",以及如何在 Rasa 中處理它們。

The decision to handle these types of user input should always come from reviewing real conversations. You should first build part of your assistant, test it with real users (whether that’s your end user, or your colleague) and then add what’s missing. You shouldn’t try to implement every possible edge case that you think might happen, because in the end your users may never actually behave in that way. Rasa X is a tool that can help you review conversations and make these types of decisions.

處理這些類型的使用者輸入的決定應始終來自檢視實際對話。您應該首先建構機器人的一部分,使用真實使用者(無論是最終使用者還是同僚)進行測試,然後添加缺少内容。您不應嘗試先定義實作您認為可能發生的每一個可能的邊緣情況,因為最終您的使用者可能永遠不會真正以這樣的方式行事。Rasa X 是一個工具,可幫助您檢視對話并做出這些類型的決策。

Generic interjections 通用插話

If you have generic interjections that should always have the same single response no matter the context, you can use the Mapping Policy to handle these. It will always predict the same action for an intent, and when combined with a forgetting mechanism, you don’t need to write any stories either.

如果具有通用的插話,無論上下文如何,它們應始終具有相同的單個響應,可以使用映射政策Mapping Policy 來處理這些響應。它将始終預測意圖的相同操作,并且與遺忘機制結合使用時,您也不需要編寫任何故事。

For example, let’s say you see users having conversations like the following one with your assistant, where they write a greeting in the middle of a conversation - maybe because they were gone for a few minutes:

例如,假設您看到使用者與助手進行如下對話,他們在對話中寫一個問候語Hi again - 可能是因為他們離開對話了幾分鐘:

The greet intent is a good example where we will always give the same response and yet we don’t want the intent to affect the dialogue history. To do this, the response must be an action that returns the UserUtteranceReverted() event to remove the interaction from the dialogue history.

問候意圖是一個很好的例子,我們将永遠給予相同的回應,但我們不想意圖影響對話曆史。是以響應必須是傳回 UserUtteranceReverted() 事件以從對話曆史記錄中删除互動的操作。

First, open the domain.yml file and modify the greet intent and add a new block `actions` in the file, next, add the action_greet as shown here:

首先,打開domain.yml檔案并修改問候意圖,并在檔案中添加新塊"actions",接下來,添加action_greet如下所示:

intents:

  - greet: {triggers: action_greet}

  - bye

  - thank

  - faq

  - contact_sales

  - inform

actions:

  - action_greet

Remove any stories using the “greet” intent if you have them.

删除任何跟“greet”有關的意圖

Next, we need to define action_greet. Add the following action to your actions.py file:

現在我們需要定義action_greet。 在actions.py增加代碼:

from rasa_sdk import Actionfrom rasa_sdk.events import UserUtteranceReverted

class ActionGreetUser(Action):"""Revertible mapped action for utter_greet"""

def name(self):

    return "action_greet"

def run(self, dispatcher, tracker, domain):

    dispatcher.utter_template("utter_greet", tracker)

    return [UserUtteranceReverted()]

To test the modified intents, we need to re-start our action server:

測試修改後的意圖,我們需要重新開機我們的服務

rasa run actions

Then we can retrain the model, and try out our additions:

重新訓練并啟動

rasa train

rasa shell

FAQs are another kind of generic interjections that should always get the same response. For example, a user might ask a related FAQ in the middle of filling a form:

FAQs常見問題是另一種通用的插話,應始終得到相同的響應。例如,使用者可能會在填寫表單時詢問相關的FAQ 常見問題解答:

To handle FAQs defined with retrieval actions, you can add a simple story that will be handled by the MemoizationPolicy:

若要處理使用檢索操作定義的FAQs 常見問題,可以添加一個簡單的故事,由"MemoizationPolicy記憶政策"來處理。

## just sales, continue* contact_sales

    - sales_form

    - form{"name": "sales_form"}* faq

    - respond_faq

    - sales_form

    - form{"name": null}

This will break out of the form and deal with the users FAQ question, and then return back to the original task. For example:

這将打破表單并處理使用者常見問題解答問題,然後傳回到原始任務。例如:

If you find it difficult to write stories in this format, you can always use Interactive Learning to help you create them.

如果您發現很難以這種格式編寫故事,您始終可以使用 Interactive Learning 互動式學習來幫助建立它們。

As always, make sure to add an end to end test case to your test_stories.md file.

與之前一樣,請確定将端到端測試用例添加到 test_stories.md 檔案中。

Contextual questions 上下文問題

You can also handle contextual questions, like the user asking the question “Why do you need to know that”. The user could ask this based on a certain slot the bot has requested, and the response should differ for each slot. For example:

您還可以處理上下文問題,例如使用者詢問"為什麼您需要了解這一點"的問題。使用者可以根據機器人請求的某一詞槽詢問此問題,并且每個詞槽的響應應有所不同。例如:

To handle this, we need to make the requested_slot featurized, and assign it the categorical type:

為了處理這種情況,我們需要使requested_slot ,并為其配置設定分類類型:

slots:

  requested_slot:

    type: categorical

    values:

      - business_email

      - company

      - person_name

      - use_case

      - budget

      - job_function

This means that Core will pay attention to the value of the slot when making a prediction (read more about other featurized slots), whereas unfeaturized slots are only used for storing information. The stories for this should look as follows:

這意味着 Core 在進行預測時将注意詞槽的值而非僅用于存儲資訊。(閱讀更多有關featurized slots資訊),對此應如下所示:

## explain email* contact_sales

    - sales_form

    - form{"name": "sales_form"}

    - slot{"requested_slot": "business_email"}* explain

    - utter_explain_why_email

    - sales_form

    - form{"name": null}

## explain budget* contact_sales

    - sales_form

    - form{"name": "sales_form"}

    - slot{"requested_slot": "budget"}* explain

    - utter_explain_why_budget

    - sales_form

    - form{"name": null}

We’ll need to add the intent and utterances we just added to our domain.yml file:

我們需要把意圖intent 和話語utterances 添加到domain.yml  檔案中:

intents:- greet: {triggers: action_greet_user}- bye- thank- faq- explain

responses:

  utter_explain_why_budget:

  - text: We need to know your budget to recommend a subscription

  utter_explain_why_email:

  - text: We need your email so we can contact you

Finally, we’ll need to add some NLU data for the explain intent:

最後我們需要添加一些 NLU 資料以說明目的:

## intent:explain- why- why is that- why do you need it- why do you need to know that?- could you explain why you need it?

Then you can retrain your bot and test it again:

重新訓練,再測一次。

rasa train

rasa shell

Note

You will need to add a story for each of the values of the requested_slot slot for the bot to handle every case of “Why do you need to know that”

您将需要為每一個機器人添加一個story包含requested_slot詞槽,來處理"為什麼需要知道"的情景。

Don’t forget to add a few end to end stories to your test_stories.md for testing as well.

不要忘記在您的 test_stories.md 中添加一些端到端用例測試。

Note

Here’s a minimal checklist of of files we modified to handle unexpected user input:

以下是我們為處理意外使用者輸入最小修改檔案清單:

actions.py: Define action_greet  

定義action_greet

data/nlu.md: Add training data for an explain intent

為explain 意圖增加訓練資料

domain.yml:

Map intent greet to action_greet_user

将greet 意圖定位到action_greet_user

Make requested_slot a categorical slot with all required slots as values

增加requested_slot 詞槽定義所需的值

Add the explain intent

增加explain 意圖

Add responses for contextual question interruptions

增加上下文問題中斷的回應

data/stories.md:

Remove stories using mapped intents if you have them

删除有已經映射需要修改的意圖的故事

Add stories with FAQ & contextual interruptions in the middle of filling a form

在填寫表單時增加具有常見問題和上下文中斷的故事

Failing gracefully 優雅的處理失敗情況

Even if you design your bot perfectly, users will inevitably say things to your assistant that you did not anticipate. In these cases, your assistant will fail, and it’s important you ensure it does so gracefully.

即使您完美地設計了您的機器人,使用者也不可避免地會向您的機器人助手說出您沒有預料到的事情。在這些情況下,您的助手将回答失敗,重要的是您確定它這樣做優雅。

Fallback policy  回退政策

One of the most common failures is low NLU confidence, which is handled very nicely with the TwoStageFallbackPolicy. You can enable it by adding the following to your configuration file,

TwoStageFallbackPolicy政策可以很好的處理NLU故障最常見的錯誤。您可以通過向配置檔案中添加以下内容來啟用它,

policies:

  - name: TwoStageFallbackPolicy

    nlu_threshold: 0.8

and adding the out_of_scope intent to your domain.yml file:

增加out_of_scope意圖到domain.yml

intents:- out_of_scope

When the nlu confidence falls below the defined threshold, the bot will prompt the user to rephrase their message. If the bot isn’t able to get their message three times, there will be a final action where the bot can e.g. hand off to a human.

當 nlu 置信度低于定義的門檻值時,機器人将提示使用者重新表述其消息。如果機器人不能收到他們的資訊三次,将會觸發一個最後的行動,例如交給人類。

To try this out, retrain your model and send a message like “order me a pizza” to your bot:

要嘗試一下, 重新訓練你的模型, 并發送一條消息, 如 "給我訂購比薩餅" 到你的機器人:

rasa train

rasa shell

There are also a bunch of ways in which you can customise this policy. In Sara, our demo bot, we’ve customized it to suggest intents to the user within a certain confidence range to make it easier for the user to give the bot the information it needs.

還有一系列自定義此政策的方法。我們已經在Sara的示範機器人自定義了一些政策,我們自定義他去給使用者做一些建議性意向問題,使得使用者在一定的信心範圍内,更容易給機器人一些所需要的資訊

This is done by customizing the action ActionDefaultAskAffirmation as shown in the Sara rasa-demo action server We define some intent mappings to make it more intuitive to the user what an intent means.

這是通過自定義在Sara rasa-demo action server中ActionDefaultAskAffirmation,我們定義了一些意圖映射,使其對使用者的意圖的含義更加直覺。

Out of scope intent 範圍外的意圖

It is good practice to also handle questions you know your users may ask, but for which you haven’t necessarily implemented a user goal yet.

您尚未實作使用者目标的情況下,處理你知道使用者可能會問的問題是一種好的做法。

You can define an out_of_scope intent to handle generic out of scope requests, like “I’m hungry” and have the bot respond with a default message like “Sorry, I can’t handle that request”:

您可以定義out_of_scope來處理泛型範圍外請求的意圖,如"我餓了",并讓機器人響應預設消息,如"對不起,我不能處理該請求":

* out_of_scope

  utter_out_of_scope

We’ll need to add NLU data for the out_of_scope intent as well:

增加NLU資料和out_of_scope

## intent:out_of_scope- I want to order food- What is 2 + 2?- Who’s the US President?- I need a job

And finally we’ll add a response to our domain.yml file:

增加響應到domain.yml 

responses:

  utter_out_of_scope:

  - text: Sorry, I can’t handle that request.

We can now re-train, and test this addition

重新訓練,測試這個部分

rasa train

rasa shell

Going one step further, if you observe your users asking for certain things, that you’ll want to turn into a user goal in future, you can handle these as separate intents, to let the user know you’ve understood their message, but don’t have a solution quite yet. E.g., let’s say the user asks “I want to apply for a job at Rasa”, we can then reply with “I understand you’re looking for a job, but I’m afraid I can’t handle that skill yet.”

更進一步,如果您觀察到使用者詢問某些内容,即将來希望将其轉化為使用者目标,您可以作為單獨的意圖處理這些内容,讓使用者知道您已經了解了他們的消息,但還沒有完全的解決方案。例如,假設使用者問"我想申請Rasa的工作",然後我們可以回答"我知道你正在找工作,但恐怕我還不能處理這種技能。

* ask_job

  utter_job_not_handled

Note

Here’s a minimal checklist of files we modified to help our assistant fail gracefully:

以下是我們修改的最小檔案清單:

data/nlu.md:

Add training data for the out_of_scope intent & any specific out of scope intents that you want to handle seperately

為out_of_scope意圖和任何你需要單獨處理的超出範圍的意圖增加訓練資料

data/stories.md:

Add stories for any specific out of scope intents

為超出範圍的意圖增加stories

domain.yml:

Add the out_of_scope intent & any specific out of scope intents

增加out_of_scope和其他超出範圍的意圖

Add an utter_out_of_scope response & responses for any specific out of scope intents

增加utter_out_of_scope 回複

actions.py:

Customise ActionDefaultAskAffirmation to suggest intents for the user to choose from

自定義ActionDefaultAskAffirmation來建議使用者意圖選擇

config.yml:

Add the TwoStageFallbackPolicy to the policies section

增加政策TwoStageFallbackPolicy

More complex contextual conversations 更複雜的上下文對話

Not every user goal you define will fall under the category of business logic. For the other cases you will need to use stories and context to help the user achieve their goal.

不是您定義的每個使用者目标都屬于業務邏輯類别。對于其他情況需要使用更多的故事情景和上下文來幫助使用者實作他們的目标。

If we take the example of the “getting started” skill from Sara, we want to give them different information based on whether they’ve built an AI assistant before and are migrating from a different tool etc. This can be done quite simply with stories and the concept of max history.

如果我們以 Sara 的"入門"技能為例,我們希望根據他們之前是否建構了 AI 助手以及是否從其他工具遷移等,為他們提供不同的資訊。這可以通過更多的故事stories 和最大曆史 max history的概念來完成。

 ## new to rasa + built a bot before

 * how_to_get_started

   - utter_getstarted   - utter_first_bot_with_rasa * affirm   - action_set_onboarding   - slot{"onboarding": true}   - utter_built_bot_before * affirm

   - utter_ask_migration

 * deny

   - utter_explain_rasa_components

   - utter_rasa_components_details

   - utter_ask_explain_nlucorex

 * affirm

   - utter_explain_nlu

   - utter_explain_core

   - utter_explain_x

   - utter_direct_to_step2

 ## not new to rasa + core

 * how_to_get_started

   - utter_getstarted   - utter_first_bot_with_rasa * deny   - action_set_onboarding   - slot{"onboarding": false}   - utter_ask_which_product * how_to_get_started{"product": "core"}

   - utter_explain_core

   - utter_anything_else

The above example mostly leverages intents to guide the flow, however you can also guide the flow with entities and slots. For example, if the user gives you the information that they’re new to Rasa at the beginning, you may want to skip this question by storing this information in a slot.

上述示例主要利用意圖來引導流,但您也可以使用實體和插槽引導流。例如,如果使用者在開頭為您提供了 Rasa 的新規定,您可能希望通過将此資訊存儲在詞槽中來跳過此問題。

* how_to_get_started{"user_type": "new"}

  - slot{"user_type":"new"}

  - action_set_onboarding

  - slot{"onboarding": true}

  - utter_getstarted_new

  - utter_built_bot_before

For this to work, keep in mind that the slot has to be featurized in your domain.yml file. This time we can use the text slot type, as we only care about whether the slot was set or not.

要想這樣做,請記住,詞槽必須在你的domain.yml檔案中定義。這一次,我們可以使用文本text 詞槽類型,因為我們隻關心詞槽是否設定。

AugmentedMemoizationPolicy 增強化政策

To make your bot more robust to interjections, you can replace the MemoizationPolicy with the AugmentedMemoizationPolicy. It works the same way as the MemoizationPolicy, but if no exact match is found it additionally has a mechanism that forgets a certain amount of steps in the conversation history to find a match in your stories (read more here)

若要使機器人對插話更加可靠,您可以将記憶政策MemoizationPolicy 替換為增強化政策AugmentedMemoizationPolicy。它的工作方式與記憶政策相同,但如果沒有發現完全比對,它另外有一個機制,忘記對話曆史記錄中的一定數量的步驟,以在您的故事中查找比對項(在此處閱讀更多内容)

Using ML to generalise 使用機器學習概況

Aside from the more rule-based policies we described above, Core also has some ML policies you can use. These come in as an additional layer in your policy configuration, and only jump in if the user follows a path that you have not anticipated. It is important to understand that using these policies does not mean letting go of control over your assistant. If a rule based policy is able to make a prediction, that prediction will always have a higher priority (read more here) and predict the next action. The ML based policies give your assistant the chance not to fail, whereas if they are not used your assistant will definitely fail, like in state machine based dialogue systems.

除了我們上面描述的基于規則的更多政策外,Core 還有一些可以使用的 ML 政策。這些作為政策配置中的額外層進入,并且僅在使用者遵循您未預料到的路徑時才加入。重要的是要明白使用這些政策并不意味着放棄對助手的控制。如果基于規則政策能夠做出預測,則該預測将始終具有更高的優先級(在此處閱讀更多内容)并預測下一個操作。基于 ML 的政策讓您的助手有機會不失敗,而如果不使用,您的助手肯定會失敗,就像在基于狀态機的對話系統中一樣。

These types of unexpected user behaviors are something our TEDPolicy deals with very well. It can learn to bring the user back on track after some interjections during the main user goal the user is trying to complete. For example, in the conversation below (extracted from a conversation on Rasa X):

這些類型的意外使用者行為是我們的 TEDPolicy 處理得很好。它可以學習在使用者嘗試完成的主要使用者目标期間進行一些插話後使使用者回到正軌。例如,在下面的對話中(摘自 Rasa X 上的對話):

## Story from conversation with a2baab6c83054bfaa8d598459c659d2a on November 28th 2019* greet

  - action_greet_user

  - slot{"shown_privacy":true}* ask_whoisit

  - action_chitchat* ask_whatspossible

  - action_chitchat* telljoke

  - action_chitchat* how_to_get_started{"product":"x"}

  - slot{"product":"x"}

  - utter_explain_x

  - utter_also_explain_nlucore* affirm

  - utter_explain_nlu

  - utter_explain_core

  - utter_direct_to_step2

Here we can see the user has completed a few chitchat tasks first, and then ultimately asks how they can get started with Rasa X. The TEDPolicy correctly predicts that Rasa X should be explained to the user, and then also takes them down the getting started path, without asking all the qualifying questions first.

Since the ML policy generalized well in this situation, it makes sense to add this story to your training data to continuously improve your bot and help the ML generalize even better in future. Rasa X is a tool that can help you improve your bot and make it more contextual.

在這裡,我們可以看到使用者已經完成了一些閑聊任務,然後最終詢問他們如何開始使用Rasa X。TEDPolicy 正确地預測Rasa X應該向使用者解釋,然後讓他們沿着入門路徑前進,而不首先詢問所有限定問題。

由于 ML 政策在此情況下推廣得很好,是以将這個故事添加到您的教育訓練資料中是有意義的,以持續改進您的機器人并幫助 ML 在将來更好地推廣。Rasa X 是一個工具,可以幫助您改進您的機器人,使其更具上下文。

Rasa 文檔 中英文翻譯版本 3 - Tutorial: Building Assistants

https://rasa.com/docs/rasa/user-guide/building-assistants/

Tutorial: Building Assistants  建立對話機器人助理

After following the basics of setting up an assistant in the Rasa Tutorial, we’ll now walk through building a basic FAQ chatbot and then build a bot that can handle contextual conversations.

FAQ是英文Frequently Asked Questions的縮寫

在學完了前面的教程基礎知識後,我們現在将演練建構一個基本的常見問題聊天機器人,然後建構一個可以處理上下文對話的機器人。

目錄

Building a simple FAQ assistant 建立FAQ 常見問題機器人助理

Memoization Policy 記憶政策

Response Selectors  響應選擇器

Building a contextual assistant   建構上下文助理

Handling business logic 處理業務邏輯

Handling unexpected user input 處理意外使用者輸入

Generic interjections 通用插話

Contextual questions 上下文問題

Failing gracefully 優雅地回複失敗問題

Fallback policy 回退政策

Out of scope intent 範圍外意圖處理

More complex contextual conversations 更複雜的上下文對話

AugmentedMemoizationPolicy 增強記憶政策

Using ML to generalise 使用ML機器學習來生成

Building a simple FAQ assistant 建立FAQ 常見問題機器人助手

FAQ assistants are the simplest assistants to build and a good place to get started. These assistants allow the user to ask a simple question and get a response. We’re going to build a basic FAQ assistant using features of Rasa designed specifically for this type of assistant.

常見問題助理是最簡單的助手,也是好的入門教程。這些助手允許使用者提出一個簡單的問題并得到答複。我們将使用 Rasa 專為此類助手設計的功能建構一個基本的常見問題解答助手。

In this section we’re going to cover the following topics:

這個章節我們覆寫一下内容

Responding to simple intents with the MemoizationPolicy

使用MemoizationPolicy回應簡單意圖對話

Handling FAQs using the ResponseSelector

使用ResponseSelector處理常見問題

We’re going to use content from Sara, the Rasa assistant that, amongst other things, helps the user get started with the Rasa products. You should first install Rasa using the Step-by-step Installation Guide and then follow the Rasa Tutorial to make sure you know the basics.

我們将使用來自Rasa機器人助手示例Sara 的内容和其他一些内容,幫助使用者開始使用 Rasa 産品。您應該首先使用分步安裝指南安裝 Rasa,然後按照 Rasa 教程操作,以確定了解基礎知識。

To prepare for this tutorial, we’re going to create a new directory and start a new Rasa project.

為了準備本教程,我們将建立一個新目錄,并開始一個新的 Rasa 項目。

mkdir rasa-assistant

rasa init

Let’s remove the default content from this bot, so that the nlu.md, stories.md and domain.yml files are empty.

我們需要删除預設生成的檔案内容,是以 nlu.md, stories.md domain.yml三個檔案是空的

Memoization Policy 記憶政策

The MemoizationPolicy remembers examples from training stories for up to a max_history of turns. The number of “turns” includes messages the user sent, and actions the assistant performed. For the purpose of a simple, context-less FAQ bot, we only need to pay attention to the last message the user sent, and therefore we’ll set that to 1.

MemoizationPolicy 記憶政策可以設定用幾輪對話的内容來進行訓練進行。

配置中用max_history标記來标記輪次(turns) 。

對話輪次的數量包括使用者發送的消息以及助手執行的操作。為了簡單、無上下文的常見問題程式,我們隻需要注意使用者發送的最後一條消息,是以我們将它設定為 1。

You can do this by editing your config.yml file as follows (you can remove TEDPolicy for now):

你可以修改config.yml來配置。(現在可以删除TEDPolicy )

policies:- name: MemoizationPolicy

  max_history: 1- name: MappingPolicy

Note

The MappingPolicy is there because it handles the logic of the /restart intent, which allows you to clear the conversation history and start fresh.

MappingPolicy 政策之是以存在,是因為它處理 /restart 意圖的邏輯,它允許您清除對話曆史記錄并開始重新開始。

Now that we’ve defined our policies, we can add some stories for the goodbye, thank and greet intents to the stories.md file:

現在,我們已經定義了我們的政策,我們可以添加一些故事的goodbye,thank 和greet 的意圖在stories.md檔案:

## greet* greet

  - utter_greet

## thank* thank

  - utter_noworries

## goodbye* bye

  - utter_bye

We’ll also need to add the intents, actions and responses to our domain.yml file in the following sections:

我們還需要在以下部分中向域.yml 檔案添加intents, actions and responses:

intents:

  - greet

  - bye

  - thank

responses:

  utter_noworries:

    - text: No worries!

  utter_greet:

    - text: Hi

  utter_bye:

    - text: Bye!

Finally, we’ll copy over some NLU data from Sara into our nlu.md file (more can be found here):

最後,我們将從 Sara 複制一些 NLU 資料到我們的nlu.md檔案:

## intent:greet- Hi- Hey- Hi bot- Hey bot- Hello- Good morning- hi again- hi folks

## intent:bye- goodbye- goodnight- good bye- good night- see ya- toodle-oo- bye bye- gotta go- farewell

## intent:thank- Thanks- Thank you- Thank you so much- Thanks bot- Thanks for that- cheers

You can now train a first model and test the bot, by running the following commands:

現在,您可以通過運作以下指令來訓練第一個模型并測試自動程式:

rasa train

rasa shell

This bot should now be able to reply to the intents we defined consistently, and in any order.

此機器人現在應該能夠以任何順序回複我們定義的意圖。

For example:

While it’s good to test the bot interactively, we should also add end to end test cases that can later be included as part of a CI/CD system. End-to-end test conversations include NLU data, so that both components of Rasa can be tested. The file tests/conversation_tests.md contains example test conversations. Delete all the test conversations and replace them with some test conversations for your assistant so far:

雖然以互動方式測試自動程式是好事,但我們還應添加可稍後作為 CI/CD 系統一部分的端到端測試用例。端到端測試對話包括 NLU 資料,以便可以測試 Rasa 的兩個元件。tests/conversation_tests.md 包含示例測試會話。删除之前所有測試對話,并将其替換為新的一些測試對話:

## greet + goodbye* greet: Hi!

  - utter_greet* bye: Bye

  - utter_bye

## greet + thanks* greet: Hello there

  - utter_greet* thank: thanks a bunch

  - utter_noworries

## greet + thanks + goodbye* greet: Hey

  - utter_greet* thank: thank you

  - utter_noworries* bye: bye bye

  - utter_bye

To test our model against the test file, run the command:

要針對測試檔案測試我們的模型,請運作以下指令:

rasa test --stories tests/conversation_tests.md

The test command will produce a directory named results. It should contain a file called failed_stories.md, where any test cases that failed will be printed. It will also specify whether it was an NLU or Core prediction that went wrong. As part of a CI/CD pipeline, the test option --fail-on-prediction-errors can be used to throw an exception that stops the pipeline.

test指令将生成一個名為results的目錄。它應該包含一個名為 failed_stories.md 的檔案,其中将列印任何對話失敗的測試用例。它還将指出出錯的是 NLU 還是 Core 預測出錯。作為 CI/CD 管道的一部分,測試選項 --fail-on-prediction-errors 可用于抛出停止管道的異常。

Response Selectors 響應選擇器

The ResponseSelector NLU component is designed to make it easier to handle dialogue elements like Small Talk and FAQ messages in a simple manner. By using the ResponseSelector, you only need one story to handle all FAQs, instead of adding new stories every time you want to increase your bot’s scope.

ResponseSelector  NLU 元件旨在更輕松地以簡單的方式處理對話元素,如小談話和常見問題消息。通過使用響應程式,您隻需要一個故事來處理所有常見問題解答,而不是每次增加機器人範圍的時候還需要添加新故事。

People often ask Sara different questions surrounding the Rasa products, so let’s start with three intents: ask_channels, ask_languages, and ask_rasax. We’re going to copy over some NLU data from the Sara training data into our nlu.md. It’s important that these intents have an faq/ prefix, so they’re recognised as the faq intent by the ResponseSelector:

人們經常問Sara圍繞Rasa産品的不同問題,是以讓我們從三個意圖開始:ask_channels,ask_languages和ask_rasax。我們将從 Sara 教育訓練資料中複制一些 NLU 資料導入到nlu.md。具有 faq/字首非常重要,ResponseSelector  将它們識别為 faq 意圖:

## intent: faq/ask_channels- What channels of communication does rasa support?- what channels do you support?- what chat channels does rasa uses- channels supported by Rasa- which messaging channels does rasa support?

## intent: faq/ask_languages- what language does rasa support?- which language do you support?- which languages supports rasa- can I use rasa also for another laguage?- languages supported

## intent: faq/ask_rasax- I want information about rasa x- i want to learn more about Rasa X- what is rasa x?- Can you tell me about rasa x?- Tell me about rasa x- tell me what is rasa x

Next, we’ll need to define the responses associated with these FAQs in a new file called responses.md in the data/ directory:

接下來,我們需要在data/ 目錄中responses.md中定義常見問題相關的響應回複:

## ask channels* faq/ask_channels

  - We have a comprehensive list of [supported connectors](https://rasa.com/docs/core/connectors/), but if

    you don't see the one you're looking for, you can always create a custom connector by following

    [this guide](https://rasa.com/docs/rasa/user-guide/connectors/custom-connectors/).

## ask languages* faq/ask_languages

  - You can use Rasa to build assistants in any language you want!

## ask rasa x* faq/ask_rasax

 - Rasa X is a tool to learn from real conversations and improve your assistant. Read more [here](https://rasa.com/docs/rasa-x/)

The ResponseSelector should already be at the end of the NLU pipeline in our config.yml:

ResponseSelector 應該配置在 config.yml中的 NLU 管道的末尾:

language: enpipeline:

  - name: WhitespaceTokenizer

  - name: RegexFeaturizer

  - name: LexicalSyntacticFeaturizer

  - name: CountVectorsFeaturizer

  - name: CountVectorsFeaturizer

    analyzer: "char_wb"

    min_ngram: 1

    max_ngram: 4

  - name: DIETClassifier

    epochs: 100

  - name: EntitySynonymMapper

  - name: ResponseSelector

    epochs: 100

Now that we’ve defined the NLU side, we need to make Core aware of these changes. Open your domain.yml file and add the faq intent:

現在,我們已經定義了 NLU 端的内容,我們需要讓 Core 意識到這些更改。打domain.yml 檔案并添加 faq 意圖:

intents:

  - greet

  - bye

  - thank

  - faq

We’ll also need to add a retrieval action, which takes care of sending the response predicted from the ResponseSelector back to the user, to the list of actions. These actions always have to start with the respond_ prefix:

我們還需要添加一個retrieval action檢索操作,該操作負責将來自響應ResponseSelector 的響應發送回使用者,并将其發送到操作清單中。這些操作始終必須從字首respond_開始:

actions:

  - respond_faq

Next we’ll write a story so that Core knows which action to predict:

接下來,我們将寫一個story ,以便 Core 知道要預測的操作:

## Some question from FAQ* faq

    - respond_faq

This prediction is handled by the MemoizationPolicy, as we described earlier.

After all of the changes are done, train a new model and test the modified FAQs:

正如我們前面描述的那樣此預測由MemoizationPolicy處理。

完成所有更改後,訓練新模型并測試修改後的常見問題解答:

rasa train

rasa shell

At this stage it makes sense to add a few test cases to your test_stories.md file again:

在此階段,可以再次向 test_stories.md 檔案添加一些測試用例:

## ask channels* faq: What messaging channels does Rasa support?

  - respond_faq

## ask languages* faq: Which languages can I build assistants in?

  - respond_faq

## ask rasa x* faq: What’s Rasa X?

  - respond_faq

You can read more in this blog post and the Retrieval Actions page.

Using the features we described in this tutorial, you can easily build a context-less assistant. When you’re ready to enhance your assistant with context, check out Building a contextual assistant.

使用本教程中介紹的功能,您可以輕松地建構無上下文助手。當您準備好使用上下文增強助手時,請檢視Building a contextual assistant.。

Note

Here’s a minimal checklist of files we modified to build a basic FAQ assistant:

以下是我們建構基本常見問題助手所需要檔案的最小清單:

data/nlu.md: Add NLU training data for faq/ intents

為faq/ 意圖增加NLU訓練資料

data/responses.md: Add responses associated with faq/ intents

 faq/ intents關聯回複

config.yml: Add ReponseSelector in your NLU pipeline

為NLU通道增加ReponseSelector 

domain.yml: Add a retrieval action respond_faq and intent faq

增加一個檢索respond_faq 和意圖faq

data/stories.md: Add a simple story for FAQs

FAQs增加一個簡單的story

test_stories.md: Add E2E test stories for your FAQs

FAQs增加E2E的測試story

Building a contextual assistant 建構上下文助理

Whether you’ve just created an FAQ bot or are starting from scratch, the next step is to expand your bot to handle contextual conversations.

無論您是剛剛建立了FAQ機器人還是從頭開始,下一步是擴充自動程式以處理上下文對話。

In this tutorial we’re going to cover a variety of topics:

在本教程中,我們将介紹以下的幾個主題:

Handling business logic

Handling unexpected user input

Failing gracefully

More complex contextual conversations

處理業務邏輯

處理意外使用者輸入

優雅地處理失敗

更複雜的上下文對話

Please make sure you’ve got all the data from the Building a simple FAQ assistant section before starting this part. You will need to make some adjustments to your configuration file, since we now need to pay attention to context:

在開始此部分之前,請確定你已經從"建構一個簡單的FAQ助理"章節中獲得所需要的資料和代碼。因為我們現在需要注意上下文的部分,您需要對配置檔案進行一些調整,:

policies:- name: MemoizationPolicy- name: MappingPolicy

We removed the max_history: 1 configuration. The default is 5, meaning Core will pay attention to the past 5 turns when making a prediction (see explanation of max history).

我們删除了max_history:1 配置。預設值為 5,這意味着 Core 在進行預測時将注意過去 5 個對話輪次(請參閱max history最大曆史記錄的解釋)。

Handling business logic 處理業務邏輯

A lot of conversational assistants have user goals that involve collecting a bunch of information from the user before being able to do something for them. This is called slot filling. For example, in the banking industry you may have a user goal of transferring money, where you need to collect information about which account to transfer from, whom to transfer to and the amount to transfer. This type of behavior can and should be handled in a rule based way, as it is clear how this information should be collected.

許多會話助理都有使用者目标,這些目标涉及在能夠為他們執行某一操作之前,先從使用者那裡收集大量資訊。這稱為插槽填充。例如,在銀行業中,您可能有一個使用者轉賬的目标,即您需要收集有關要從哪個賬戶轉移、向誰轉賬以及轉賬金額的資訊。這種類型的行為可以而且應該以基于規則的方式處理,因為應該如何收集此資訊。

For this type of use case, we can use Forms and our FormPolicy. The FormPolicy works by predicting the form as the next action until all information is gathered from the user.

對于這種類型的用例,我們可以使用窗體Forms 和表單政策FormPolicy。FormPolicy 的工作原理是用表單内容來預測為下一個操作,直到從使用者那裡收集所有所需要的資訊。

As an example, we will build out the SalesForm from Sara. The user wants to contact our sales team, and for this we need to gather the following pieces of information:

例如,我們将從 Sara 建構銷售表單SalesForm 。使用者希望聯系我們的銷售團隊,為此我們需要收集以下資訊:

Their job

Their bot use case

Their name

Their email

Their budget

Their company

他們的工作

他們的機器人用例

他們的名字

他們的電子郵件

他們的預算

他們的公司

We will start by defining the SalesForm as a new class in the file called actions.py. The first method we need to define is the name, which like in a regular Action returns the name that will be used in our stories:

我們将首先将 SalesForm 定義為一個新的類class,名為"actions.py"。SalesForm這個類我們需要定義的第一個方法是名稱name,就像在正常操作中一樣,它傳回将在我們的故事中使用的名稱:

from rasa_sdk.forms import FormAction

class SalesForm(FormAction):

    """Collects sales information and adds it to the spreadsheet"""

    def name(self):

        return "sales_form"

Next we have to define the required_slots method which specifies which pieces of information to ask for, i.e. which slots to fill.

接下來,我們必須定義required_slots(必填詞槽),該方法指定要請求哪些資訊,即要填充哪些詞槽。

@staticmethoddef required_slots(tracker):

    return [

        "job_function",

        "use_case",

        "budget",

        "person_name",

        "company",

        "business_email",

        ]

Note: you can customise the required slots function not to be static. E.g. if the job_function is a developer, you could add a required_slot about the users experience level with Rasa

注意:您可以自定義所需的詞槽slots 功能,詞槽slots 可以不是一個靜态變量。例如,如果job_function的值是開發者developer,您可以添加一個required_slot,用來增加了解 使用者對Rasa 的體驗級别

Once you’ve done that, you’ll need to specify how the bot should ask for this information. This is done by specifying utter_ask_{slotname} responses in your domain.yml file. For the above we’ll need to specify the following:

完成此工作後,您需要指定自動程式應如何請求此資訊。這是通過在domain.yml 中utter_ask_{slotname} 來指定響應。對于上面例子,我們需要指定以下内容:

utter_ask_business_email:

  - text: What's your business email?utter_ask_company:

  - text: What company do you work for?utter_ask_budget:

  - text: "What's your annual budget for conversational AI? utter_ask_job_function:

  - text: "What's your job? utter_ask_person_name:

  - text: What's your name?utter_ask_use_case:

  - text: What's your use case?

We’ll also need to define all these slots in our domain.yml file:

我們同僚需要在domain.yml檔案中定義這些詞槽

slots:

  company:

    type: unfeaturized

  job_function:

    type: unfeaturized

  person_name:

    type: unfeaturized

  budget:

    type: unfeaturized

  business_email:

    type: unfeaturized

  use_case:

    type: unfeaturized

Going back to our Form definition, we need to define the submit method as well, which will do something with the information the user has provided once the form is complete:

回到我們的表單定義,我們還需要定義submit 方法,該方法将在表單完成後對使用者提供的資訊執行一些操作:

def submit(

        self,

        dispatcher: CollectingDispatcher,

        tracker: Tracker,

        domain: Dict[Text, Any],

    ) -> List[Dict]:

    dispatcher.utter_message("Thanks for getting in touch, we’ll contact you soon")

    return []

In this case, we only tell the user that we’ll be in touch with them, however usually you would send this information to an API or a database. See the rasa-demo for an example of how to store this information in a spreadsheet.

在這個情景中,我們會回複告訴使用者我們将與他們聯系,同時我們會将此資訊發送到 API 或資料庫。有關如何在電子表格中存儲此資訊的示例,請參閱 rasa-demo 。

We’ll need to add the form we just created to a new section in our domain.yml file:

我們需要将剛建立的表單定義添加到domain.yml檔案:

forms:

  - sales_form

We also need to create an intent to activate the form, as well as an intent for providing all the information the form asks the user for. For the form activation intent, we can create an intent called contact_sales. Add the following training data to your nlu file:

我們還需要建立一個意圖intent 來激活表單,以及提供表單要求使用者提供的所有資訊的意圖。對于表單激活意圖,我們可以建立一個名為"contact_sales。将以下訓練資料添加到 nlu 檔案中:

## intent:contact_sales- I wanna talk to your sales people.- I want to talk to your sales people- I want to speak with sales- Sales- Please schedule a sales call- Please connect me to someone from sales- I want to get in touch with your sales guys- I would like to talk to someone from your sales team- sales please

You can view the full intent here)

你可以點選檢視完整的意圖

We will also create an intent called inform which covers any sort of information the user provides to the bot. The reason we put all this under one intent, is because there is no real intent behind providing information, only the entity is important. Add the following data to your NLU file:

我們還将建立一個名為"inform 通知"的意圖,它涵蓋了使用者向機器人提供的任何類型的資訊。我們之是以把這一切放在一個意圖下,是因為這些提供資訊背後沒有真正的意圖,隻有實體(【】裡面的内容)才是重要的。将以下資料添加到 NLU 檔案中:

## intent:inform- [100k](budget)- [100k](budget)- [240k/year](budget)- [150,000 USD](budget)- I work for [Rasa](company)- The name of the company is [ACME](company)- company: [Rasa Technologies](company)- it's a small company from the US, the name is [Hooli](company)- it's a tech company, [Rasa](company)- [ACME](company)- [Rasa Technologies](company)- [[email protected]](business_email)- [[email protected]](business_email)- [[email protected]](business_email)- [[email protected]](business_email)- [my email is [email protected]](business_email)- [engineer](job_function)- [brand manager](job_function)- [marketing](job_function)- [sales manager](job_function)- [growth manager](job_function)- [CTO](job_function)- [CEO](job_function)- [COO](job_function)- [John Doe](person_name)- [Jane Doe](person_name)- [Max Mustermann](person_name)- [Max Meier](person_name)- We plan to build a [sales bot](use_case) to increase our sales by 500%.- we plan to build a [sales bot](use_case) to increase our revenue by 100%.- a [insurance tool](use_case) that consults potential customers on the best life insurance to choose.- we're building a [conversational assistant](use_case) for our employees to book meeting rooms.

Note

Entities like business_email and budget would usually be handled by pretrained entity extractors (e.g. DucklingHTTPExtractor or SpacyEntityExtractor), but for this tutorial we want to avoid any additional setup.

像 business_email 和budget 這樣的實體通常由預先訓練的實體提取器(例如DucklingHTTPExtractor或 SpacyEntityExtractor)處理,但對于本教程,我們希望避免任何其他設定。

The intents and entities will need to be added to your domain.yml file as well:

意圖和實體也需要添加到您的domain.yml  檔案中:

intents:

  - greet

  - bye

  - thank

  - faq

  - contact_sales

  - inform

entities:

  - company

  - job_function

  - person_name

  - budget

  - business_email

  - use_case

A story for a form is very simple, as all the slot collection form happens inside the form, and therefore doesn’t need to be covered in your stories. You just need to write a single story showing when the form should be activated. For the sales form, add this story to your stories.md file:

form表單的的story非常簡單,因為所有詞槽slot的集合都發生在表單中,是以不需要在story中介紹。您隻需要寫一個story,顯示何時應激活表單。現在把sales form的story添加到stories.md中:

## sales form* contact_sales

    - sales_form                   <!--Run the sales_form action-->

    - form{"name": "sales_form"}   <!--Activate the form-->

    - form{"name": null}           <!--Deactivate the form-->

As a final step, let’s add the FormPolicy to our config file:

最後,我們在配置檔案中加入FormPolicy

policies:

  - name: MemoizationPolicy

  - name: KerasPolicy

  - name: MappingPolicy

  - name: FormPolicy

At this point, you already have a working form, so let’s try it out. Make sure to uncomment the action_endpoint in your endpoints.yml to make Rasa aware of the action server that will run our form:

此時,您已經有一個工作表單,是以讓我們嘗試一下。確定取消了action_endpoint.yml檔案中action_endpoint的注釋,確定 Rasa 能夠在運作表單的時候能夠觸發服務。

action_endpoint:

 url: "http://localhost:5055/webhook"

Then start the action server in a new terminal window:

啟動服務

rasa run actions

Then you can retrain and talk to your bot:

你可以重新訓練并跟機器人對話

rasa train

rasa shell

This simple form will work out of the box, however you will likely want to add a bit more capability to handle different situations. One example of this is validating slots, to make sure the user provided information correctly (read more about it here).

這個簡單的表單将開箱即用,但你可能想要添加更多的能力來處理不同的情況。其中一個示例是詞槽Slots驗證,以確定使用者正确提供資訊(在此處閱讀有關它的資訊) 。

Another example is that you may want to fill slots from things other than entities of the same name. E.g. for the “use case” situation in our Form, we would expect the user to type a full sentence and not something that you could necessarily extract as an entity. In this case we can make use of the slot_mappings method, where you can describe what your entities should be extracted from. Here we can use the from_text method to extract the users whole message:

另一個示例是,您可能希望從同名實體以外的其他事物中填充詞槽。例如,對于表單中的"use case"情況,我們希望使用者鍵入完整的句子,而不是一些簡單的實體單詞。在這種情況下,我們可以使用 slot_mappings方法,其中您可以描述應從中提取哪些實體。在這裡,我們可以from_text提取使用者的全部消息:

def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict[Text, Any]]]]:

    """A dictionary to map required slots to    - an extracted entity    - intent: value pairs    - a whole message    or a list of them, where a first match will be picked"""

    return {"use_case": self.from_text(intent="inform")}

Now our bot will extract the full user message when asking for the use case slot, and we don’t need to use the use_case entity defined before.

現在,我們的機器人将在請求用例詞槽時提取完整的使用者消息,我們不需要使用以前定義的use_case實體。

All of the methods within a form can be customized to handle different branches in your business logic. Read more about this here. However, you should make sure not to handle any unhappy paths inside the form. These should be handled by writing regular stories, so your model can learn this behavior.

form表單中的所有方法都可以根據業務邏輯定義成不同的分支。在此處閱讀有關此内容的更多資訊。但是,您應該確定不要處理表單中任何不正确的路徑(非監督式學習),這些應該通過編寫正常stories來處理,這樣您的模型就可以學習此行為。

Note

Here’s a minimal checklist of files we modified to handle business logic using a form action:

我們使用表單定義業務邏輯所需要的最小檔案清單:

actions.py:

Define the form action, including the required_slots, slot_mappings and submit methods

定義表單動作,包含required_slots, slot_mappings and submit 方法

data/nlu.md:

Add examples for an intent to activate the form

為意圖增加用例來啟動form

Add examples for an inform intent to fill the form

為意圖增加用例來填寫表單

domain.yml:

Add all slots required by the form

增加必填詞槽

Add utter_ask_{slot} responses for all required slots

增加必填詞槽的utter_ask_{slot} 響應

Add your form action to the forms section

增加form動作

Add all intents and entities from your NLU training data

增加所有意圖和實體到NLU訓練資料

data/stories.md:

Add a story for the form

為form增加story

config.yml:

Add the FormPolicy to your policies

增加FormPolicy 

Add entity extractors to your pipeline

在通道定義裡增加實體分析器entity extractors

endpoints.yml: Define the action_endpoint

定義action_endpoint

Handling unexpected user input 處理意外使用者輸入

All expected user inputs should be handled by the form we defined above, i.e. if the user provides the information the bot asks for. However, in real situations, the user will often behave differently. In this section we’ll go through various forms of “interjections” and how to handle them within Rasa.

如果使用者按照機器人要求的資訊提供資訊,那所有預期的使用者輸入都應由我們上面定義的表單處理。但是在實際情況下,使用者的行為通常會不同。在本節中,我們将介紹各種形式的"插話interjections",以及如何在 Rasa 中處理它們。

The decision to handle these types of user input should always come from reviewing real conversations. You should first build part of your assistant, test it with real users (whether that’s your end user, or your colleague) and then add what’s missing. You shouldn’t try to implement every possible edge case that you think might happen, because in the end your users may never actually behave in that way. Rasa X is a tool that can help you review conversations and make these types of decisions.

處理這些類型的使用者輸入的決定應始終來自檢視實際對話。您應該首先建構機器人的一部分,使用真實使用者(無論是最終使用者還是同僚)進行測試,然後添加缺少内容。您不應嘗試先定義實作您認為可能發生的每一個可能的邊緣情況,因為最終您的使用者可能永遠不會真正以這樣的方式行事。Rasa X 是一個工具,可幫助您檢視對話并做出這些類型的決策。

Generic interjections 通用插話

If you have generic interjections that should always have the same single response no matter the context, you can use the Mapping Policy to handle these. It will always predict the same action for an intent, and when combined with a forgetting mechanism, you don’t need to write any stories either.

如果具有通用的插話,無論上下文如何,它們應始終具有相同的單個響應,可以使用映射政策Mapping Policy 來處理這些響應。它将始終預測意圖的相同操作,并且與遺忘機制結合使用時,您也不需要編寫任何故事。

For example, let’s say you see users having conversations like the following one with your assistant, where they write a greeting in the middle of a conversation - maybe because they were gone for a few minutes:

例如,假設您看到使用者與助手進行如下對話,他們在對話中寫一個問候語Hi again - 可能是因為他們離開對話了幾分鐘:

The greet intent is a good example where we will always give the same response and yet we don’t want the intent to affect the dialogue history. To do this, the response must be an action that returns the UserUtteranceReverted() event to remove the interaction from the dialogue history.

問候意圖是一個很好的例子,我們将永遠給予相同的回應,但我們不想意圖影響對話曆史。是以響應必須是傳回 UserUtteranceReverted() 事件以從對話曆史記錄中删除互動的操作。

First, open the domain.yml file and modify the greet intent and add a new block `actions` in the file, next, add the action_greet as shown here:

首先,打開domain.yml檔案并修改問候意圖,并在檔案中添加新塊"actions",接下來,添加action_greet如下所示:

intents:

  - greet: {triggers: action_greet}

  - bye

  - thank

  - faq

  - contact_sales

  - inform

actions:

  - action_greet

Remove any stories using the “greet” intent if you have them.

删除任何跟“greet”有關的意圖

Next, we need to define action_greet. Add the following action to your actions.py file:

現在我們需要定義action_greet。 在actions.py增加代碼:

from rasa_sdk import Actionfrom rasa_sdk.events import UserUtteranceReverted

class ActionGreetUser(Action):"""Revertible mapped action for utter_greet"""

def name(self):

    return "action_greet"

def run(self, dispatcher, tracker, domain):

    dispatcher.utter_template("utter_greet", tracker)

    return [UserUtteranceReverted()]

To test the modified intents, we need to re-start our action server:

測試修改後的意圖,我們需要重新開機我們的服務

rasa run actions

Then we can retrain the model, and try out our additions:

重新訓練并啟動

rasa train

rasa shell

FAQs are another kind of generic interjections that should always get the same response. For example, a user might ask a related FAQ in the middle of filling a form:

FAQs常見問題是另一種通用的插話,應始終得到相同的響應。例如,使用者可能會在填寫表單時詢問相關的FAQ 常見問題解答:

To handle FAQs defined with retrieval actions, you can add a simple story that will be handled by the MemoizationPolicy:

若要處理使用檢索操作定義的FAQs 常見問題,可以添加一個簡單的故事,由"MemoizationPolicy記憶政策"來處理。

## just sales, continue* contact_sales

    - sales_form

    - form{"name": "sales_form"}* faq

    - respond_faq

    - sales_form

    - form{"name": null}

This will break out of the form and deal with the users FAQ question, and then return back to the original task. For example:

這将打破表單并處理使用者常見問題解答問題,然後傳回到原始任務。例如:

If you find it difficult to write stories in this format, you can always use Interactive Learning to help you create them.

如果您發現很難以這種格式編寫故事,您始終可以使用 Interactive Learning 互動式學習來幫助建立它們。

As always, make sure to add an end to end test case to your test_stories.md file.

與之前一樣,請確定将端到端測試用例添加到 test_stories.md 檔案中。

Contextual questions 上下文問題

You can also handle contextual questions, like the user asking the question “Why do you need to know that”. The user could ask this based on a certain slot the bot has requested, and the response should differ for each slot. For example:

您還可以處理上下文問題,例如使用者詢問"為什麼您需要了解這一點"的問題。使用者可以根據機器人請求的某一詞槽詢問此問題,并且每個詞槽的響應應有所不同。例如:

To handle this, we need to make the requested_slot featurized, and assign it the categorical type:

為了處理這種情況,我們需要使requested_slot ,并為其配置設定分類類型:

slots:

  requested_slot:

    type: categorical

    values:

      - business_email

      - company

      - person_name

      - use_case

      - budget

      - job_function

This means that Core will pay attention to the value of the slot when making a prediction (read more about other featurized slots), whereas unfeaturized slots are only used for storing information. The stories for this should look as follows:

這意味着 Core 在進行預測時将注意詞槽的值而非僅用于存儲資訊。(閱讀更多有關featurized slots資訊),對此應如下所示:

## explain email* contact_sales

    - sales_form

    - form{"name": "sales_form"}

    - slot{"requested_slot": "business_email"}* explain

    - utter_explain_why_email

    - sales_form

    - form{"name": null}

## explain budget* contact_sales

    - sales_form

    - form{"name": "sales_form"}

    - slot{"requested_slot": "budget"}* explain

    - utter_explain_why_budget

    - sales_form

    - form{"name": null}

We’ll need to add the intent and utterances we just added to our domain.yml file:

我們需要把意圖intent 和話語utterances 添加到domain.yml  檔案中:

intents:- greet: {triggers: action_greet_user}- bye- thank- faq- explain

responses:

  utter_explain_why_budget:

  - text: We need to know your budget to recommend a subscription

  utter_explain_why_email:

  - text: We need your email so we can contact you

Finally, we’ll need to add some NLU data for the explain intent:

最後我們需要添加一些 NLU 資料以說明目的:

## intent:explain- why- why is that- why do you need it- why do you need to know that?- could you explain why you need it?

Then you can retrain your bot and test it again:

重新訓練,再測一次。

rasa train

rasa shell

Note

You will need to add a story for each of the values of the requested_slot slot for the bot to handle every case of “Why do you need to know that”

您将需要為每一個機器人添加一個story包含requested_slot詞槽,來處理"為什麼需要知道"的情景。

Don’t forget to add a few end to end stories to your test_stories.md for testing as well.

不要忘記在您的 test_stories.md 中添加一些端到端用例測試。

Note

Here’s a minimal checklist of of files we modified to handle unexpected user input:

以下是我們為處理意外使用者輸入最小修改檔案清單:

actions.py: Define action_greet  

定義action_greet

data/nlu.md: Add training data for an explain intent

為explain 意圖增加訓練資料

domain.yml:

Map intent greet to action_greet_user

将greet 意圖定位到action_greet_user

Make requested_slot a categorical slot with all required slots as values

增加requested_slot 詞槽定義所需的值

Add the explain intent

增加explain 意圖

Add responses for contextual question interruptions

增加上下文問題中斷的回應

data/stories.md:

Remove stories using mapped intents if you have them

删除有已經映射需要修改的意圖的故事

Add stories with FAQ & contextual interruptions in the middle of filling a form

在填寫表單時增加具有常見問題和上下文中斷的故事

Failing gracefully 優雅的處理失敗情況

Even if you design your bot perfectly, users will inevitably say things to your assistant that you did not anticipate. In these cases, your assistant will fail, and it’s important you ensure it does so gracefully.

即使您完美地設計了您的機器人,使用者也不可避免地會向您的機器人助手說出您沒有預料到的事情。在這些情況下,您的助手将回答失敗,重要的是您確定它這樣做優雅。

Fallback policy  回退政策

One of the most common failures is low NLU confidence, which is handled very nicely with the TwoStageFallbackPolicy. You can enable it by adding the following to your configuration file,

TwoStageFallbackPolicy政策可以很好的處理NLU故障最常見的錯誤。您可以通過向配置檔案中添加以下内容來啟用它,

policies:

  - name: TwoStageFallbackPolicy

    nlu_threshold: 0.8

and adding the out_of_scope intent to your domain.yml file:

增加out_of_scope意圖到domain.yml

intents:- out_of_scope

When the nlu confidence falls below the defined threshold, the bot will prompt the user to rephrase their message. If the bot isn’t able to get their message three times, there will be a final action where the bot can e.g. hand off to a human.

當 nlu 置信度低于定義的門檻值時,機器人将提示使用者重新表述其消息。如果機器人不能收到他們的資訊三次,将會觸發一個最後的行動,例如交給人類。

To try this out, retrain your model and send a message like “order me a pizza” to your bot:

要嘗試一下, 重新訓練你的模型, 并發送一條消息, 如 "給我訂購比薩餅" 到你的機器人:

rasa train

rasa shell

There are also a bunch of ways in which you can customise this policy. In Sara, our demo bot, we’ve customized it to suggest intents to the user within a certain confidence range to make it easier for the user to give the bot the information it needs.

還有一系列自定義此政策的方法。我們已經在Sara的示範機器人自定義了一些政策,我們自定義他去給使用者做一些建議性意向問題,使得使用者在一定的信心範圍内,更容易給機器人一些所需要的資訊

This is done by customizing the action ActionDefaultAskAffirmation as shown in the Sara rasa-demo action server We define some intent mappings to make it more intuitive to the user what an intent means.

這是通過自定義在Sara rasa-demo action server中ActionDefaultAskAffirmation,我們定義了一些意圖映射,使其對使用者的意圖的含義更加直覺。

Out of scope intent 範圍外的意圖

It is good practice to also handle questions you know your users may ask, but for which you haven’t necessarily implemented a user goal yet.

您尚未實作使用者目标的情況下,處理你知道使用者可能會問的問題是一種好的做法。

You can define an out_of_scope intent to handle generic out of scope requests, like “I’m hungry” and have the bot respond with a default message like “Sorry, I can’t handle that request”:

您可以定義out_of_scope來處理泛型範圍外請求的意圖,如"我餓了",并讓機器人響應預設消息,如"對不起,我不能處理該請求":

* out_of_scope

  utter_out_of_scope

We’ll need to add NLU data for the out_of_scope intent as well:

增加NLU資料和out_of_scope

## intent:out_of_scope- I want to order food- What is 2 + 2?- Who’s the US President?- I need a job

And finally we’ll add a response to our domain.yml file:

增加響應到domain.yml 

responses:

  utter_out_of_scope:

  - text: Sorry, I can’t handle that request.

We can now re-train, and test this addition

重新訓練,測試這個部分

rasa train

rasa shell

Going one step further, if you observe your users asking for certain things, that you’ll want to turn into a user goal in future, you can handle these as separate intents, to let the user know you’ve understood their message, but don’t have a solution quite yet. E.g., let’s say the user asks “I want to apply for a job at Rasa”, we can then reply with “I understand you’re looking for a job, but I’m afraid I can’t handle that skill yet.”

更進一步,如果您觀察到使用者詢問某些内容,即将來希望将其轉化為使用者目标,您可以作為單獨的意圖處理這些内容,讓使用者知道您已經了解了他們的消息,但還沒有完全的解決方案。例如,假設使用者問"我想申請Rasa的工作",然後我們可以回答"我知道你正在找工作,但恐怕我還不能處理這種技能。

* ask_job

  utter_job_not_handled

Note

Here’s a minimal checklist of files we modified to help our assistant fail gracefully:

以下是我們修改的最小檔案清單:

data/nlu.md:

Add training data for the out_of_scope intent & any specific out of scope intents that you want to handle seperately

為out_of_scope意圖和任何你需要單獨處理的超出範圍的意圖增加訓練資料

data/stories.md:

Add stories for any specific out of scope intents

為超出範圍的意圖增加stories

domain.yml:

Add the out_of_scope intent & any specific out of scope intents

增加out_of_scope和其他超出範圍的意圖

Add an utter_out_of_scope response & responses for any specific out of scope intents

增加utter_out_of_scope 回複

actions.py:

Customise ActionDefaultAskAffirmation to suggest intents for the user to choose from

自定義ActionDefaultAskAffirmation來建議使用者意圖選擇

config.yml:

Add the TwoStageFallbackPolicy to the policies section

增加政策TwoStageFallbackPolicy

More complex contextual conversations 更複雜的上下文對話

Not every user goal you define will fall under the category of business logic. For the other cases you will need to use stories and context to help the user achieve their goal.

不是您定義的每個使用者目标都屬于業務邏輯類别。對于其他情況需要使用更多的故事情景和上下文來幫助使用者實作他們的目标。

If we take the example of the “getting started” skill from Sara, we want to give them different information based on whether they’ve built an AI assistant before and are migrating from a different tool etc. This can be done quite simply with stories and the concept of max history.

如果我們以 Sara 的"入門"技能為例,我們希望根據他們之前是否建構了 AI 助手以及是否從其他工具遷移等,為他們提供不同的資訊。這可以通過更多的故事stories 和最大曆史 max history的概念來完成。

 ## new to rasa + built a bot before

 * how_to_get_started

   - utter_getstarted   - utter_first_bot_with_rasa * affirm   - action_set_onboarding   - slot{"onboarding": true}   - utter_built_bot_before * affirm

   - utter_ask_migration

 * deny

   - utter_explain_rasa_components

   - utter_rasa_components_details

   - utter_ask_explain_nlucorex

 * affirm

   - utter_explain_nlu

   - utter_explain_core

   - utter_explain_x

   - utter_direct_to_step2

 ## not new to rasa + core

 * how_to_get_started

   - utter_getstarted   - utter_first_bot_with_rasa * deny   - action_set_onboarding   - slot{"onboarding": false}   - utter_ask_which_product * how_to_get_started{"product": "core"}

   - utter_explain_core

   - utter_anything_else

The above example mostly leverages intents to guide the flow, however you can also guide the flow with entities and slots. For example, if the user gives you the information that they’re new to Rasa at the beginning, you may want to skip this question by storing this information in a slot.

上述示例主要利用意圖來引導流,但您也可以使用實體和插槽引導流。例如,如果使用者在開頭為您提供了 Rasa 的新規定,您可能希望通過将此資訊存儲在詞槽中來跳過此問題。

* how_to_get_started{"user_type": "new"}

  - slot{"user_type":"new"}

  - action_set_onboarding

  - slot{"onboarding": true}

  - utter_getstarted_new

  - utter_built_bot_before

For this to work, keep in mind that the slot has to be featurized in your domain.yml file. This time we can use the text slot type, as we only care about whether the slot was set or not.

要想這樣做,請記住,詞槽必須在你的domain.yml檔案中定義。這一次,我們可以使用文本text 詞槽類型,因為我們隻關心詞槽是否設定。

AugmentedMemoizationPolicy 增強化政策

To make your bot more robust to interjections, you can replace the MemoizationPolicy with the AugmentedMemoizationPolicy. It works the same way as the MemoizationPolicy, but if no exact match is found it additionally has a mechanism that forgets a certain amount of steps in the conversation history to find a match in your stories (read more here)

若要使機器人對插話更加可靠,您可以将記憶政策MemoizationPolicy 替換為增強化政策AugmentedMemoizationPolicy。它的工作方式與記憶政策相同,但如果沒有發現完全比對,它另外有一個機制,忘記對話曆史記錄中的一定數量的步驟,以在您的故事中查找比對項(在此處閱讀更多内容)

Using ML to generalise 使用機器學習概況

Aside from the more rule-based policies we described above, Core also has some ML policies you can use. These come in as an additional layer in your policy configuration, and only jump in if the user follows a path that you have not anticipated. It is important to understand that using these policies does not mean letting go of control over your assistant. If a rule based policy is able to make a prediction, that prediction will always have a higher priority (read more here) and predict the next action. The ML based policies give your assistant the chance not to fail, whereas if they are not used your assistant will definitely fail, like in state machine based dialogue systems.

除了我們上面描述的基于規則的更多政策外,Core 還有一些可以使用的 ML 政策。這些作為政策配置中的額外層進入,并且僅在使用者遵循您未預料到的路徑時才加入。重要的是要明白使用這些政策并不意味着放棄對助手的控制。如果基于規則政策能夠做出預測,則該預測将始終具有更高的優先級(在此處閱讀更多内容)并預測下一個操作。基于 ML 的政策讓您的助手有機會不失敗,而如果不使用,您的助手肯定會失敗,就像在基于狀态機的對話系統中一樣。

These types of unexpected user behaviors are something our TEDPolicy deals with very well. It can learn to bring the user back on track after some interjections during the main user goal the user is trying to complete. For example, in the conversation below (extracted from a conversation on Rasa X):

這些類型的意外使用者行為是我們的 TEDPolicy 處理得很好。它可以學習在使用者嘗試完成的主要使用者目标期間進行一些插話後使使用者回到正軌。例如,在下面的對話中(摘自 Rasa X 上的對話):

## Story from conversation with a2baab6c83054bfaa8d598459c659d2a on November 28th 2019* greet

  - action_greet_user

  - slot{"shown_privacy":true}* ask_whoisit

  - action_chitchat* ask_whatspossible

  - action_chitchat* telljoke

  - action_chitchat* how_to_get_started{"product":"x"}

  - slot{"product":"x"}

  - utter_explain_x

  - utter_also_explain_nlucore* affirm

  - utter_explain_nlu

  - utter_explain_core

  - utter_direct_to_step2

Here we can see the user has completed a few chitchat tasks first, and then ultimately asks how they can get started with Rasa X. The TEDPolicy correctly predicts that Rasa X should be explained to the user, and then also takes them down the getting started path, without asking all the qualifying questions first.

Since the ML policy generalized well in this situation, it makes sense to add this story to your training data to continuously improve your bot and help the ML generalize even better in future. Rasa X is a tool that can help you improve your bot and make it more contextual.

在這裡,我們可以看到使用者已經完成了一些閑聊任務,然後最終詢問他們如何開始使用Rasa X。TEDPolicy 正确地預測Rasa X應該向使用者解釋,然後讓他們沿着入門路徑前進,而不首先詢問所有限定問題。

由于 ML 政策在此情況下推廣得很好,是以将這個故事添加到您的教育訓練資料中是有意義的,以持續改進您的機器人并幫助 ML 在将來更好地推廣。Rasa X 是一個工具,可以幫助您改進您的機器人,使其更具上下文。

繼續閱讀