Lesson 04 · Core Skills

Structured Output & Function Calling

The bridge from "the model writes text" to "the model is part of my program."

FDE skill · wire a model into real software without duct tape
🎧 Listen to this lesson · ~5 min · narrated audiobook edition

⏱ ~7 min read · 🎧 5 min listen · ✎ 3 quizzes · 🧪 ~30 min lab

In the Lesson 03 lab you hit a wall that every AI engineer hits in week one: the model's answer was text, and your program needed data. You resorted to fishing JSON out of the reply with a regex — and even your best prompt sometimes returned chatty extras or a malformed object. This lesson removes the duct tape. Two API features — structured outputs and function calling — turn the model from a text generator into a component you can program against.

The problem: prose isn't parseable

Software integration runs on contracts: your code expects a severity field that is exactly one of three strings, every single time. A next-token sampler makes no such promise. Prompting "return only JSON" plus few-shot examples gets you to mostly — but "mostly" at 10,000 calls a day means a daily pile of parse failures, and a 2% silent-corruption rate is worse than a crash at a customer site.

You could catch failures and retry — and production systems do — but retries cost latency and tokens, and they only paper over format errors, not schema drift like a severity of "URGENT!!". The right fix moves the contract from polite request to enforced guarantee.

Structured outputs: the schema becomes a guarantee

Modern APIs let you attach a JSON schema to the call, and the platform guarantees the reply conforms — valid JSON, right fields, right types, allowed values only.1 In practice you rarely write raw schemas: you define a Pydantic model (Python) or Zod schema (TypeScript) and the SDK converts it. Your parsing code stops being defensive; a whole failure class disappears.

The mechanism is worth knowing, because it's Lesson 01 again: constrained decoding. At each step of the next-token loop, tokens that would break the schema are masked out of the distribution before sampling. The model literally cannot emit an invalid character. Nothing about its "understanding" changed — the sampler's menu did.

Guarantee ≠ correctness Anthropic's structured-outputs docs are careful about the claim: the schema guarantees shape, not truth. A conforming reply can still put the wrong ticket in "severity": "low". Schema enforcement kills parse failures; only evals (Lesson 07) tell you about accuracy.

Function calling: the model asks your code to act

Structured output makes the model's answers machine-readable. Function calling (Anthropic calls it tool use) goes further: you describe functions your code offers — name, purpose, parameters as a JSON schema — and the model can respond with a request to call one: {"name": "lookup_order", "input": {"order_id": "A-1729"}}.2

Hold on to the key reframe: the model never executes anything. It emits a structured request — the API even sets stop_reason: "tool_use" and waits. Your code decides whether to run the function, runs it, and sends the result back as a new message. The model then continues with that result in context. Control, permissions, and side effects stay entirely in your code — a sentence you will repeat in every security review a customer runs on your design.

Same idea, many names "Function calling" (OpenAI), "tool use" (Anthropic), "tool calling" (almost everyone in conversation) — one mechanism. The model emits a structured call; your runtime executes it. Even the fancy acronyms layered on top later (agents, MCP) are packaging around this one move.

One craft point does most of the work in practice: tool definitions are prompts. The model chooses tools by reading their names and descriptions, so Anthropic's docs push you to write them like documentation for a new colleague — what it does, when to use it, what each parameter means, what it returns.2 Most "the model picked the wrong tool" bugs are description bugs.

What this unlocks

With these two features, the model becomes a programmable component: an extraction pipeline that feeds a database, a router that classifies and dispatches tickets, an assistant that can look up live order status instead of hallucinating it. And one question should be nagging you: if the model can request a tool call, and get the result, and request another… what happens when you put that in a loop? That's the next lesson — the agent loop.

Grounding, previewed Notice what the lookup_order pattern really does: instead of the model guessing an answer from frozen training data, your code fetches the true value and puts it in the context window. Fresh facts in, hallucination out. That principle — ground the model in real data — scales up into RAG in Lesson 06.

🧪 Lab: kill the regex, then hand the model a phone

The lab file is labs/0004-structured-extraction.py — same setup as before. Part 1 re-runs Lesson 03's ticket extraction, but with the schema enforced by the API instead of begged for in the prompt: the regex fishing is gone, the parse step cannot fail, and you'll see the checker go clean on format errors.

Part 2 defines a lookup_order tool, asks a question that requires it, and walks the wire format: the tool_use stop reason, the structured arguments the model produced, your code returning a result, and the model's final grounded answer. You will watch the moment of hand-off — model asks, your code acts — happen in plain sight.

🤖 Get your work reviewed

No chat here — this box replaces it. Copy the prompt into any AI assistant (Claude, ChatGPT, Gemini…), then paste your work after it.

You are a senior AI engineer reviewing my work: the output of my structured-output and function-calling lab (labs/0004-structured-extraction.py), plus my written answers to two design questions: (1) what schema enforcement does and does not guarantee, and (2) who executes a tool call and why that matters for security.

Grade each item as Strong / Adequate / Missing, with one sentence of evidence:
- My Part 1 output shows schema-conforming extractions with no parse/regex step, and I can explain constrained decoding in one sentence (invalid tokens are masked from the sampling distribution).
- I clearly distinguish shape guarantees from correctness — and name evals as the tool for the latter.
- My Part 2 trace shows the tool_use stop reason and structured arguments, and my explanation puts execution and permissions in MY code, not the model.
- My tool description would let a new colleague use the function correctly without asking questions.

Be skeptical — challenge my weakest explanation first. Then ask me 2–3 follow-up questions a customer's security engineer would ask. Finish with the single highest-leverage improvement.

My work follows below.

Check yourself — design the integration

Three integration decisions. Don't scroll up — reason from the mechanism. Wrong picks stay live.

Scenario A

A pipeline prompts for JSON and parses the reply. It works 98% of the time; the 2% failures are malformed JSON or extra prose. The fix with the strongest guarantee?

Scenario B

A customer's security team blocks your design: "We can't have an LLM running SQL against our database." What's the accurate correction?

Scenario C

An assistant with six tools keeps calling search_docs when it should call lookup_order, and passes a customer name where the tool expects an order ID. Most likely root cause?

Primary source — read this
The canonical reference for the request→execute→result cycle you just learned, including the wire format your lab prints. Pair it with the structured outputs page — together they're this whole lesson from the source.
Your one tangible win You can now design the seam between a model and real software: schema-enforced output where your code consumes answers, tool definitions where the model needs your code to act — and you can explain to a security reviewer, precisely, why the model never executes anything. That seam is where most customer AI projects live or die.
Questions? Schema not validating? Confused about what goes in a tool_result? Paste the relevant lesson section — or your lab trace — into any AI assistant (Claude, ChatGPT, Gemini…) and ask. For a structured review of your lab, use the box above.

Recommended learning

Hand-picked follow-ups on making models programmable. None are required — the primary source above comes first.

References

  1. Anthropic, Structured outputs documentation — JSON output format and strict tool use guarantees (verified July 2026).
  2. Anthropic, Tool use documentation — client vs. server tools, the tool_use/tool_result cycle, and tool-description guidance (verified July 2026).
  3. Chip Huyen, AI Engineering (O'Reilly, 2025) — structured outputs and tool use as the foundation of agentic applications.