Tools are the agent's hands
An AI agent decides *what to do* by choosing among tools you define and *how to do it* by filling in their JSON arguments. The quality of your tool schemas determines whether the agent acts correctly or flails. This is schema design as product design.
Principle 1: One tool, one job
Each tool should do one clear thing. A single manage_user tool with a mode field that switches between create/update/delete forces the model to reason about modes and makes arguments conditional. Split it:
{ "name": "create_user", "input_schema": { "type": "object", "properties": { "email": {"type":"string","format":"email"}, "name": {"type":"string"} }, "required": ["email"] } }
{ "name": "deactivate_user", "input_schema": { "type": "object", "properties": { "user_id": {"type":"string"} }, "required": ["user_id"] } }Focused tools are easier for the model to select and harder to misuse.
Principle 2: Descriptions are behavior
The description field is where you encode *when* and *when not* to use a tool. Treat it as policy:
{
"name": "send_email",
"description": "Send an email to a customer. Only use after the user explicitly approves the recipient and content. Never use for internal notes.",
"input_schema": { "type": "object", "properties": { "to": {"type":"string","format":"email"}, "subject": {"type":"string"}, "body": {"type":"string"} }, "required": ["to","subject","body"] }
}Principle 3: Constrain arguments tightly
- Enums for any closed set of options.
- Formats (
email,date,uri) andpatternfor IDs. - `minimum`/`maximum` for numbers,
maxItemsfor arrays. - `required` only for arguments the tool genuinely cannot run without.
The tighter the schema, the fewer invalid calls reach your code.
Principle 4: Return structured results
A tool's *output* should also be JSON the model can reason about. Return status plus data, not a sentence:
{ "ok": true, "user_id": "usr_91", "created_at": "2026-06-04T10:00:00Z" }Structured results let the agent chain steps: it can read user_id from one call and pass it to the next.
Principle 5: Validate before acting
Never execute a destructive tool on raw model arguments. Re-validate against the schema server-side, and add business checks (does this user exist? is the amount within limits?). The model proposes; your code disposes.
Principle 6: Keep the toolset small and routed
Accuracy degrades as the number of simultaneously available tools grows. Strategies:
- Expose only the tools relevant to the current task or step.
- Use a router/planner that selects a sub-agent with its own focused toolset.
- Group rarely-used tools behind a single "advanced" tool that takes an action name.
A reusable schema template
{
"name": "verb_noun",
"description": "What it does. When to use it. When NOT to use it.",
"input_schema": {
"type": "object",
"properties": {
"id": { "type": "string", "description": "..." },
"option": { "type": "string", "enum": ["a", "b"], "description": "..." }
},
"required": ["id"],
"additionalProperties": false
}
}