January 3rd, 2020
The Rasa Masterclass Handbook: Episode 6
The Rasa Masterclass is a weekly video series that takes viewers through the process of building an AI assistant, all the way from idea to production. Hosted by Head of Developer Relations Justina Petraityte, each episode focuses on a key concept of building sophisticated AI assistants with Rasa and applies those learnings to a hands-on project. At the end of the series, viewers will have built a fully-functioning AI assistant that can locate medical facilities in US cities.
To supplement the video content, we'll be releasing these handbooks to summarize each episode. You can follow along as you watch to reinforce your understanding, or you can use them as a quick reference. We'll also include links to additional resources you can use to help you along your journey.
In Episode 6 of the Rasa Masterclass, we cover essential components in building dialogue management models with Rasa, including domain, custom actions, slots, and more.
This episode builds heavily on Episode 5, in which we covered dialogue management, handled by Rasa core. Dialogue management is the function that controls the next action the assistant takes during a conversation. Based on the intents and entities extracted by Rasa NLU, as well as other context, like the conversation history, Rasa core decides which text response should be sent back to the user or whether to execute custom code, like querying a database.
If you're just joining, be sure to catch up on previous episodes before moving on to Episode 6.
Want to skip straight to the code? Get the full code for this episode on GitHub.
Domain File in Rasa
The domain is an essential component of a Rasa dialogue management model. It defines the environment in which the assistant operates, including:
- What the user means: specifically, what intents and entities the model can understand
- What responses the model can provide: such as utterances or custom actions
- What to say next: what the model should be ready to respond with
- What info to remember: what information an assistant should remember and use throughout the conversation
Building a Domain for Medicare Locator
To understand the domain better, let's build out an actual example domain for our medicare locator assistant.
The domain of an assistant is usually specified in a domain.yml file of the project directory.
Earlier, we ran the
rasa init function and a domain was automatically created for our Moodbot assistant. This domain is a nice starting point for creating a custom domain for our medicare locator assistant.
In this Moodbot domain, you can see three sections which are necessary to build an assistant with Rasa: intents, actions and templates. We'll start by discussing these sections, and then add two more sections that are necessary to build many assistants, including our medicare locator: entities and slots.
The section labeled intents defines a list of intents that the assistant is able to understand. These details come from the NLU model (nlu.md). The intents section is where you need to provide the labels of all the intents that you trained your NLU model to understand. In earlier episodes of the Rasa Masterclass, we created new intents for the medicare locator assistant, which you can see below in the nlu.md file. Those two intents (
## intent:inform and
## intent:search_provider ) need to be added to the domain file for the medicare assistant.
The section called actions should contain the list of all utterances and custom actions an assistant should use to respond to user's inputs. These should come from your stories data in the stories.md file.
In the screenshot above on the right, you can see the actions created earlier for the medicare locator assistant (
action_facility_search), contained in the stories file. We need to add those actions the domain file also.
The final section in the domain is called templates. The templates section is where you can define the specific text responses that your assistant will provide to the user, based on which utterance is predicted by the dialogue management model.
Each utterance can have more than one template, that is, more than one specific text response that captures the meaning of the utterance. Utterances can also go beyond simple messages, and can include things like images, buttons, custom payloads (for a datepicker, for example), and more.
Below you can see some templates created for our medicare locator assistant.
Another important section of the domain file is for entities. While the Moodbot assistant domain does not have this section, the NLU model for our medicare locator assistant does extract entities, like location and facility type. Since entities influence how an assistant responds to a user's input, entities must included in the domain file.
As you can see, we've created the entities section in the domain file, and listed the entity labels that the medicare locator NLU model (nlu.md) was trained to extract. In our case, we have two entities,
Custom Actions in Rasa
Adding response templates directly to the domain file is the easiest way to define the message an assistant sends the user once a specific utterance is predicted. But there is another way to achieve the same result - by creating custom actions.
Custom actions are response actions which include custom code. That custom code can define anything from a simple text response to a backend integration - an API call, connecting to the database, or anything else your assistant needs to do.
Custom actions are defined in a file called actions.py, containing python code, as the file extension suggests. Again, the
rasa init function created a sample file for us, this time including the code for a simple "Hello World" custom action. Let's look at "Hello World" to better understand custom actions.
The import statement (boxed in red, below) imports modules (like rasa sdk) that are necessary to ensure that the custom action server and the server running your assistant can exchange information.
Next, we have the class of the custom action. The class consists of two functions -
The function name in the class must match the name of the custom action in your training stories (in stories.md). For example, when the custom action
action_hello_world is included in a story, Rasa knows to run the code defined in the custom action class named
run function within the class contains the code to be executed, once the custom action is predicted. The run function is where you can define what the custom action actually does. Note the
dispatcher elements, which are very useful and important pieces of the run function:
trackerkeeps track of what happens at each point within a dialogue - what intents were predicted, which entities where extracted, as well as other information
dispatcheris the element that sends the response back to the user.
Updating this actions file for our medicare locator would look like this. We created a class called
ActionFacilitySearch that, when the action called
action_facility_search is predicted, the assistant responds, "Sure, I'm on it!"
An important thing to remember about custom actions is that the names of these actions must match the actions included in the domain file.
As you can see, the domain, NLU training data, and stories data files are very closely connected. There is no specific rule for which one should come first, but you will notice that changes in one file will result in changes in other files. Developing an assistant with Rasa usually takes a number of iterations; that's why you should expect to constantly go back and forth between these files and make modifications as you go.
Slots in Rasa
Another important element of the domain file - very important for dialogue management in Rasa - is slots. Slots function as the assistant's memory, and are used by your assistant to remember important details throughout the conversation and apply those details in context to drive the conversation. Slots act as a key-value pair to store information critical to the conversation with the user. This information can be provided by the user (e.g., entity values extracted by the NLU model) or gathered from outside the conversation (e.g.,results extracted from the external database).
Earlier in the Masterclass, we covered situations in which details provided by the user influence the path of the conversation. For our medicare locator assistant, if the user wants help finding a medicare facility, the assistant needs both location and facility type to perform the search. We trained the NLU model to extract the location and the facility type from the user requests, if provided. If the user asks for a facility search, but hasn't yet provided location and facility type, the assistant directs the conversation to ask for them, before performing the search. In this way, the dialogue management model uses the provided information to drive the conversation.
This is implemented in Rasa using slots. The details of location and facility type are stored as slots, and allow the dialogue management model to use the content of the slots to determine the next step in the conversation.
Slots have a dedicated section in a domain file. To define a slot, you have to provide two pieces of information - slot name and a slot type ( in the screenshot above,
type: text ). Slot names can match the names of the entities. If there is a match, the values of extracted entities are automatically set as slots.
Slot types are extremely important and have a direct influence on the predictions the dialogue management makes. For some types, only the presence or the absence of the slot matters, in other cases the values of the slots matter too.
Slot Type: text
- Use for: user preferences where you care only whether or not the preference has been specified
- A slot of the type
textonly tells Rasa whether the slot has been set or not. The actual value doesn't make any difference.
- Slots with type
textare useful when the dialogue should take different turns depending on whether or not users provided specific details.
- Example: if the slot
locationhas not been set, an assistant should ask for this detail, otherwise, move forward and drive the conversation further.
Slot Type: bool
- Use for: true or false
- When using this slot type, not only the presence or absence of this slot matters, but also the value
- Example: the dialogue management model checks if a slot value is true and based on that, drives the conversation further.
Slot Type: categorial
- Use for: slots which can take one of N values
- Both the presence of and the value of the categorical slot matters.
- Categorical slots are useful when a piece of information can take one of N possible values.
- For example: slot with possible values of low, medium, and high. A dialogue management model can take the value of the slot into account and use it to make the prediction for the next best action to respond with.
Slot Type: float
- Use for: continuous values
- Useful to store continuous values like float numbers
- Both the presence of the slot and the value matters
- The float slot has the parameters
max_value, which lets you define the highest and lowest possible values for the slot. Anything that is above max_value will be set to max_value while everything that is below min_value will be set to min_value.
Slot type: list
- Use for: list of values
- If the NLU model extracts more than one value for an entity, you might want to store all the provided values.
- A slot with the type list is designed to store details with multiple values.
- The length and values of of a list slot doesn't really matter; what matters is if the slot is empty or filled.
Slot type: unfeaturized
- Use for: continuous values
- Useful when you want to use slots to store the information as extracted, but not to drive the dialogue.
- Slot type unfeaturized means that neither the value of the slot nor whether it's filled will influence the dialogue management model's predictions.
Using Slots in the Medicare Locator
Here we will define the slots for the medicare locator assistant -
In addition to driving conversations, slots can be useful in other situations when developing your assistant.
Using Slots to Customize Templates
Slots can be used when creating the responses of an assistant. Slots hold the values of important details, which can be added to utterance templates to make them more personal. Simply provide the slot name in curly brackets within the template.
Slots can also be used in custom actions when running backend integrations, querying database, making API calls, and more.
Slots & Custom Actions
Using slots, let's update our custom action
A tracker keeps track of the slots set at each dialogue state. The values of these slots can be returned using the
get_slot method, and providing the name of the slot we need ("facility_type"). Then we can enable the custom action to extract the user's requested facility type and use this slot to find an address of the facility that meets the user's requirements.
For the sake of simplicity in this example, we hard-coded a suggested facility address (300 Hyde St, San Francisco).
Slots can be set by the NLU model as well as by custom actions. This is useful when important information is provided by running a backend integration, which should be saved and used later on throughout the conversation. For example, when our medicare locator assistant finds the address of a facility for the user, it is useful to save this piece of information, because the user may ask follow-up questions about the facility later in the conversation. Saving the address as a slot lets your assistant handle this situation. You can set slots in custom actions using the
In our medicare locator, we can import the SlotSet event, and update the return statement of the run function with the
SlotSet event, providing the slot name and the value.
An important note about slots set using a custom action: Rasa requires that these slot events be reflected in the training stories (stories.md).
In our medicare locator assistant,
action_facility_search sets a slot
address, and so in our stories file, this action must be followed by an event slot. This is necessary so that the dialogue management model can access these details to make the right decision on how to respond going forward.
Lastly, remember that all slots have to be listed in the domain. Since we created a new slot
address, it needs to be added to the domain file as well.
Slot values are kept in memory until reset. If the slot is set by the NLU model, then every time a new value is extracted, the slot value will be updated with the most recently extracted one. The same is true of slots set by the custom actions. In some situations you may want to reset specific or all slots. To achieve that, your can use Rasa in-built events like
Training your Rasa Assistant
With domain and custom actions in place, we can train the first version of our assistant and see how it works.
To do that we can use the function called
rasa train which will retrain the NLU model alongside the dialogue management model. Once the model is trained, we can test in on our command line by running a command
rasa shell. The
rasa train command will also tell us if we forgot any details in the domain file.
Custom actions run on a separate server than the server that the models run on. Rasa will call an end point, which you specify, when a custom action is predicted. This endpoint should be a web server that reacts to the call, runs the code, and optionally, returns information to modify the dialogue state. The full configuration of the custom action server is provided in the file in the project directory named
Let's update the file to use the endpoint for our medicare locator model, by updated this
Now we can start the custom action server using the Rasa CLI function
rasa run actions and load the assistant for us to test, using the Rasa CLI function
rasa shell. With this, we have the very first version of our medicare locator assistant.
We hope you enjoyed this deep dive into the Rasa domain file, and are ready to use intents, actions, templates, entities, custom actions, and slots in your Rasa assistant.
In this episode, we used a default dialogue management model created by the
rasa init function. This model is defined using training policies - and training policies will be the focus of Episode 7 of the Rasa Masterclass. This next episode will cover what the training policies are, how they work, how to define them in the configuration file, and in what situations one policy may be better than another.
If you're coding along, now would be the time to start having conversations with your assistant, to see how it works. Keep up the progress, and if you get stuck, ask us a question in the Community forum.