aiagentsjson-schemallm

Designing JSON Tool Schemas for AI Agents

·9 min read·AI & JSON

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:

json
{ "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:

json
{
  "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) and pattern for IDs.
  • `minimum`/`maximum` for numbers, maxItems for 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:

json
{ "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

json
{
  "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
  }
}

Frequently asked questions

There is no hard limit, but accuracy drops as the list grows past a handful of similar tools. Route or scope instead of exposing everything at once.

Where possible, yes. Agents retry. Idempotent tools (safe to call twice) prevent duplicate side effects.

Log the full JSON arguments the model produced, validate them against the schema, and tighten descriptions or types where the model went off track.

Try JSON Schema Generator

Generate JSON Schemas for your agent's tools from example inputs.