Skip to main content
Tools are how a skill does things. Look up an account, lock a card, place an order. A tool is a decorated Python function. Drop it in the skill’s tools/ folder and it’s automatically available; the LLM reads its name, description, and inputs and decides when to call it.

Defining a tool

skills/check_balance/tools.py
The function signature is the schema:
  • Name: the function name (check_balance)
  • Description: the @tool decorator argument
  • Inputs: extracted from the type hints
  • context: injected by the runtime, never visible to the LLM
Tools are auto-discovered from the skill’s tools.py (or a tools/ folder, if you’d rather split them across files). No imports, no registration. The LLM sees the tool and calls it when the instructions call for it. The tool must be async, and the injected parameter must be named exactly context.

Using a tool in instructions

Reference a tool from the instructions body with its plain name:
The tool is already in the model’s schema whenever the skill is active: naming it in prose is guidance about when to use it, not a reference the compiler resolves.

Sharing state with the skill

Tools read and write memory through context, so their results are available to the rest of the skill:
Every key you write must be declared in the skill’s memory.yml or the project-root one. rasa train rejects an undeclared write. A tool can also send a message to the user directly, bypassing the LLM. It is a coroutine, so it must be awaited:

When a turn is cancelled

On voice, a user can start talking while your tool is still running. The runtime ends the turn and raises asyncio.CancelledError inside your tool at whatever await it is suspended on. Read-only tools can ignore this. For a tool that changes something, check context.is_cancelled before the irreversible step. See Cancellation.

Shared tools

Local tools need no declaration. To use a tool defined outside the skill folder, one in the agent-root tools/ folder: add import_tools to the frontmatter:
A shared tool that isn’t declared is not available to the skill at all.

Adding guarantees

By default the LLM decides when to call a tool, and it can get it wrong. Gate a tool behind a required value with tool constraints:
Now check_balance is invisible to the LLM until account_number is set. requires: is a string expression using the namespaced memory form: see Conditions.

Reference

For ToolContext, ToolResult, invocation modes, tool resolution order, and the built-in default tools, see the Tools reference.