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
- Name: the function name (
check_balance) - Description: the
@tooldecorator argument - Inputs: extracted from the type hints
context: injected by the runtime, never visible to the LLM
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:Sharing state with the skill
Tools read and write memory throughcontext, so their
results are available to the rest of the skill:
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 raisesasyncio.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-roottools/ folder: add import_tools to the
frontmatter:
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: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
ForToolContext, ToolResult, invocation modes, tool resolution order, and the
built-in default tools, see the Tools reference.