Part 5 of 7 · 2 min read
Choosing what to expose
Start read-only, return compact results, and how tool calling differs from structured output.
- Start with read-only tools. Add tools that change things only with limits and confirmation (Level 10).
- Return compact, useful results: only the fields the model needs, with units. Every result is re-sent on every later step (Level 1, module 6).
- Make tools idempotent where possible (safe to run twice), because retries happen (module 5).
- Show the model a short error, but log the full details (stack trace, inputs) for yourself.
Tool calling and structured output both ask the model for JSON that matches a schema. The purpose differs:
| Structured output (module 3) | Tool calling | |
|---|---|---|
| Purpose | The answer is the data | The data is a request to act |
| Who uses the result | Your code | A function, then the model sees the outcome |
| Loop | Usually one call (plus retries) | Repeats until there are no more calls |
Providers often use similar machinery for both, but the details differ by provider and model, so validate in both cases.
What you will use daily at work
| Practice | What it looks like |
|---|---|
| Official SDK tool helpers | The SDK turns a typed function into a tool description and may run the loop for you. |
| Schemas from types | Pydantic (Python) or Zod (TypeScript) models produce the JSON Schema, so code and description cannot drift apart. |
| Per-call logging | Each tool call logs name, validated arguments, duration, success and result size. |
| Allow-lists and limits | File, network and money tools enforce their own limits, whatever the model asked. |
Draft: confirm tool-description fields, parallel-call behaviour and schema limits against your provider's current documentation before relying on them.
Interview angle
Answer in your head first, then open it.
How does tool calling work?
The model gets tool descriptions with schemas. It replies with a tool name and JSON arguments. Your code validates and runs it, returns the result as a tool message, and the model then answers or asks for another call.
Does the model execute the function?
No. Your code does, which is why you can validate, limit and log.
What if the model calls a tool that does not exist, or with bad arguments?
Return a clear error as the tool result and let it retry. Never crash and never guess.
What stops an agent from looping forever?
Caps on steps, tokens and cost, plus detection of repeated identical calls.
Why not just eval a calculator expression?
Model text is untrusted. Parse it and allow only what you need, and bound the time and size too.
Function calling versus structured output?
Structured output returns data for your code. Function calling returns a request to act, in a loop.