Tool use and function calling
Schemas, the tool-result loop, errors, code execution and computer use
Tools are how a model's words become actions. The function-calling interface is the same everywhere: you describe functions with JSON Schema, the model emits a structured call, you run it and feed the result back. Getting this loop right — including parallel calls, errors, budgets and good tool descriptions — is the single most reusable skill in agent engineering; every framework in 9.10 Frameworks and SDKs and 10.6 Multi-agent systems is a wrapper around it, and MCP (10.7 MCP and interoperability (plus Agent Skills and A2A)) is a protocol for sharing it.
You'll be able to
- Define tools with JSON Schema and explain why the description is a prompt
- Implement the complete tool-call/tool-result loop against the Anthropic or OpenAI API, including parallel calls and error returns
- Apply Anthropic's tool-design guidance: consolidation, namespacing, meaningful results, token efficiency
- Explain code execution and computer use as generalized tools and their cost/safety trade-offs
Key ideas
- A tool = name + description + JSON Schema; the model emits a structured call, your code executes it and returns a tool result with the matching id.
- Anthropic (tool_use / tool_result blocks, stop_reason) and OpenAI (tool_calls / role 'tool') implement the identical loop with different field names.
- Tool descriptions are prompts: say when to use and when not to, use enums and required fields, namespace tools, and consolidate near-duplicates.
Show 4 more key ideas
- Return high-signal, token-efficient results and send errors back as flagged tool results so the model can recover.
- Handle parallel calls (one result per id), cap steps/time/tokens, detect loops, and validate arguments before executing anything.
- Code execution turns many tool calls into one and keeps intermediate data out of the context; 'tools as code APIs' reported >98% token savings.
- Computer use is a universal but slow, costly and injection-exposed tool interface; prefer APIs or DOM access when available.
Suggested path through this lesson
Tools are the agent's hands
A tool is a function your code can run, described to the model as a name, a natural-language description and a JSON Schema for its inputs. When the model decides a tool would help, it does not call anything — it emits a structured tool-call block: the tool's name and a JSON object of arguments that conforms to the schema. Your harness validates the arguments, runs the function, and sends the output back as a tool-result message. The model then continues with that result in its context, and may call more tools or answer. This is function calling (OpenAI's term) or tool use (Anthropic's); both APIs implement the same shape:
| step | Anthropic Messages API | OpenAI API |
|---|---|---|
| declare tools | tools=[{name, description, input_schema}] |
tools=[{type: "function", function: {name, description, parameters}}] |
| model asks | content block type: "tool_use" with id, name, input; stop_reason == "tool_use" |
tool_calls on the assistant message with id, function.name, function.arguments (JSON string) |
| you answer | user message with type: "tool_result" blocks referencing tool_use_id |
messages with role: "tool" referencing tool_call_id |
Models are trained to produce these blocks reliably, which is what the 2023 free-text agents lacked (10.1 What is an agent? Loops, autonomy and workflows vs agents). Structured outputs (9.6 Generation side: context assembly, citations, structured outputs and tool calling) are the same machinery used to force a final answer into a schema.
The schema is a prompt
The model chooses tools by reading their descriptions, so the description is prompt engineering (8.4 Prompting as programming). Anthropic's Writing effective tools for agents (September 2025) distills what works:
- Fewer, better tools. Consolidate: one
search_customerswith filters beats five near-duplicates. Each tool competes for the model's attention. - Describe when to use and when not to, units and formats, defaults and examples. Name parameters unambiguously (
user_idnotid). Useenumandrequiredrather than prose rules. - Namespace related tools (
github_create_issue,github_list_prs) so the model can tell providers apart. - Return meaningful, high-signal context, not raw dumps: resolve ids to names, include what the model will need next, and offer a
response_formatof "concise" vs "detailed". - Be token-efficient: paginate, truncate with a note on how to get more, filter server-side.
- Evaluate tools with real tasks and iterate on descriptions — the post describes letting an agent rewrite tool descriptions based on transcripts of its own failures.
The loop in code
A complete minimal agent in Python with the Anthropic SDK shape (the OpenAI version differs only in field names):
import json
import anthropic
client = anthropic.Anthropic()
MODEL = "claude-sonnet-5-5" # use the current model id from the docs
TOOLS = [{
"name": "get_weather",
"description": "Current weather for a city. Use for any question about present conditions; "
"do NOT use for forecasts or historical data.",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name, e.g. 'Paris'"},
"units": {"type": "string", "enum": ["celsius", "fahrenheit"], "default": "celsius"}
},
"required": ["city"]
}
}]
def get_weather(city: str, units: str = "celsius") -> str:
# In real life: call an API. Return compact, model-friendly text or JSON.
return json.dumps({"city": city, "temperature": 21, "units": units, "sky": "clear"})
HANDLERS = {"get_weather": get_weather}
def run_agent(task: str, max_steps: int = 10) -> str:
messages = [{"role": "user", "content": task}]
for step in range(max_steps):
resp = client.messages.create(
model=MODEL, max_tokens=1024, tools=TOOLS,
system="You are a careful assistant. Use tools when they help; otherwise answer directly.",
messages=messages,
)
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason != "tool_use": # model is done
return "".join(b.text for b in resp.content if b.type == "text")
results = []
for block in resp.content: # may contain several tool_use blocks
if block.type != "tool_use":
continue
try:
output = HANDLERS[block.name](**block.input)
results.append({"type": "tool_result", "tool_use_id": block.id, "content": output})
except Exception as exc: # send errors back, don't crash
results.append({"type": "tool_result", "tool_use_id": block.id,
"content": f"Error: {type(exc).__name__}: {exc}", "is_error": True})
messages.append({"role": "user", "content": results})
return "Stopped: step budget exhausted."
print(run_agent("Is it warm in Lisbon right now?"))
Read the transcript it produces: user → assistant (tool_use) → user (tool_result) → assistant (text). Every agent framework you will meet is this loop with more bookkeeping.
Parallel calls, errors, budgets
- Parallel tool calls. A single assistant turn may contain several tool-call blocks (e.g. three searches). Execute them concurrently and return one result per id, in any order; a missing result breaks the conversation.
- Errors are information. Return failures as tool results (flagged as errors) so the model can retry with different arguments or choose another route. Make the error text actionable ("city not found; try the English name").
- Budgets and loop detection. Cap steps, wall-clock time and tokens; detect repeated identical calls; make tools idempotent where you can, because the model may retry.
- Validate before executing. Schema-check arguments; never pass model output to a shell unsanitized; check permissions per tool (10.10 Agent safety and security).
Code execution: the universal tool
Give the model a sandboxed interpreter and it can compose arbitrary logic — loops over data, math, parsing — in one step instead of twenty tool calls. Two 2025 refinements make this central:
- Tools as code APIs. Anthropic's Code execution with MCP (November 2025) presents MCP servers as importable functions in a filesystem; the agent writes code that calls several tools and only the final result enters the context. In their example this cut token usage by more than 98%, because intermediate data stays in the sandbox instead of round-tripping through the model.
- Tool search and programmatic tool calling (advanced tool use, November 2025): with hundreds of tools, load definitions on demand instead of stuffing them all into the prompt, and let the model orchestrate tool calls from code.
Intuition. Every tool result you send back is paid for twice: once as output of the tool and again as input on every later step. Doing work inside a tool (or a sandbox) rather than through the model is the biggest lever on agent cost.
Computer use as a tool interface
Computer use reduces a GUI to a tiny tool set: screenshot, click(x, y), type(text), key(name), scroll. It is universal — any software a human can use — but slow (one screenshot per action), expensive (images are many tokens) and exposed to whatever text appears on screen (10.10 Agent safety and security). Prefer an API or a DOM/accessibility-tree tool when one exists; reserve pixels for the long tail (10.8 Coding agents and computer use).
Where this shows up later
- The ReAct trace in 10.3 Reasoning and planning for agents is this loop with explicit reasoning between calls; the context you send each step is engineered in 10.4 Memory and context engineering.
- MCP (10.7 MCP and interoperability (plus Agent Skills and A2A)) standardizes how tool definitions and results cross process and network boundaries.
- Tool results are the main channel for prompt injection — the security model of 10.10 Agent safety and security starts here; production concerns (timeouts, idempotency, tracing) continue in 10.11 Building production agents.
Common pitfalls (4)
- Dumping raw API responses into tool results: the model drowns in irrelevant fields and you pay for them on every subsequent step.
- Crashing the loop on a tool exception instead of returning the error to the model, which usually can recover.
- Forgetting to answer every tool_use id when the model issues parallel calls — the API rejects the next request.
- Letting model-generated strings reach a shell, SQL engine or HTTP client without validation and permission checks.
Recap: all 7 key points
- A tool = name + description + JSON Schema; the model emits a structured call, your code executes it and returns a tool result with the matching id.
- Anthropic (tool_use / tool_result blocks, stop_reason) and OpenAI (tool_calls / role 'tool') implement the identical loop with different field names.
- Tool descriptions are prompts: say when to use and when not to, use enums and required fields, namespace tools, and consolidate near-duplicates.
- Return high-signal, token-efficient results and send errors back as flagged tool results so the model can recover.
- Handle parallel calls (one result per id), cap steps/time/tokens, detect loops, and validate arguments before executing anything.
- Code execution turns many tool calls into one and keeps intermediate data out of the context; 'tools as code APIs' reported >98% token savings.
- Computer use is a universal but slow, costly and injection-exposed tool interface; prefer APIs or DOM access when available.
Watch
The tool-use segment: how a model decides to call a calculator or browser and how results flow back.
Read
Try it live
Interactive demo
runs in your browserExercises
- Run the minimal agent and read the transcript
Copy the loop above, add a second tool (
convert_currencywith an enum of currencies) and ask a question that needs both tools. Print every message. Expected: the model issues two tool calls (possibly in one turn), you return two results with matching ids, and the final answer cites both. - Break it, then make it robust
Make
get_weatherraise for unknown cities and ask about a misspelled city. First observe the crash; then return the error as anis_errortool result. Expected: the model retries with a corrected name or asks you to clarify. Add a step budget and a repeated-call detector. - Rewrite a bad tool description
Write a deliberately vague tool (
lookup(id)) and a precise one (lookup_order(order_id: str)with when-to-use notes and an example). Run 10 varied requests against each. Expected: the precise version reduces wrong or missing calls; record the counts — this is your first tool eval. - Compute the cost of 'through' vs 'inside'
Simulate a task that needs 15 tool calls each returning 1,200 tokens. Compute the input tokens if results flow through the model (history re-sent each step) versus running the same 15 calls inside one code-execution tool that returns a 300-token summary. Expected: a 10–50× difference, in line with the code-execution-with-MCP write-up.
Quiz
Flashcards
These cards are now in your spaced-repetition queue. Review all due cards →