ConceptAgents & Tool Use
Tool / Function Calling
At a glance
The model emits a structured call to a function you defined, and you run it.
- Who this is for
- Engineers and technical readers learning the terms used in AI systems.
- Topics
- Agents & Tool Use
- Concept
Tool calling, which OpenAI's docs call function calling, is what turns a text generator into something that can act: check a database, send an email, run a search, file a ticket. The key idea is that the model never executes anything itself. It reads the tools you have described, decides one is relevant, and emits a structured request naming the tool and its arguments. Your application runs the actual function and hands the result back, and the model continues with that new information in context. Every production AI agent is this one primitive repeated in a loop.
A tool is a typed contract#
You describe each tool to the model as three things: a name, a plain-language description, and a JSON Schema for its inputs. A get_weather tool might declare a required city string and an optional units enum of celsius or fahrenheit. Because the schema is machine-checkable, providers can enforce it at generation time: strict modes (OpenAI's strict, Anthropic's strict: true on a tool definition) use constrained decoding so the emitted arguments are guaranteed to validate. OpenAI's own guidance is to always enable strict mode, and it is easy to see why: the next stop for those arguments is real code, where a missing required field is an exception, not a typo.
The schema only says what is structurally valid, though. It cannot say when to call the tool, which parameter combinations make sense, or what conventions your API expects. That is the description's job, and the description is the part the model actually reasons over when choosing what to do. Write it the way you would explain the tool to a new hire: what it does, when to use it and when not to, what each parameter means, and what a good call looks like.
The round trip: request, execute, return#
A single tool call is a round trip with four beats. You ask "what is the weather in Pune?" The model cannot know that, but it sees get_weather in its toolset, so instead of prose it returns a response whose stop reason signals a tool call (Anthropic: tool_use, OpenAI: tool_calls), carrying the tool name and an arguments object with city set to Pune. Your code receives that JSON, validates it, dispatches to the real function, calls the weather API, and appends the output to the conversation as a tool result: 31C, clear skies. The model reads the result and writes the final sentence, or decides it needs another call first.
Two production details hide in that loop. First, failures should flow back as results too: return "error: unknown city, did you mean Pune, Maharashtra?" and the model will usually self-correct on the next turn, whereas a silent crash strands the conversation. Second, when several independent calls are needed, modern models emit them in parallel within a single turn: weather for three cities, or a customer's profile, orders, and open tickets at once. You execute them concurrently and return all the results together, so latency is the slowest call rather than the sum. Parallelize independent reads freely, keep dependent or destructive calls sequential, and note that providers expose a switch (parallel_tool_calls) to force one call at a time when you need it.
Authorize every call#
A tool call is untrusted input, full stop. The model can be steered by any text it reads, including text an attacker planted in a web page, document, or email, which is the heart of prompt injection: an assistant with an inbox tool can be instructed by an incoming email to forward confidential threads. So the discipline is to authorize and validate every single call in code. Check arguments against the schema and your business rules server-side. Enforce permissions per call using the end user's identity, never via a line in the system prompt. Scope credentials so the weather tool literally cannot reach billing. Gate irreversible actions, payments, deletions, outbound email, behind human approval. Log every call with its arguments and result. A proposed delete_account is a request, not permission.
Tool design quality is model performance#
Same model, same prompt, different toolset: wildly different reliability. Anthropic's engineering guidance, distilled from building MCP servers and measuring agents against them, comes down to a few rules. Build a few thoughtful tools that map to real workflows instead of auto-wrapping every API endpoint; one good search_orders beats five overlapping list and filter variants. Namespace related tools (asana_projects_search, asana_users_search) so the model can tell forty tools apart at a glance. Return high-signal, token-efficient results: human-readable names instead of raw UUIDs, pagination and filtering instead of a 50,000-token dump that drowns the context. Then treat the toolset as something you evaluate and iterate on: frequent invalid-parameter errors point to unclear schemas, and redundant call patterns point to bad pagination defaults. When toolsets grow into the hundreds, newer techniques such as on-demand tool search and programmatic tool calling, where the model writes code that orchestrates several tools and only the final output enters context, keep the context lean.
Where MCP and structured output fit#
Tool calling is a per-vendor API feature; the Model Context Protocol standardizes how tools are packaged, discovered, and connected. An MCP server exposes tools, with their schemas, descriptions, and auth, over a common protocol so any compatible client, whether Claude, ChatGPT, or your IDE, can use them without custom glue. Underneath, the model still emits the same function-call JSON; MCP does not replace tool calling, it distributes it. With OpenAI, Google, and Microsoft all adopting the protocol since 2025, it has become the de facto integration layer above the primitive this page describes.
Structured output is the same constrained-decoding machinery aimed at a different target. Tool calling guarantees a schema-valid request to act; structured output guarantees a schema-valid final answer. If you ever catch yourself defining a fake tool just to get clean JSON out of the model, structured output is the feature you actually wanted.
Practical takeaway#
Tool calling is the contract layer between a probabilistic model and your deterministic code: the model proposes, your code disposes. Write schemas strictly and descriptions like onboarding docs, return errors the model can act on, parallelize independent reads, and authorize every call as if a stranger typed it. Get those habits right at one tool and they scale unchanged to a full agent loop.