responses.yml holds named text templates the framework delivers verbatim. Use
it for wording that must be exact: legal disclosures, compliance notices,
regulated confirmations. Everything else should stay prose so the agent sounds
natural.
skills/card_replace/responses.yml
responses:. Each name maps to a list of variants. At
delivery the engine selects one variant from that list (see
Conditional variants below). A response with a single
variant and no condition always selects that single variant.
An entry is either a mapping with a text key, or a plain string:
Conditional variants
Add an optionalcondition on a variant to gate its wording on current memory.
Conditions use the same expression grammar as skill
requires: and prose if: lines.
How a variant is selected
When a response is delivered, the engine evaluates variants in YAML order:- Skip variants with no
conditionduring this pass. - For each conditioned variant, evaluate its
conditionagainst readable memory. The first variant whose condition is true is delivered. - If none match, deliver the default variant — the one that omits
condition. - If every variant is unconditioned, deliver the first variant.
metadata.rephrase applies to whichever variant is selected, not always the
first variant.
Default variant rules
When any variant on a response has acondition, exactly one variant
must omit condition. That variant is the fallback when no condition matches.
It may appear anywhere in the YAML list — first, last, or between
conditioned variants. The engine skips default variants while evaluating conditions,
then delivers that single fallback variant.
rasa train rejects:
- empty or non-list response entries (must be a non-empty variant list)
- empty or whitespace-only
texton any variant - invalid or empty
conditionsyntax (must be a string expression) - memory references in a
conditionthat are not declared in skill or projectmemory.yml - conditioned variants with no default, or more than one default
rasa data validate, packaging):
All project
responses.yml files are checked; findings accumulate across files.
Runtime model load (packaged agent) still uses strict registry parsing.
Unknown variant keys there raise ValidationError with code
responses.registry.invalid_variant and stop loading that file.
Unsupported variant keys
Onlytext, metadata, and condition are permitted on a variant.
channel: and buttons: are not supported in this release — adding them
is reported at project validation time and causes strict registry load to fail
at runtime.
Where the file lives
At load, every file is merged into one flat registry, later sources
overriding earlier ones on duplicate names:
- Packaged system defaults
- Each bundled default skill’s
responses.yml - Each project skill’s
responses.yml, in directory order - The project-root
responses.yml
utter_silence_timeout_check_in, for example, replaces
the check-in the bundled default_silence_timeout skill delivers.
The bundled default_session_start skill has no greeting response. To greet,
override the skill as described in
Start a conversation.
Because the registry is flat, response names are global rather than scoped to
the skill that declares them. Prefix names with the skill (utter_card_replace_completed)
so two skills keep their wording distinct.
Interpolation
A placeholder in braces is replaced with a memory value at delivery time. Two forms work, and they resolve differently:public field. The bare form is
convenient for a skill’s own entries and follows the same resolution order a
tool’s context.memory.get() uses.
A placeholder whose value is unset at delivery time is left in the text as
written, so interpolate only values you know are set by the time the response is
sent, typically ones written earlier in the same ordered block.
Interpolation applies to responses. For live values in skill.md instruction
prose, use @memory.… instead — see skill.md. Do not
put bare session.* in free prose; train fails and points you at @memory.
metadata.rephrase
A response may opt into being reworded by the LLM instead of delivered verbatim:
rephrase: true the orchestrator makes a tool-free LLM call to reword the
selected variant’s text in context, and falls back to the literal text if
that call fails or comes back empty. Leave it off (the default) for anything
compliance-sensitive: that is the entire point of declaring the response.
How a response is delivered
Four things reference a response by name:
The two step fields differ:
utter: is accepted as a step-level alias for action: and is normalised at
load. Prefer action:.
rasa train validates every response name referenced from any of the four
places above, and runs per-variant checks on project-authored responses.yml
files (non-empty text, valid conditions, default-variant rules). A name that is
not in the registry, or a malformed variant list, is caught before the agent
runs.
See also
- Responses concept: when to declare wording
- skill.md: the
utter:trigger andtool_constraintsshapes - Ordered block steps: the step fields that deliver responses
- Conditions: the namespaced reference form