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.
Custom Output Payloads#
You can send any arbitrary output to the output channel using the custom key. The output channel receives the object stored under the custom key as a JSON payload.
Here's an example of how to send a date picker to the Slack Output Channel:
text: "Make a bet on when the world will end:"
initial_date: '2019-05-21'
Session configuration#
A conversation session represents the dialogue between the assistant and the user. Conversation sessions can begin in three ways:
the user begins the conversation with the assistant,
the user sends their first message after a configurable period of inactivity, or
a manual session start is triggered with the /session_start intent message.
You can define the period of inactivity after which a new conversation session is triggered in the domain under the session_config key.
Available parameters are:
The default session configuration looks as follows:
session_expiration_time: 60 # value in minutes, 0 means infinitely long
carry_over_slots_to_new_session: true # set to false to forget slots between sessions
This means that if a user sends their first message after 60 minutes of inactivity, a new conversation session is triggered, and that any existing slots are carried over into the new session. Setting the value of session_expiration_time to 0 means that sessions will not end (note that the action_session_start action will still be triggered at the very beginning of conversations).
A session start triggers the default action action_session_start. Its default implementation moves all existing slots into the new session. Note that all conversations begin with an action_session_start. Overriding this action could for instance be used to initialize the tracker with slots from an external API call, or to start the conversation with a bot message. The docs on Customizing the session start action shows you how to do that.
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"
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_
- 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_
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.
Multiple Domain Files#
The domain can be defined as a single YAML file or split across multiple files in a directory. When split across multiple files, the domain contents will be read and automatically merged together.
Using the command line interface, you can train a model with split domain files by running:
rasa train --domain path_to_domain_directory
The intents key in your domain file lists all intents used in your NLU data and conversation training data.
Multiple Domain Files#
The domain can be defined as a single YAML file or split across multiple files in a directory. When split across multiple files, the domain contents will be read and automatically merged together. You can also manage your responses, slots, custom actions in Rasa Studio.
Using the command line interface, you can train a model with split domain files by running:
rasa train --domain path_to_domain_directory
Responses are templated messages that your assistant can send to your user. Responses can contain rich content like buttons, images, and custom json payloads. Every response is also an action, meaning that it can be used directly in an action step in a flow. Responses can be defined directly in the domain file under the responses key. For more information on responses and how to define them, see Responses.
Actions are the things your bot can do. For example, an action could:
All custom actions should be listed in your domain.
Rasa also has default actions which you do not need to list in your domain.
Slots are your assistant'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 default value. Different slot types exist to restrict the possible values a slot can take.
If you decide to fill slots through response buttons where the payload syntax issues SetSlot command(s), note that the slot name must not include certain characters such as (, ), = or ,.
A text slot can take on any string value.
A boolean slot can only take on the values true or false. This is useful when you want to store a binary value.
A categorical slot can only take on values from a predefined set. This is useful when you want to restrict the possible values a slot can take.
If the user provides a value where the casing does not match the casing of the values defined in the domain, the value will be coerced to the correct casing. For example, if the user provides the value LOW for a slot with values low, medium, high, the value will be converted to low and stored in the slot.
If you define a categorical slot with a list of values, where multiple of the values coerce to the same value, a warning will be issued and you should remove one of the values from the set in the domain. For example, if you define a categorical slot with values low, medium, high, and Low, the value Low will be coerced to low and a warning will be issued.
A float slot can only take on floating point values. This is useful when you want to store a number with a decimal point.
This slot type can take on any value. This is useful when you want to store any type of information, including structured data like dictionaries.
A list slot can take on a list of values. Note that the list slot type is only supported in custom actions when building an assistant with CALM. List slots cannot be filled with flows in either the collect or set_slots flow step types.
When building an assistant with CALM, you can configure slot filling to either use nlu-based predefined slot mappings or the newly introduced from_llm slot mapping type.
You can continue using the nlu-based predefined slot mappings such as from_entity or from_intent when building an assistant with CALM. In addition to including tokenizers, featurizers, intent classifiers, and entity extractors to your pipeline, you must also add the NLUCommandAdapter to the config.yml file. The NLUCommandAdapter will match the output of the NLU pipeline (intents and entities) against the slot mappings defined in the domain file. If the slot mappings are satisfied, the NLUCommandAdapter will issue set slot commands to fill the slots.
If during message processing, the NLUCommandAdapter issues commands, then the following command generators in the pipeline such as LLM-based command generators will be entirely bypassed. As a consequence, LLM-based command generators will not be able to fill slots by issuing set slot commands at any point in the conversation flow. If the LLM-based command generator issues commands to fill slots with nlu-based predefined mappings, these set slot commands from LLM-based command generator are ignored. If no other commands were predicted for the same turn, then the assistant will trigger the cannot_handle conversation repair pattern.
Sometimes the user message may contain intentions that go beyond setting a slot. For example, the user message may contain an entity that fills a slot but also starts a digression that must be handled. In such cases, we recommend using NLU triggers to handle those specific intents within flows. Please refer to the Impact of slot mappings in different scenarios section for more details.
In a CALM assistant built with flows and using NLU components to process the message, the default action action_extract_slots will not run, because the slot set events are applied to the dialogue tracker during command execution. This ensures that this default action does not overwrite CALM set slot(./dialogue-understanding.mdx#set-slot) commands and does not duplicate SlotSet events that were already applied to the dialogue tracker.
In the case of coexistence, the action_extract_slots action will be executed only when the NLU-based system is active.
You can use the from_llm slot mapping type to fill slots with values generated by LLM-based command generators. This is the default slot mapping type if the mappings are not explicitly defined in the domain file.
In this example, the user_name slot will be filled with the value generated by the LLM-based command generator. The LLM-based command generator is allowed to fill this slot at any point in the conversation flow, not just at the corresponding collect step for this slot.
If you have defined additional NLU-based components in the config.yml pipeline, these components will continue to process the user message however they will not be able to fill slots. The NLUCommandAdapter will skip any slots with from_llm mappings and will not issue set slot commands to fill these slots. Please refer to the Impact of slot mappings in different scenarios section for more details.
Note that a slot must not have both from_llm and NLU-based predefined mappings or custom slot mappings. If you define a slot with from_llm mapping, you cannot define any other mapping types for that slot.
You can define conditions for slot mappings to be satisfied before the slot is filled. The conditions are defined as a list of conditions under the conditions key. Each condition can specify the flow id that must be active to the active_flow property.
This is particularly useful if you define several slots mapped to the same entity, but you do not want to fill all of them when the entity is extracted.
- active_flow: greet_user
- active_flow: issue_invoice
You can use the custom mapping type to define custom slot mappings for slots that should be filled by a custom action. The custom action must be specified in the action property of the slot mapping. You must also list the action in the domain file under the actions key.
- action_fill_user_name
action: action_fill_user_name
In this example, the user_name slot will be filled by the action_fill_user_name custom action. The custom action must return a SlotSet event with the slot name and value to fill the slot.
Note that if you're using the action_ask_
If you are using custom validation actions (using the validate_
If you are training with the --skip-validation flag and you have defined slots with custom slot mappings that do not
specify the action property in the domain file, nor do they have corresponding action_ask_
You can also run this check via the rasa data validate command.
This section clarifies which components in a CALM assistant built with flows and a NLU pipeline are responsible for filling slots in different scenarios when the flow is at either the collect step for slot name or at any other step.
Main takeaway is that the NLUCommandAdapter cannot fill slots with from_llm mappings at any point in the conversation.
You can provide an initial value for any slot in your domain file:
Checkpoints and OR statements#
Checkpoints and OR statements should be used with caution, if at all. There is usually a better way to achieve what you want by using Rules or the ResponseSelector.
You can use checkpoints to modularize and simplify your training data. Checkpoints can be useful, but do not overuse them. Using lots of checkpoints can quickly make your example stories hard to understand, and will slow down training.
Here is an example of stories that contain checkpoints:
- story: beginning of flow
- action: action_ask_user_question
- checkpoint: check_asked_question
- story: handle user affirm
- checkpoint: check_asked_question
- action: action_handle_affirmation
- checkpoint: check_flow_finished
- story: handle user deny
- checkpoint: check_asked_question
- action: action_handle_denial
- checkpoint: check_flow_finished
- checkpoint: check_flow_finished
- action: utter_goodbye
Unlike regular stories, checkpoints are not restricted to starting with user input. As long as the checkpoint is inserted at the right points in the main stories, the first event can be a custom action or a response as well.
Another way to write shorter stories, or to handle multiple intents or slot events the same way, is to use an or statement. For example, if you ask the user to confirm something, and you want to treat the affirm and thankyou intents in the same way. The story below will be converted into two stories at training time:
- action: utter_ask_confirm
- action: action_handle_affirmation
You can also use or statements with slot events. The following means the story requires that the current value for the name slot is set and is either joe or bob:
- action: utter_greet
or statements can be useful, but if you are using a lot of them, it is probably better to restructure your domain and/or intents. Overusing OR statements will slow down training.
Using Variables in Responses#
You can use variables to insert information into responses. Within a response, a variable is enclosed in curly brackets. For example, see the variable name below:
- text: "Hey, {name}. How are you?"
When the utter_greet response is used, Rasa automatically fills in the variable with the value found in the slot called name. If such a slot doesn't exist or is empty, the variable gets filled with None.
Another way to fill in a variable is within a custom action. In your custom action code, you can supply values to a response to fill in specific variables. If you're using the Rasa SDK for your action server, you can pass a value for the variable as a keyword argument to dispatcher.utter_message:
dispatcher.utter_message(
template="utter_greet",
If you use a different custom action server, supply the values by adding extra parameters to the responses your server returns:
"template":"utter_greet",
You can make your assistant's replies more interesting if you provide multiple response variations to choose from for a given response name:
- text: "Hey, {name}. How are you?"
- text: "Hey, {name}. How is your day going?"
In this example, when utter_greet gets predicted as the next action, Rasa will randomly pick one of the two response variations to use.
You can now set an ID for any response. This is useful when you want to use the NLG server to generate the response.
Type for ID is string.
Example of response variations with ID:
text: "Hey, {name}. How are you?"
text: "Hey, {name}. How is your day going?"
Dynamic Form Behavior#
By default Rasa Open Source will ask for the next empty slot from the slots listed for your form in the domain file. If you use custom slot mappings and the FormValidationAction, it will ask for the first empty slot returned by the required_slots method. If all slots in required_slots are filled the form will be be deactivated.
If needed, you can update the required slots of your form dynamically. This is, for example, useful when you need further details based on how a previous slot was filled or you want to change the order in which slots are requested.
If you are using the Rasa SDK, we recommend you to use the FormValidationAction and
override required_slots to fit your dynamic behavior. You should implement
a method extract_
from typing import Text, List, Optional
from rasa_sdk.forms import FormValidationAction
class ValidateRestaurantForm(FormValidationAction):
def name(self) -> Text:
return "validate_restaurant_form"
async def required_slots(
slots_mapped_in_domain: List[Text],
dispatcher: "CollectingDispatcher",
domain: "DomainDict",
) -> Optional[List[Text]]:
additional_slots = ["outdoor_seating"]
if tracker.slots.get("outdoor_seating") is True:
additional_slots.append("shade_or_sun")
return additional_slots + slots_mapped_in_domain