Skills
Voice and chat agents in Rasa are built from composable skills, coordinated at runtime by an orchestrator called Maestro. Reliability at scale comes from progressive control: each skill starts as plain instructions, and you add deterministic guarantees only where the business needs them.
This page builds one skill, card_replace, from a single file to a constrained procedure. Scroll to follow along.
Start with skill.md
A skill is a folder: instructions for the LLM, plus optional tools and references. At its simplest, the folder holds one file. Frontmatter with a name and description, then instructions in plain language. The folder name is the skill id; see Project structure for the full layout.
No flowcharts, no state machine. The LLM interprets the instructions in conversation.
Add tools/
Define tools in a tools/ subfolder and they are automatically available while the skill is active. No registration. A tool returns structured data to the LLM and can store results in memory for later steps.
Add references/
FAQs, policies, and other reference material live in a references/ subfolder. They are indexed at training time and retrieved on demand, so the agent can answer from them without carrying them in every prompt.
Progressive control
Everything so far is instructions an LLM interprets. Where a mistake is expensive, you constrain it, with tool constraints, skill prerequisites, or ordered blocks.
These are framework guarantees enforced by the runtime, not suggestions to the model. A tool whose constraint isn’t met is not available for the LLM to call; a jailbreak can’t change that.
Tool constraints
A requires condition in the frontmatter gates when a tool becomes available. Until selected_card_id exists in memory, lock_card is removed from the tool schema entirely. The model can’t call a tool it never sees.
Scoped instructions
Different situations need different instructions. if: markers scope a paragraph to a memory value: when replacement_reason is stolen, only the stolen paragraph is visible to the LLM. Non-matching branches are stripped from the prompt entirely.
Skill prerequisites
A requires block at the root of the frontmatter gates the whole skill: Maestro won’t activate card_replace until authenticated is true. The only contract with the authentication skill is the memory key.
Ordered blocks
For steps that must run in exact order, add an ordered_block to the instructions. The LLM decides when to invoke @block.pick_card; the runtime executes the steps inside it in order.
If a whole skill must follow a strict procedure, replace the entire body with an ordered block. Start simple, add control incrementally, and build fully deterministic skills where you need them.