| name | rasa-managing-slots |
| description | Defines and manages slots in Rasa CALM assistant domain files. Use when creating or editing slot definitions, choosing slot types and mappings, configuring validation, or controlling how slots get filled and persist across flows.
|
| license | Apache-2.0 |
| metadata | {"author":"rasa","version":"0.1.0","rasa_version":">=3.12.0","docs-url":"https://rasa.com/docs/reference/primitives/slots/"} |
Managing Slots in Rasa
Workflow
- Identify what information the assistant needs to remember.
- Review existing slots in the domain — reuse before creating new ones.
- Choose the most restrictive slot type that fits the data (see "Choosing a slot type").
- Define the slot in the domain file with type and mapping (see "Slot mappings").
- Set an
initial_value if the slot needs a default.
- Add validation if the slot requires format or range checks
(see "Validation strategies").
- Use the slot in flows via
collect or set_slots steps.
File organization
Slots are defined in domain YAML files, typically under domain/ or in a single
domain.yml. Before creating new slots, check the existing domain layout — the user's
existing convention always takes precedence.
Domain files are commonly split by business process, so each flow's slots, responses,
and actions live together (e.g. domain/transfer_money.yml).
domain/
├── transfer_money.yml # slots + responses + actions for one flow
├── book_appointment.yml
└── shared.yml # slots reused across multiple flows
Choosing a slot type
Pick the most restrictive type that fits the data. This prevents invalid values and
helps the LLM within the Command Generator extract correctly.
| Type | Use when | Example |
|---|
text | Any string value | names, emails, free-text input |
bool | Binary yes/no | is_authenticated, terms_accepted |
categorical | Value must come from a fixed set (auto-coerces casing) | account types, priority levels |
float | Numeric value with decimals | temperature, amounts, scores |
any | Structured data (dicts, mixed types) | API responses, shopping carts |
list | List of values (custom actions only) | item lists — cannot be filled via collect or set_slots |
slots:
patient_name:
type: text
terms_accepted:
type: bool
priority:
type: categorical
values:
- low
- medium
- high
temperature:
type: float
search_results:
type: any
Slot mappings
Mappings define how a slot gets filled. Choose based on what controls the slot
value.
A slot can combine from_llm with NLU-based mappings — NLU takes priority when both
extract a value. Use allow_nlu_correction: true on from_llm if the LLM within the
Command Generator should be able to correct NLU-filled values.
| Mapping | When to use |
|---|
from_llm | Default for CALM (assumed if no mapping defined). The LLM within the Command Generator extracts value from user messages at any point in the conversation, not just at the collect step. |
controlled | Slot should only be filled by custom actions, button payloads, or set_slots. NLU and the LLM within the Command Generator cannot fill it. Use run_action_every_turn to keep the slot up to date on every turn. |
from_entity | NLU pipeline extracts a specific entity. Requires NLUCommandAdapter in config. Use conditions with active_flow to disambiguate when multiple slots map to the same entity. |
from_intent | NLU pipeline maps a predicted intent to a value. Requires NLUCommandAdapter in config. |
slots:
destination_city:
type: text
mappings:
- type: from_llm
is_authenticated:
type: bool
mappings:
- type: controlled
session_token:
type: text
mappings:
- type: controlled
run_action_every_turn: action_refresh_session
sender_name:
type: text
mappings:
- type: from_entity
entity: person
conditions:
- active_flow: transfer_money
username:
type: text
mappings:
- type: from_llm
allow_nlu_correction: true
- type: from_entity
entity: username
Initial values
Set a default value for slots that should not start empty. The slot resets to this value
(not null) when a flow ends. Also useful for optional collect steps with
ask_before_filling: false — the flow skips the question if the slot already has a
value.
slots:
language:
type: categorical
values:
- en
- de
- fr
initial_value: en
num_retries:
type: float
initial_value: 0
Validation strategies
Three levels of validation, from simplest to most complex:
| Validation need | Where to define | How |
|---|
| Format/range checks (regex, length) | Domain — validation.rejections on the slot | Runs globally whenever the slot is set. refill_utter is optional (defaults to utter_ask_{slot_name}). |
| Business rule tied to a specific flow | Flow — rejections on the collect step | Only runs at that collect step. |
| External API or database check | Custom action named validate_{slot_name} | Rasa runs it automatically when the slot is collected. |
slots:
phone_number:
type: text
mappings:
- type: from_llm
validation:
rejections:
- if: not (slots.phone_number matches "^\d{10}$")
utter: utter_invalid_phone
refill_utter: utter_ask_phone_again
Naming conventions
This section proposes default conventions. If the user's project already follows
different conventions, match those instead.
- Use
snake_case: patient_name, order_id, is_authenticated
- Use descriptive nouns: name after the data, not the flow —
email not collect_email
- Prefix booleans with
is_ or has_: is_verified, has_insurance
- Avoid special characters
(, ), =, , in slot names — they break response button
payloads