Tools & Tool Calling

A tool is an external capability the model can invoke: a database query, an API call, a search index, a calculator, a file write. Tool calling is the mechanism by which the model decides one is needed and requests it.

This is the step that turns a model from something that generates text into something that takes action, and it is where most of the engineering effort in an AI system actually goes.


The Loop

The model never executes anything itself. It returns a structured request, your code runs it, and the result goes back into the context for the next turn.

Three consequences follow from the model not being the executor:

  • Every permission check is yours. The model requests; your code decides whether that request is allowed, for this user, right now.
  • Every loop is yours to bound. Nothing stops a model requesting the same tool indefinitely except an iteration cap in your code.
  • Every tool result is untrusted context. A result containing text that looks like an instruction will be read as one. See Guardrails & Safety.

Defining a Tool

The model chooses tools based only on the name, description, and parameter schema you supply. A tool it uses incorrectly is nearly always a description problem, not a reasoning problem.

{
  "name": "get_invoice_status",
  "description": "Look up the current approval status of a single invoice by its invoice number. Use this when the user asks whether a specific invoice has been paid or approved. Does not search by supplier or date - use search_invoices for that.",
  "input_schema": {
    "type": "object",
    "properties": {
      "invoice_number": {
        "type": "string",
        "description": "The invoice number exactly as printed, for example INV-2026-0041"
      }
    },
    "required": ["invoice_number"]
  }
}

What makes that description work:

  • It says when to use the tool, not just what it does.
  • It says what the tool does not do, and names the alternative. Negative boundaries prevent the most common misfires.
  • Each parameter carries a format example, so the model does not guess at a convention.

Design Rules

RuleWhy
Few, well-named tools over many overlapping onesSelection accuracy falls as the tool list grows and descriptions start to overlap
One job per toolA tool that reads and writes cannot be granted read-only permission
Return structured, trimmed resultsRaw API payloads waste context and bury the useful field
Return errors as descriptions, not exceptions"Invoice not found" lets the model recover; a stack trace does not
Make writes idempotentA retried tool call must not post the transaction twice
Separate read tools from write tools by permissionRead tools can run automatically; write tools go behind an approval gate

Every registered tool also costs context on every call, since its definition sits in the prompt whether it is used or not. Twenty tools is a context and accuracy problem before it is a capability win. Route to a smaller tool subset per task instead.


Failure Modes

FailureCauseMitigation
Wrong tool selectedOverlapping or vague descriptionsSharpen descriptions, state the boundaries, reduce the tool count
Hallucinated argumentsNo format example, or no null pathAdd examples to the parameter schema, allow an explicit "unknown"
Loop that never terminatesTool keeps failing, model keeps retryingHard iteration cap, plus a token budget per request
Silent wrong answer after a tool errorError returned as an empty resultReturn an explicit error string the model can reason about
Destructive action taken unpromptedWrite tool available with no gateHuman-in-the-loop approval on write tools. See Autonomous AI

Where MCP Fits

Tool calling is the model-side mechanism. The Model Context Protocol is the integration standard around it: instead of writing bespoke glue for every system, a system exposes an MCP server and any MCP-aware client can use its tools.

The trade is standardisation against control. An MCP server built by someone else defines its own tool descriptions and return payloads, which are exactly the things that determine whether the model uses a tool correctly. Review them as you would review a dependency. See MCP for the protocol detail.


Key Takeaways

  • The model requests tool calls; your code executes them. Authorisation, validation, and loop bounds are all your responsibility.
  • Tool descriptions are the model's only selection signal. Say when to use it and what it does not cover.
  • Prefer few sharp tools to many overlapping ones. Every definition costs context on every call.
  • Return trimmed, structured results and descriptive errors, so the model can recover rather than guess.
  • Split read tools from write tools and gate the writes. Make every write idempotent.
  • Tool results are untrusted input, same as user text.