Writing Good Tool Definitions

The tool description is a prompt, and it is the one the model relies on most. Vague descriptions cause more agent failures than weak reasoning.

On this page

When an agent misbehaves, the instinct is to blame reasoning. Usually it is the tool definitions.

The model selects tools using their names, descriptions, and parameter schemas — and nothing else. It cannot read your implementation. The definition is the entire interface, and it is a prompt, subject to every rule that makes prompts work.

The description does the work

Compare:

"description": "Search the database"

against:

"description": "Search customer support tickets by keyword.
Returns up to 20 matching tickets with id, subject, status, and
created date. Searches ticket subject and body, not attachments.
Use for finding tickets about a topic. Do not use to look up a
specific ticket by ID — use get_ticket for that."

The second answers what it does, what it returns, what it does not cover, when to use it, and when to use something else. Every one of those prevents a specific mistake.

Four things a description should always cover:

What it does, precisely enough to distinguish it from neighbours.

What it returns, so the model can plan the next step.

When to use it, especially versus similar tools.

What it does not do. The most-skipped and most valuable part. Boundaries prevent misuse better than capabilities enable correct use.

Disambiguate aggressively

The most common failure is two tools whose descriptions overlap. search_tickets and find_issues — the model has no way to choose.

Fixes, in order of preference: merge them into one tool with a parameter; or make the descriptions explicitly contrastive, each naming the other and stating when to prefer it.

Names carry weight too. get_user_by_email beats lookup — the name alone communicates the parameter and the purpose.

Parameter design

Schema shape affects reliability, not just validity.

Enums over free strings. "status": {"enum": ["open","closed","pending"]} cannot produce an invalid status. A free-text status field frequently will.

Flat over nested. Deeply nested arguments fail more often. Flatten where you can.

Describe every parameter, including the obvious ones. Especially formats: "date": {"type": "string", "description": "ISO 8601, e.g. 2026-03-15"}. Without the example, expect every date format that exists.

Mark required fields accurately. Optional-but-actually-required is a reliable source of malformed calls.

Give uncertainty a destination. If the model may not know a value, provide a null option or an explicit UNKNOWN. Without one, it invents a value — the same commitment pressure that drives invention elsewhere.

Defaults over required parameters where sensible. Fewer decisions, fewer errors.

Keep the surface small

Tool selection accuracy degrades as the toolset grows, particularly with similar tools. Somewhere past a dozen, confusion becomes routine.

Three responses:

Consolidate. Five specific search tools usually want to be one with a parameter.

Route. Expose only the tools relevant to the current task, selected by your code before the model ever sees them.

Layer. A tool that returns a list of available sub-operations, then a second call to invoke one. Adds a round trip, keeps the top-level surface small.

Every tool definition also costs tokens on every single request. Twenty verbose definitions is real overhead per call.

Return values matter as much

Tool results enter the context window and stay there for the rest of the loop.

Return only useful fields. Dumping a full database row when three fields matter wastes budget every subsequent iteration.

Errors as data, not exceptions. {"error": "No ticket with that ID", "suggestion": "Use search_tickets to find it"} lets the model recover. A raised exception ends the run.

Include what enables the next step. If results are paginated, say so and return the cursor. If truncated, say that too — otherwise the model treats a partial list as complete.

Stable, self-describing shapes. The model reads these as text; labelled fields beat positional arrays.

Test the definitions directly

Definitions are testable independently of the agent, and this is worth doing.

Give the model a task and a toolset, and check which tool it picks and with what arguments — before executing anything. Wrong selections point straight at description problems.

Ambiguous tasks are the useful test cases. If two tools could plausibly apply, that is where descriptions need to be contrastive.

What to remember

  • The definition is the whole interface; the model sees nothing else.
  • Cover what it does, what it returns, when to use it, and what it does not do.
  • Overlapping descriptions are the top failure — merge or make them explicitly contrastive.
  • Enums, flat parameters, format examples, and a slot for uncertainty all raise reliability.
  • Keep the toolset small; consolidate, route, or layer.
  • Return compact results and errors as data so the loop can recover.

Next: Multi-Step Planning