# Maestro > Build AI agents with exactly the control you need, and no more. Maestro is a framework for building conversational AI agents with progressive control: start with prose instructions and auto-discovered tools, then add framework-enforced guarantees incrementally without restructuring. A skill is a folder. `skill.md` is the only required file; `memory.yml`, `responses.yml`, `tools.py`, and `references/` are added as the skill needs them. ## Docs ### Get Started - [Introduction](/): What Maestro is, progressive control, what a skill looks like - [Getting Started](/getting-started): Install and build your first agent with the Rasa Copilot - [Skills](/skills): The building block of every agent ### Building Skills - [Instructions](/concepts/instructions): The plain-language body of a skill - [Tools](/concepts/tools): Typed functions a skill can call - [Memory](/concepts/memory): Values a skill tracks across a conversation - [References](/concepts/references): Knowledge the agent answers questions from - [Responses](/concepts/responses): Verbatim wording the LLM never rewrites ### Progressive Control - [Tool Constraints](/build-guide/tool-constraints): requires:, requires_confirmation:, on_success:/on_failure: - [Scoped Instructions](/build-guide/scoped-instructions): if: markers for deterministic branching - [Ordered Blocks](/build-guide/ordered-blocks): Strict sequence control - [Sub-skills](/build-guide/sub-skills): Composition via @skill. ### Orchestration - [Maestro](/maestro): The orchestrator - [Runtime Loop](/maestro/runtime-loop): Deterministic-first loop - [Guarantees](/maestro/guarantees): What the framework enforces - [Context](/maestro/context): How Maestro manages conversation context - [Skills & Routing](/maestro/skills): Skill selection and stacking ### Reference - [Project structure](/reference/project-structure): Every file and folder an agent recognises, and which are required - [Conditions](/reference/conditions): The memory expression language used by requires:, if:, complete_when:, next: - [skill.md](/reference/skill-md): Frontmatter properties and body format - [agent.yml](/reference/agent-yml): Identity, persona, rules, prompt tuning - [integrations.yml](/reference/integrations-yml): LLM provider, channels, voice ASR/TTS, Langfuse tracing - [memory.yml](/reference/memory-yml): Memory schema, types, visibility - [responses.yml](/reference/responses-yml): Response templates and interpolation - [Ordered block steps](/reference/ordered-block-steps): Step kinds, step fields, branching - [Tools](/reference/tools): Tool interface, ToolContext, built-in framework tools - [Execution Loop](/reference/execution-loop): The per-turn loop as a spec - [Constraint Table](/reference/constraint-table): Framework vs LLM at each control level - [System Prompt](/reference/system-prompt): Prompt assembly order and agent.yml overrides - [Prompt templates](/reference/prompt-templates): The assembled system prompt for each situation, verbatim ### More - [What's Next](/whats-next): Designed but not yet built - [Changelog](/changelog): Builder-facing changes per release ## Key facts for code generation ### Skills - The skill id is the folder name. The frontmatter `name:` is a display name. - `skill.md` is YAML frontmatter, then a markdown body. A skill needs prose, an ordered block, or both. - Prose branches with `if: ` on the first line of a paragraph. Write one `if:` paragraph per case, each stating its own condition. `else:` belongs in an ordered-block `next:` list. - Ordered-block ids are fence attributes: `:::ordered_block id=pick_card`. - `@block.` enters a block in the same skill; `@skill.` runs another skill and resumes the parent. Tools are named in plain prose. ### Conditions - Conditions are **strings**: `requires: "session.project.authenticated"`. - Memory references are three segments: `session..`. - Use a folded `>` scalar for a multi-line condition. ### Memory - Skill memory uses `schema:` with `public:` / `private:`, plus optional `access:`. Project memory (root `memory.yml`) is a flat map of entry name to attributes. - Types: `text`, `bool`, `int`, `float`, `list`, `json`, `categorical`, `any`. Enums use `enum_values:`. - `llm_settable: true` lets the LLM write an entry via `set_fields`. Collect-step targets are settable regardless. - Every key a tool writes must be declared in a `memory.yml`, or `rasa train` fails with `undeclared_memory_write`. - A tool's bare entry name resolves against its own skill's schema, then project memory. Another skill's `public` field is readable in conditions and reaches a tool as an argument. ### Tools - Import from `rasa.calm_v2.tools.decorator` (`tool`, `ToolContext`) and `rasa.calm_v2.tools.result` (`ToolResult`), not `rasa_sdk`. - A tool is `async`, takes `context: ToolContext = None`, and returns `ToolResult`. `@tool` takes `description=` as a keyword argument. - `context.send()` is a coroutine: `await context.send("…")`. - `tool_constraints` gate a tool at schema build and again at dispatch, including for an ordered-block `execute_tool:` step. Both fail closed. ### Responses - Each name in `responses.yml` maps to a list; the first entry is delivered. The registry is flat, so names are global. - Four things fire a response: a frontmatter `utter:` trigger (`on: activate` or `when:`), `on_success:` / `on_failure:` on a tool constraint, the `requires_confirmation:` utterances, and an ordered-block `action:` or `utterance:`. - Interpolation takes `{session..}` or the bare `{entry}` form. Prose in `skill.md` is not interpolated. ### Project config - `agent.yml` requires an `agent:` block with a non-empty `persona`. `rules`, `prompts`, `references`, `conversation`, and `session_config` are top-level siblings, not nested inside `agent:`. - `integrations.yml` requires a flat `llm:` block with `provider` plus `model` (or `deployment` for Azure), and a `channels:` block. `api_key_env` names an environment variable and works for every provider. - `llm:` and `channels:` are read from the project directory at runtime; `model_groups:` is read from the packaged snapshot, so changing embeddings needs a retrain. - Voice ASR and TTS are configured under a voice channel's `asr:` and `tts:` keys in `integrations.yml`. - Optional Langfuse tracing lives under `tracing:` in `integrations.yml`. Keys must use `${ENV_VAR}` references; they resolve at Langfuse configure time, not YAML load. Example projects ship the block commented until `LANGFUSE_PUBLIC_KEY` / `LANGFUSE_SECRET_KEY` are set.