Handbooks / RAG & AI Agents / Chapter 3

Tool Calling

7 pages · ~5 min✓ Reviewed

Builds on Chunking and Retrieval. Next up: Agent Loops and Memory.

RAG & AI AgentsPage 1

Tool Calling Mental Model

1. What a Tool Is

  • A tool = a function the model asks for by name with JSON arguments
  • The model never runs it; your code does
  • Definition has 3 parts: name, description, input JSON schema
  • The description is the prompt: it tells the model when to use the tool

2. The Round Trip

  1. Sendmessages + tools
  2. Tool callname, id, arguments
  3. Runyour code
  4. Returnresult by id
APIWants toolsFinal answer
Anthropicstop_reason: tool_useend_turn
OpenAIfinish_reason: tool_callsstop
Remember

A tool call comes instead of text. Send the result back, then repeat until a plain answer.

3. Interview Point

  • Who executes a call? Your app, never the model
  • What does the model output? A tool call: name, id, JSON arguments
  • How do you know it wants a tool? tool_use / tool_calls; end_turn / stop means final
RAG & AI AgentsPage 2

Defining Tools and JSON Schemas

1. Schema Basics

KeywordConstrains
type: objecttop level; fields go in properties
requiredarray of mandatory names
type / enumvalue kind / fixed choices
minimum / maximumnumber range
itemselement schema of an array
descriptionmeaning and format

2. Steering the Model

  • Description: what it does, when to use it, when not, each arg's format
  • Fixed choices → enum; keep params flat
  • additionalProperties: false asks for no extra keys; enforced only with strict tool use
json
{"name":"get_weather","input_schema":{"type":"object",
"properties":{"location":{"type":"string"},
"unit":{"enum":["celsius","fahrenheit"]}},
"required":["location"],
"additionalProperties":false}}

the model's call is below

output
{"location":"Pune","unit":"celsius"}

3. Mistakes and Interview Point

  • Vague names like do_action
  • Many overlapping tools
  • Optional fields marked required: model invents values
Schema is a hint

Always validate arguments server side.

  • Why validate? The schema only guides the model; check values server side
  • Wrong tool? Sharp descriptions, few distinct tools, narrow schemas
  • In a description? What, when, when not, argument formats
RAG & AI AgentsPage 3

The Tool Call Loop

1. The Loop

  1. Call modelmessages + tools
  2. Tool calls?none: final answer
  3. Run eachyour code
  4. Appendassistant + results, repeat
  • Match each result to its call by id (tool_use_id / tool_call_id)
  • Results must follow the assistant message that made the calls
  • Parallel calls: run them concurrently
  • Return all results together, each matched by id

2. Skeleton and tool_choice

python
for _ in range(max_turns):
    resp = model(messages, tools)
    messages.append(resp.message)
    if not resp.tool_calls: break
    for c in resp.tool_calls:
        messages.append(result(c.id, run(c)))
else: raise RuntimeError('turn cap hit')

for/else: the cap fails loudly, not silently

GoalAnthropicOpenAI
Model decidesautoauto
Must call some toolanyrequired
Must call this tooltool + namenamed function
No toolsnonenone

3. Common Mistakes

  • No turn cap: runaway loop and cost
  • Dropped assistant tool-call message
  • Result with a mismatched id
Always cap turns

A max_turns cap ends a runaway loop; handle the cap, never hang.

RAG & AI AgentsPage 4

Structured Outputs and Error Handling

1. Structured Output

MethodGuarantee
Prompt for JSONNone; may add prose or break syntax
Forced toolalways a tool call; args usually match, guaranteed only with strict mode
Schema-constrained outputValid JSON in your schema
  • Forced tool: input schema = your shape, set tool_choice
  • Still validate values; handle refusal and max_tokens truncation

2. Tool Errors

  1. Tool fails
  2. Flagged resultis_error true
  3. Model fixes call
  4. Retry cap, then give up
json
{"type":"tool_result","tool_use_id":"t1","is_error":true,
"content":"{\"error\":\"unit must be celsius or fahrenheit\"}"}

short, actionable message

3. Mistakes

  • Raising exceptions that crash the loop
  • Returning raw stack traces
  • Retrying forever
  • Retrying payments or emails without safeguards
  • No timeouts or permission checks on destructive tools
RAG & AI AgentsPage 5

MCP Basics

1. What MCP Is

  • MCP (Model Context Protocol): open standard linking AI apps to tools and data
  • A host app runs several MCP clients
  • Each client connects to one server
  • Messages use JSON-RPC 2.0

2. Primitives and Transports

  • Tools: model-invoked actions
  • Resources: readable data
  • Prompts: reusable templates
  • tools/list discovers tools
  • tools/call invokes one
TransportRunsServer
stdioLocal subprocessSame machine
Streamable HTTPOver the networkRemote

3. Compare and Avoid

MCPFunction calling
DiscoveryStandard tools/listHand-written
ReuseOne server, many appsCustom glue per app
SchemasJSON schemaSame JSON schema
  • Trusting third-party servers: prompt injection via tool output
  • Over-broad permissions
  • Too many tools bloat context
  • Logging to stdout on stdio corrupts protocol; use stderr
RAG & AI AgentsPage 6

Tool Calling Cheat Sheet

1. The Loop

  1. Model callmessages + tools
  2. Tool call?name, id, args
  3. Run in your codemodel never executes
  4. Result by idthen repeat
Always cap turns

Loop until a plain answer, but set max_turns. Results must match the call id.

2. Tool Definition

PartRule
Namespecific, not do_action
Descriptionwhat, when, when not
Schematypes, enum, required, additionalProperties: false
Servervalidate args anyway

3. Structured Output and Errors

TopicDo
Structuredschema-constrained output, or a forced tool
Still checkvalues, refusal, max_tokens truncation
Errorsflagged result (is_error), short actionable message
Retrieslimit them; never auto-retry payments or emails

4. Interview Point

  • Round trip? Send tools, get call, run it, return result by id, get answer
  • Function calling vs MCP? Same schemas; MCP standardizes discovery and calls
  • Safe agent? Cap turns, validate, least privilege, timeouts, confirm destructive
RAG & AI AgentsPage 7

Check yourself

A loop appends only the tool result, not the assistant message that made the call. What happens?
  • The API rejects it: the result has no matching call id.
  • Keep the assistant tool-call message first, then the results by id.
A send_email tool times out, so the loop retries it three times. What is the bug?
  • Sending is non-idempotent, so the user may get duplicates.
  • Use an idempotency key or ask for confirmation; auto-retry only safe tools.
A stdio MCP server runs print('ready') for debugging. Why does the client break?
  • Stdout carries the JSON-RPC messages, so stray text corrupts them.
  • Log to stderr instead.