Course Content
Agents & Tools Interview Prep
6 sections · 40 lessons
How does function calling work in LLM systems from start to finish?
What you need to know
- Declare — send
tools(name, description,input_schema) with the messages. - Decide — the model returns text, one or more
tool_useblocks, or both. - Execute — your code validates the arguments and runs the real function.
- Return — a user message with a
tool_resultfor everytool_useid. - Continue — call the model again; repeat until
stop_reasonisend_turn.
The request
1tools = [{2 "name": "search_flights",3 "description": "Search one-way flights. Use when the user wants flight options or fares.",4 "input_schema": {5 "type": "object",6 "properties": {7 "origin": {"type": "string", "description": "IATA code, e.g. DEL"},8 "destination": {"type": "string", "description": "IATA code, e.g. GOI"},9 "date": {"type": "string", "format": "date", "description": "YYYY-MM-DD"},10 "adults": {"type": "integer", "minimum": 1, "maximum": 9},11 },12 "required": ["origin", "destination", "date", "adults"],13 },14}]15messages = [{"role": "user", "content": "Flights Delhi to Goa on 20 Dec for 2 people?"}]16resp = llm.call(messages, tools) # our wrapper around client.messages.createThe model's reply
1{2 "role": "assistant",3 "stop_reason": "tool_use",4 "content": [5 {"type": "text", "text": "I'll search flights for that date."},6 {"type": "tool_use", "id": "toolu_01A",7 "name": "search_flights",8 "input": {"origin": "DEL", "destination": "GOI", "date": "2026-12-20", "adults": 2}}9 ]10}In the Anthropic API, input is already a parsed JSON object.
Sending the result back
1messages.append({"role": "assistant", "content": resp.content})2messages.append({"role": "user", "content": [{3 "type": "tool_result",4 "tool_use_id": "toolu_01A",5 "content": '[{"flight": "6E-2134", "dep": "06:10", "fare_inr": 5890}, ...]',6}]})7resp = llm.call(messages, tools) # now the model can answer with real faresRules that trip people up:
- The
tool_resultgoes in a user message, and it must directly follow the assistant message that contained thetool_use. - If the model made several calls in one turn (parallel tool use), return all results in one user message, one block per id.
- If a tool failed, still return a result:
{"type": "tool_result", "tool_use_id": "...", "is_error": true, "content": "Airline API timed out after 10 s; try again or search a different date."}. The model can then recover or explain.
The OpenAI equivalent
| Step | Anthropic Messages API | OpenAI Responses API | OpenAI Chat Completions |
|---|---|---|---|
| Declare | tools[].input_schema | tools[] with type: "function", parameters | tools[].function.parameters |
| Model's call | tool_use block, input object | function_call item, arguments JSON string | tool_calls[], function.arguments string |
| Signal | stop_reason: "tool_use" | output contains function_call items | finish_reason: "tool_calls" |
| Result | tool_result block with tool_use_id | function_call_output item with call_id | message with role: "tool", tool_call_id |
The concepts are identical; only field names differ. OpenAI returns arguments as a string, so you must json.loads them and handle a parse error.
A real-life example
A travel-booking assistant receives: "Find me a flight Delhi to Goa on 20 December and a hotel in Candolim for 3 nights, two adults."
Turn 1: the model returns two tool_use blocks in one reply — search_flights(...) and search_hotels(area="Candolim", check_in="2026-12-20", nights=3, adults=2). The harness runs both at the same time (1.8 s instead of 3.5 s) and returns both tool_result blocks in one message.
The hotel API responds with HTTP 503. The harness does not crash and does not silently drop it; it returns is_error: true with "Hotel search is temporarily unavailable." Turn 2: the model shows the three cheapest flights (from ₹5,890) and says hotel search failed and it will retry. It calls search_hotels again, which succeeds. Turn 3: a final answer with flights and four hotels, stop_reason: "end_turn".
Three model calls, three tool executions, and every step is visible in the logs.
Follow-up questions to expect
- "Where does the model's text before the tool call go?" — It is part of the assistant content. Keep it in history; you may show it to the user as a progress message.
- "What happens if you forget a
tool_resultfor one of the ids?" — The Anthropic API rejects the next request, because everytool_usemust be answered. - "Can a tool return an image or a document?" — Yes.
tool_resultcontent can be a list of blocks, including text and images.