A guardrail is just a Python function you hand to an agent or a tool. Motus calls it with the relevant value and interprets what the function returns. Reach for guardrails when you need to:Documentation Index
Fetch the complete documentation index at: https://docs.motus.lithosai.com/llms.txt
Use this file to discover all available pages before exploring further.
- Block risky actions before they run (a SQL tool rejecting
DROP, a shell tool refusingrm -rf). - Redact or mask sensitive data in arguments, tool outputs, or the agent’s final response (API keys, SSNs, PII).
- Normalize inputs the model is sloppy about (trim whitespace, coerce enums, canonicalize paths).
- Enforce policy on prompts or answers (refuse off-topic requests, require a score to fall in range, strip forbidden words).
- Gate with human approval for high-stakes tool calls before they execute.
- Return
None(or nothing): let the value through unchanged. - Return a value: rewrite what the guardrail is guarding. A
strreplaces a string input or output; adictpatches specific keys of a tool’s arguments or a structured output. - Raise an exception: block execution.
Guardrails declare only the parameters they care about. Motus inspects the function signature and passes the matching values automatically, so you never need to accept the full set of arguments.
Tool guardrails
Tool input guardrails run before a tool function executes. They declare only the parameters they want to inspect, in exactly the names and types the tool uses. Motus reads the function’s signature and passes just the matching arguments through.block_drop does not mention timeout or database, so Motus does not pass them in. The guardrail sees only query. This lets you write focused checks instead of accepting a long signature just to look at one field.
To modify an argument instead of blocking, return a dict with the keys you want to change. Motus merges it into the tool’s kwargs; omitted keys stay unchanged.
When a tool guardrail raises, Motus catches the exception and returns the message to the model as a
{"error": ...} tool result. The model sees the failure the same way it would see any other tool error, reads your exception message as feedback, and can reconsider what to try next. This is how an agent naturally learns to avoid a blocked action and route around it.Multiple guardrails chain sequentially
Passing several guardrails builds a pipeline where each one sees the previous one’s output. Order matters.post_comment(" Hello WORLD ") flows through normalize → lowercase → profanity check. The tool function itself receives text="hello world".
Agent guardrails
Attach guardrails to aReActAgent with input_guardrails (run on the user’s prompt before the agent starts) and output_guardrails (run on the final response before it returns to the caller).
agent, Motus passes in the running ReActAgent instance so the guardrail can read its configuration, inspect memory, or call helpers on it. Return a string to rewrite the prompt; raise InputGuardrailTripped to block the run.
Output guardrails receive the final response string. Return a string to replace it; raise OutputGuardrailTripped to block.
Structured output guardrails
When an agent usesresponse_format with a Pydantic model, the final result is a model instance rather than a string. Output guardrails in this mode declare the fields they want to inspect; Motus looks up each parameter name on the model and passes the value through. Declare score on your guardrail, and Motus passes the parsed result’s score field.
validate_score only declares score; other fields of AnalysisResult pass through untouched. Return a dict for a partial update, for example {"summary": "[redacted]"}.
Where to attach guardrails
| Level | How to attach | Parameters |
|---|---|---|
| Single tool | @tool(...) or tool(fn, ...) | input_guardrails, output_guardrails |
| Tool collection | @tools(...) on a class (see Tools) | input_guardrails, output_guardrails |
| Agent | ReActAgent(...) | input_guardrails, output_guardrails |
@tool with its own guardrails overrides the class-level @tools defaults for that one method. The lists do not merge.
Exceptions
All guardrail exceptions inherit fromGuardrailTripped. Import the one that matches what you are guarding:
| Exception | Where it applies |
|---|---|
InputGuardrailTripped | Agent input guardrails |
OutputGuardrailTripped | Agent output guardrails |
ToolInputGuardrailTripped | Tool input guardrails |
ToolOutputGuardrailTripped | Tool output guardrails |

