Samyang Rasa Baru

Samyang Rasa Baru

Using Responses in Conversations#

Custom Slot Mappings#

You can define custom slot mappings using slot validation actions when none of the predefined mappings fit your use case. You must define this slot mapping to be of type custom, for example:

action: action_calculate_day_of_week

You can also use the custom slot mapping to list slots that will be filled by arbitrary custom actions in the course of a conversation, by listing the type and no specific action. For example:

This slot will not be updated on every user turn, but only once a custom action that returns a SlotSet event for it is predicted.

You can provide an initial value for a slot in your domain file:

Responses are actions that send a message to a user without running any custom code or returning events. These responses can be defined directly in the domain file under the responses key and can include rich content such as buttons and attachments. For more information on responses and how to define them, see Responses.

Forms are a special type of action meant to help your assistant collect information from a user. Define forms under the forms key in your domain file. For more information on form and how to define them, see Forms.

Actions are the things your bot can actually do. For example, an action could:

All custom actions should be listed in your domain, except responses which need not be listed under actions: as they are already listed under responses:.

Test Conversation Format#

The test conversation format is a format that combines both NLU data and stories into a single file for evaluation. Read more about this format in Testing Your Assistant.

This format is only used for testing and cannot be used for training.

End-to-end training is an experimental feature. We introduce experimental features to get feedback from our community, so we encourage you to try it out! However, the functionality might be changed or removed in the future. If you have feedback (positive or negative) please share it with us on the Rasa Forum.

With end-to-end training, you do not have to deal with the specific intents of the messages that are extracted by the NLU pipeline or with separate utter_ responses in the domain file. Instead, you can include the text of the user messages and/or bot responses directly in your stories. See the training data format for detailed description of how to write end-to-end stories.

You can mix training data in the end-to-end format with labeled training data which has intents and actions specified: Stories can have some steps defined by intents/actions and other steps defined directly by user or bot utterances.

We call it end-to-end training because policies can consume and predict actual text. For end-to-end user inputs, intents classified by the NLU pipeline and extracted entities are ignored.

Only Rule Policy and TED Policy allow end-to-end training.

RulePolicy uses simple string matching during prediction. Namely, rules based on user text will only match if the user text strings inside your rules and input during prediction are identical.

TEDPolicy passes user text through an additional Neural Network to create hidden representations of the text. In order to obtain robust performance you need to provide enough training stories to capture a variety of user texts for any end-to-end dialogue turn.

Rasa policies are trained for next utterance selection. The only difference to creating utter_ response is how TEDPolicy featurizes bot utterances. In case of an utter_ action, TEDPolicy sees only the name of the action, while if you provide actual utterance using bot key, TEDPolicy will featurize it as textual input depending on the NLU configuration. This can help in case of similar utterances in slightly different situations. However, this can also make things harder to learn because the fact that different utterances have similar texts make it easier for TEDPolicy to confuse these utterances.

End-to-end training requires significantly more parameters in TEDPolicy. Therefore, training an end-to-end model might require significant computational resources depending on how many end-to-end turns you have in your stories.

To use forms with Rasa you need to make sure that the Rule Policy is added to your policy configuration. For example:

Define a form by adding it to the forms section in your domain. The name of the form is also the name of the action which you can use in stories or rules to handle form executions. You will need to specify a list of slot names to the mandatory required_slots key.

The following example form restaurant_form will fill the slot cuisine and slot num_people.

You can define a list of intents to ignore for the whole form under the ignored_intents key. Intents listed under ignored_intents will be added to the not_intent key of each slot mapping.

For example, if you do not want any of the required slots of a form to be filled when the intent is chitchat, then you would need to define the following (after the form name and under the ignored_intents keyword):

Once the form action gets called for the first time, the form gets activated and will prompt the user for the next required slot value. It does this by looking for a response called utter_ask__ or utter_ask_ if the former isn't found. Make sure to define these responses in your domain file for each required slot.

To activate a form you need to add a story or rule, which describes when the assistant should run the form. In the case a specific intent triggering a form, you can for example use the following rule:

- rule: Activate form

- intent: request_restaurant

- action: restaurant_form

- active_loop: restaurant_form

The active_loop: restaurant_form step indicates that the form should be activated after restaurant_form was run.

A form will automatically deactivate itself once all required slots are filled. You can describe your assistant's behavior for the end of a form with a rule or a story. If you don't add an applicable story or rule, the assistant will automatically listen for the next user message after the form is finished. The following example runs the utterances utter_submit and utter_slots_values as soon as the form your_form filled all required slots.

# Condition that form is active.

- active_loop: restaurant_form

# Form is deactivated

- action: restaurant_form

- requested_slot: null

# The actions we want to run when the form is submitted.

- action: utter_submit

- action: utter_slots_values

Users might want to break out of a form early. Please see Writing Stories / Rules for Unhappy Form Paths on how to write stories or rules for this case.

As of 3.0, slot mappings are defined in the slots section of the domain. This change allows the same slot mapping to be reused across multiple forms, removing any unnecessary duplication. Please follow the migration guide to update your assistant.

Note specifically the role of Mapping Conditions and the unique entity mapping constraint.

Validating Form Input#

After extracting a slot value from user input, you can validate the extracted slots. By default Rasa Open Source only validates if any slot was filled after requesting a slot.

Forms no longer raise ActionExecutionRejection if nothing is extracted from the user’s utterance for any of the required slots.

You can implement a Custom Action validate_ to validate any extracted slots. Make sure to add this action to the actions section of your domain:

- validate_restaurant_form

When the form is executed it will run your custom action.

This custom action can extend FormValidationAction class to simplify the process of validating extracted slots. In this case, you need to write functions named validate_ for every extracted slot.

The following example shows the implementation of a custom action which validates that the slot named cuisine is valid.

from typing import Text, List, Any, Dict

from rasa_sdk import Tracker, FormValidationAction

from rasa_sdk.executor import CollectingDispatcher

from rasa_sdk.types import DomainDict

class ValidateRestaurantForm(FormValidationAction):

def name(self) -> Text:

return "validate_restaurant_form"

def cuisine_db() -> List[Text]:

"""Database of supported cuisines"""

return ["caribbean", "chinese", "french"]

def validate_cuisine(

dispatcher: CollectingDispatcher,

) -> Dict[Text, Any]:

"""Validate cuisine value."""

if slot_value.lower() in self.cuisine_db():

return {"cuisine": slot_value}

return {"cuisine": None}

You can also extend the Action class and retrieve extracted slots with tracker.slots_to_validate to fully customize the validation process.

Using a Custom Action to Ask For the Next Slot#

As soon as the form determines which slot has to be filled next by the user, it will execute the action utter_ask__ or utter_ask_ to ask the user to provide the necessary information. If a regular utterance is not enough, you can also use a custom action action_ask__ or action_ask_ to ask for the next slot.

from typing import Dict, Text, List

from rasa_sdk import Tracker

from rasa_sdk.events import EventType

from rasa_sdk.executor import CollectingDispatcher

from rasa_sdk import Action

class AskForSlotAction(Action):

def name(self) -> Text:

return "action_ask_cuisine"

self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict

) -> List[EventType]:

dispatcher.utter_message(text="What cuisine?")

Here is a full example of a domain, taken from the concertbot example:

influence_conversation: false

influence_conversation: false

influence_conversation: true

- text: "Sorry, I didn't get that, can you rephrase?"

- text: "You're very welcome."

- text: "I am a bot, powered by Rasa."

- text: "I can help you find concerts and venues. Do you like music?"

- text: "Awesome! You can ask me things like \"Find me some concerts\" or \"What's a good venue\""

- action_search_concerts

- action_search_venues

- action_show_concert_reviews

- action_show_venue_reviews

- action_set_music_preference

session_expiration_time: 60 # value in minutes

carry_over_slots_to_new_session: true

Ignoring Entities for Certain Intents#

To ignore all entities for certain intents, you can add the use_entities: [] parameter to the intent in your domain file like this:

To ignore some entities or explicitly take only certain entities into account you can use this syntax:

You can only use_entities or ignore_entities for any single intent.

Excluded entities for those intents will be unfeaturized and therefore will not impact the next action predictions. This is useful when you have an intent where you don't care about the entities being picked up.

If you list your intents without a use_entities or ignore_entities parameter, the entities will be featurized as normal.

It is also possible to ignore an entity for all intents by setting the influence_conversation flag to false for the entity itself. See the entities section for details.

Excluded entities for intents will be unfeaturized and therefore will not impact the next action predictions. This is useful when you have an intent where you don't care about the entities being picked up.

If you list your intents without this parameter, and without setting influence_conversation to false for any entities, all entities will be featurized as normal.

If you want these entities not to influence action prediction via slots either, set the influence_conversation: false parameter for slots with the same name.

As of 3.1, you can use the influence_conversation flag under entities. The flag can be set to false to declare that an entity should not be featurized for any intents. It is a shorthand syntax for adding an entity to the ignore_entities list of every intent in the domain. The flag is optional and default behaviour remains unchanged.

The entities section lists all entities that can be extracted by any entity extractor in your NLU pipeline.

- PERSON # entity extracted by SpacyEntityExtractor

- time # entity extracted by DucklingEntityExtractor

- membership_type # custom entity extracted by DIETClassifier

- priority # custom entity extracted by DIETClassifier

When using multiple domain files, entities can be specified in any domain file, and can be used or ignored by any intent in any domain file.

If you are using the feature Entity Roles and Groups you also need to list the roles and groups of an entity in this section.

- city: # custom entity extracted by DIETClassifier

- topping: # custom entity extracted by DIETClassifier

- size: # custom entity extracted by DIETClassifier

By default, entities influence action prediction. To prevent extracted entities from influencing the conversation for specific intents you can ignore entities for certain intents. To ignore an entity for all intents, without having to list it under the ignore_entities flag of each intent, you can set the flag influence_conversation to false under the entity:

influence_conversation: false

This syntax has the same effect as adding the entity to the ignore_entities list for every intent in the domain.

Explicitly setting influence_conversation: true does not change any behaviour. This is the default setting.

Slots are your bot's memory. They act as a key-value store which can be used to store information the user provided (e.g their home city) as well as information gathered about the outside world (e.g. the result of a database query).

Slots are defined in the slots section of your domain with their name, type and if and how they should influence the assistant's behavior. The following example defines a slot with name "slot_name", type text and predefined slot mapping from_entity.

Using a Custom Action to Ask For the Next Slot#

As soon as the form determines which slot has to be filled next by the user, it will execute the action utter_ask__ or utter_ask_ to ask the user to provide the necessary information. If a regular utterance is not enough, you can also use a custom action action_ask__ or action_ask_ to ask for the next slot.

from typing import Dict, Text, List

from rasa_sdk import Tracker

from rasa_sdk.events import EventType

from rasa_sdk.executor import CollectingDispatcher

from rasa_sdk import Action

class AskForSlotAction(Action):

def name(self) -> Text:

return "action_ask_cuisine"

self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict

) -> List[EventType]:

dispatcher.utter_message(text="What cuisine?")

If there is more than one asking option for the slot, Rasa prioritizes in the following order:

Conditional Response Variations#

Specific response variations can also be selected based on one or more slot values using a conditional response variation. A conditional response variation is defined in the domain or responses YAML files similarly to a standard response variation but with an additional condition key. This key specifies a list of slot name and value constraints.

When a response is triggered during a dialogue, the constraints of each conditional response variation are checked against the current dialogue state. If all constraint slot values are equal to the corresponding slot values of the current dialogue state, the response variation is eligible to be used by your conversational assistant.

The comparison of dialogue state slot values and constraint slot values is performed by the equality "==" operator which requires the type of slot values to match too. For example, if the constraint is specified as value: true, then the slot needs to be filled with a boolean true, not the string "true".

In the following example, we will define one conditional response variation with one constraint, that the logged_in slot is set to true:

influence_conversation: False

influence_conversation: False

text: "Hey, {name}. Nice to see you again! How are you?"

- text: "Welcome. How is your day going?"

- action: action_log_in

- action: utter_greet

In the example above, the first response variation ("Hey, {name}. Nice to see you again! How are you?") will be used whenever the utter_greet action is executed and the logged_in slot is set to true. The second variation, which has no condition, will be treated as the default and used whenever logged_in is not equal to true.

It is highly recommended to always provide a default response variation without a condition to guard against those cases when no conditional response matches filled slots.

During a dialogue, Rasa will choose from all conditional response variations whose constraints are satisfied. If there are multiple eligible conditional response variations, Rasa will pick one at random. For example, consider the following response:

text: "Hey, {name}. Nice to see you again! How are you?"

name: eligible_for_upgrade

text: "Welcome, {name}. Did you know you are eligible for a free upgrade?"

- text: "Welcome. How is your day going?"

If logged_in and eligible_for_upgrade are both set to true then both the first and second response variations are eligible to be used, and will be chosen by the conversational assistant with equal probability.

You can continue using channel-specific response variations alongside conditional response variations as shown in the example below.

influence_conversation: False

influence_conversation: False

text: "Hey, {name}. Nice to see you again on Slack! How are you?"

- text: "Welcome. How is your day going?"

Rasa will prioritize the selection of responses in the following order:

You can make responses rich by adding visual and interactive elements. There are several types of elements that are supported across many channels:

Here is an example of a response that uses buttons:

- text: "Hey! How are you?"

payload: "/mood_great"

Each button in the list of buttons should have two keys:

If you would like the buttons to also pass entities to the assistant:

- text: "Hey! Would you like to purchase motor or home insurance?"

- title: "Motor insurance"

payload: '/inform{{"insurance":"motor"}}'

- title: "Home insurance"

payload: '/inform{{"insurance":"home"}}'

Passing multiple entities is also possible with:

'/intent_name{{"entity_type_1":"entity_value_1", "entity_type_2": "entity_value_2"}}'

You can use buttons to overwrite the NLU prediction and trigger a specific intent and entities.

Messages starting with / are sent handled by the RegexInterpreter, which expects NLU input in a shortened /intent{entities} format. In the example above, if the user clicks a button, the user input will be classified as either the mood_great or mood_sad intent.

You can include entities with the intent to be passed to the RegexInterpreter using the following format:

/inform{"ORG":"Rasa", "GPE":"Germany"}

The RegexInterpreter will classify the message above with the intent inform and extract the entities Rasa and Germany which are of type ORG and GPE respectively.

You need to write the /intent{entities} shorthand response with double curly braces in domain.yml so that the assistant does not treat it as a variable in a response and interpolate the content within the curly braces.

Keep in mind that it is up to the implementation of the output channel how to display the defined buttons. For example, some channels have a limit on the number of buttons you can provide. Check your channel's documentation under Concepts > Channel Connectors for any channel-specific restrictions.

You can add images to a response by providing a URL to the image under the image key:

- text: "Here is something to cheer you up:"

image: "https://i.imgur.com/nGF1K8f.jpg"

Select which actions should receive domain#

You can control if an action should receive a domain or not.

To do this you must first enable selective domain in you endpoint configuration for action_endpoint in endpoints.yml.

url: "http://localhost:5055/webhook" # URL to your action server

enable_selective_domain: true

After selective domain for custom actions is enabled, domain will be sent only to those custom actions which have specifically stated that they need it. Custom actions inheriting from rasa-sdk FormValidationAction parent class are an exception to this rule as they will always have the domain sent to them. To specify if an action needs the domain add {send_domain: true} to custom action in the list of actions in domain.yml:

- action_hello_world: {send_domain: True} # will receive domain

- action_calculate_mass_of_sun # will not receive domain

- validate_my_form # will receive domain

Validating Form Input#

After extracting a slot value from user input, you can validate the extracted slots. By default Rasa only validates if any slot was filled after requesting a slot.

You can implement a Custom Action validate_ to validate any extracted slots. Make sure to add this action to the actions section of your domain:

- validate_restaurant_form

When the form is executed it will run your custom action after every user turn to validate the latest filled slots.

This custom action can extend FormValidationAction class to simplify the process of validating extracted slots. In this case, you need to write functions named validate_ for every extracted slot.

The following example shows the implementation of a custom action which validates that the slot named cuisine is valid.

from typing import Text, List, Any, Dict

from rasa_sdk import Tracker, FormValidationAction

from rasa_sdk.executor import CollectingDispatcher

from rasa_sdk.types import DomainDict

class ValidateRestaurantForm(FormValidationAction):

def name(self) -> Text:

return "validate_restaurant_form"

def cuisine_db() -> List[Text]:

"""Database of supported cuisines"""

return ["caribbean", "chinese", "french"]

def validate_cuisine(

dispatcher: CollectingDispatcher,

) -> Dict[Text, Any]:

"""Validate cuisine value."""

if slot_value.lower() in self.cuisine_db():

return {"cuisine": slot_value}

return {"cuisine": None}

You can also extend the Action class and retrieve extracted slots with tracker.slots_to_validate to fully customize the validation process.

Anda mungkin ingin melihat