Tool use
Building agents · topic building-agents/tool-use
Tools give a model hands. This topic covers how a model requests a function call and receives the result, how to design a tool schema the model uses correctly, why connecting many models to many tools became a standards problem, how to handle tool errors, and when to let the model call several tools at once.
Concepts
- Function calling
- The mechanism by which a model asks for a tool to run. The developer sends tool definitions with the prompt; the model replies with a structured request naming a tool and its arguments instead of prose; the application executes it and sends the result back as a new message. The model never runs code itself; it emits a request the harness fulfils. glossary
- Tool schema design
- Writing the name, description and parameter schema that tell the model what a tool does and how to call it. The description is a prompt: it must say when to use the tool, what it returns and what it must not be used for. Few, well-named, strictly typed parameters with examples outperform flexible ones. Most tool misuse is a schema problem, not a model problem. glossary
- N x M integration problem
- With N agent applications and M tools or data sources, every pairing needs its own integration unless both sides speak a shared protocol. This is what made a standard for tool connections necessary: a tool exposed once through the protocol works with every compliant agent, turning N times M integrations into N plus M. glossary
- Error handling
- What happens when a tool fails, times out or returns something unexpected. The result should go back to the model as a clear, structured error it can reason about, not an exception that ends the run or an empty string it treats as success. Design tools to fail loudly and informatively, and decide in the harness how many retries a step gets. glossary
- Parallel calls
- Letting the model request several independent tool calls in one turn, which the harness executes concurrently and returns together. It cuts latency and round trips for read-heavy work such as fetching several files. Calls that depend on each other's results must stay sequential, and side-effecting tools need care because concurrent execution can reorder them. glossary
Links
- Builds on: What an agent is
- Leads to: The agent loop and harness
- Competencies drawing on it: Builds a tool-using agent loop
Lessons
- What a tool call looks like on the wire (explanation)
- Several tool calls in one turn (tutorial)
- When a tool fails (tutorial)
- Writing a tool schema the model uses correctly (tutorial)
Your reference
Each lesson above adds its takeaways and its example here once you finish it. Your reference lists every lesson you have finished.
What a tool call looks like on the wire
Unlocks when you finish What a tool call looks like on the wire.
Takeaways
- A tool definition sends the model a name, a description, and an input schema, and the function stays in your code.
- A model asks for a tool with a
tool_useblock that has an id, a name and an input, and astop_reasonoftool_use. Your loop sends the result back in ausermessage as atool_resultblock that quotes the id, and the whole history goes with it, because the model keeps no state. end_turnis where the fake model'sanswerkey went, and thestop_reasonfield is what a real loop branches on.- Every agent that calls every tool its own way costs N x M adapters, which is the problem a shared protocol solves.
Example
The first reply · open in the lesson
Run the first step, and compare what you see with the output below.
python3 wire.py first_replyPrints the lines below (verified in CI from site/examples/building-agents/how-a-model-calls-a-tool/first_reply.py)
{
"id": "msg_01",
"role": "assistant",
"stop_reason": "tool_use",
"content": [
{
"type": "text",
"text": "I'll check the weather in Lisbon."
},
{
"type": "tool_use",
"id": "toolu_01",
"name": "get_weather",
"input": {
"city": "Lisbon"
}
}
]
}Several tool calls in one turn
Unlocks when you finish Several tool calls in one turn.
Takeaways
- A model reply can hold several tool calls at once. The loop runs the list and returns one result per call, all in the next message, each under the id of the call it answers.
- Three independent lookups cost two rounds in a batch and four one at a time. The batch saves model round trips, and running the calls in a thread pool saves the wait for the tools too.
- A call whose argument is another call's result waits for the next round. Data flow decides what can share a reply.
- Running a batch at the same time is safe for calls that only read. For calls that write, run them in order, and keep the ids on every result either way.
Example
Predict the rounds, one call per turn · open in the lesson
What does this print?
show(run(QUESTION, model=model_one_at_a_time))Prints the lines below (verified in CI from site/examples/building-agents/parallel-tool-calls/one_at_a_time.py)
user: 'Compare the weather in Amsterdam, Lisbon and Oslo.' assistant: call_1 get_weather(city='Amsterdam') tool: call_1 '14°C, rain' assistant: call_2 get_weather(city='Lisbon') tool: call_2 '27°C, sun' assistant: call_3 get_weather(city='Oslo') tool: call_3 '6°C, snow' rounds: 4 stop: end_turn answer: Amsterdam: 14°C, rain. Lisbon: 27°C, sun. Oslo: 6°C, snow.
When a tool fails
Unlocks when you finish When a tool fails.
Takeaways
- A tool failure is a result, as data the model can read. An exception that escapes ends the run, and an empty result reads as success.
- In the Claude API the same thing is a
tool_resultblock withis_errorset totrueand the error text as its content. - The harness defines the retry policy and the stop reasons. It counts errors in a row and names the limit it reached.
- The tool says what went wrong, the harness decides how many tries a step gets, and the model decides what to tell the user.
Example
A tool that raises · open in the lesson
Ask for an account that doesn't exist.
run("What is the balance of account 4711?", tools=with_tool(lookup_account_raises))Prints: KeyError: '4711' (verified in CI from site/examples/building-agents/tool-errors/raises.py)
Writing a tool schema the model uses correctly
Unlocks when you finish Writing a tool schema the model uses correctly.
Takeaways
- The schema is the only prompt the model gets about a tool. A description says what the tool does, when to use it, when to use another tool, and what comes back.
- A parameter gets a type and a description, and an enum where the set is small, so the model has nothing to guess.
- Count the wrong calls before and after a change, because when the description doesn't say when to use a tool, the model uses it wrongly or not at all.
Example
Which tool gets called? · open in the lesson
Which tool name does this print?
print(choose_tool("Look up the customer with account id 4711", VAGUE_TOOLS))Prints: search_customers (verified in CI from site/examples/building-agents/tool-schemas/pick_vague.py)
Sources
AEC-03Tools, giving agents hands: function calling, schema design, the N x M problem, Agent Engineer Course (course)Academy claude-platform-101Claude Platform 101, Claude Academy (course)Academy building-with-the-claude-apiBuilding with the Claude API, Claude Academy (course)Academy introduction-to-model-context-protocolIntroduction to Model Context Protocol, Claude Academy (course)