Skip to content

December 3rd, 2021

Slots in Rasa Open Source 3.0

  • portrait of Rachael Tatman

    Rachael Tatman

In Rasa Open Source 3.0 you now need to explicitly state how each slot will be set in the domain file. This replaces the previous method where slots were sometimes set implicitly, which resulted in duplicated work and occasionally confusing bugs. You can find more information on the docs and migration guide.

Explicit is better than implicit. -The Zen of Python, Tim Peters

Why did we change this?

In short: while our previous methods of filling slots could save some development time in the best case scenario, the cost of this time savings was unexpected behaviour, duplicated effort and developer confusion.

If you used slots in previous versions of Rasa, you may have noticed that there were several ways to fill them. If you had an entity that shared a name with a slot, whenever that entity with that name was extracted it would automatically fill the slot. The downside of this is that it led to numerous problems. For example, in this one, a slot was auto-filled through the entity and slot name matching but interfered with correctly asking for that slot in a later form. And in this one an extracted entity was erroneously filling multiple slots simultaneously.

Perhaps the most commonly unexpected behavior with automated slot filling was in updating slots over the course of a conversation. An entity would be extracted that unexpectedly updated a slot when it was not intended and, since this behavior happened implicitly, it led to a lot of developer frustration.

You could also specify how a slot would be set in a form. However, if you had several similar forms that used the same slot mapping you needed to specify the exact same mapping every time. This resulted in duplication of the same slot mappings across multiple forms, as described in more depth in this issue.

In addition to these problems, having two separate ways to set slot mappings was confusing for developers learning Rasa. It also meant that you needed to dig into multiple files to understand why slots were being set in a certain way. The automated filling of slots also made it easy to confuse entities (extracted spans of user generated text) with slots (variables you store and reference over the course of a conversation). While entities can be used to set slots, entity extraction is not always the best way to set various slots. For something like “accept” or “decline”, for example, it would be easier to use an intent.

In order to address these issues, in Rasa Open Source 3.0 we have a new way of specifying slot mappings: a single, global slot mapping which is specified in the domain file. Internally, slots are now set by a new built in action, action_extract_slots. It is run at the end of the NLU pipeline but before the dialog manager and loops through each slot and it’s mappings and sets them as needed.

The new approach has a number of benefits.

  • It makes behavior more consistent: all slots are now set the same way regardless of whether or not they’re filled by an entity
  • It dramatically reduces the amount of code needed to make multiple forms that set the same slots
  • It is much simpler to overwrite (or not) slots during the course of a conversation

This change does mean slightly more upfront work for a simple assistant if all your slots were set by a single entity, since you will need to explicitly describe how the slots are set. On balance, however, we believe that this change will end up saving considerable time and frustration.

What do the new slot mappings look like?

Starting in 3.0, you will need to specify how each slot will be filled in the domain file under the “slot” section. For slots filled from entities, the new format looks like this:

YAML
slots:
cuisine:
type: text
mappings:
- type: from_entity
entity: cuisine

This will explicitly map the entity “cuisine” to the slot “cuisine” when the relevant entity is detected in the text.

For slots filled from intents, the new format will look like this:

YAML
slots:
outdoor_seating:
type: bool
mappings:
- type: from_intent
intent: affirm
value: true
- type: from_intent
intent: deny
value: false

Here the outdoor_seating slot will be filled with the value “true” if the affirm intent is detected and “false” if the deny intent is detected. This type of mapping will be most helpful for either very specific intents or if your assistant is very simple.

However, if you only want outdoor_seating to be filled when the relevant intents show up in a form, you’ll need to add additional specifications.

YAML
slots:
outdoor_seating:
type: bool
mappings:
- type: from_intent
intent: affirm
value: true
conditions:
- active_loop: restaurant_form
requested_slot: outdoor_seating
- type: from_intent
intent: deny
value: false
conditions:
- active_loop: restaurant_form
requested_slot: outdoor_seating

The other major change is in how forms are specified in the domain file. Rather than having to list how each slot in the form will be filled you now nearly need to list the slots you need (since the mappings have already been defined). As a result, the new form syntax much simpler than before.

YAML
forms:
restaurant_form:
required_slots:
- cuisine
- num_people
- outdoor_seating

Migration guide & docs

You are of course free to migrate slots by hand from your 2.0 chatbot, but the simplest way to migrate is to use our automatic migration tool using this command:

rasa data migrate -d DOMAIN --out OUT_PATH

This will create a 3.0 domain file at the path you specify as well as backing up your current domain file.

If you have a more complex use case check out the documentation for additional details. or ask on the forums. We hope you find the new, explicit slot mappings a helpful update and if you have any questions, please reach out to us on the forums.