Skip to content
47% off: the complete course for $79 (reg. $149)Order now →
Agent Builder
Module 1Full course11 min read

Structured Outputs: Getting Data, Not Prose

Make models return reliable JSON that matches a schema, so agents can hand results to code, databases, and other agents without fragile parsing.

The moment an agent's output feeds into code, prose becomes a liability. Your script needs an invoice total, not "Sure! Based on the document, the total appears to be around €1,370." Your database needs a status of paid, not "Paid (I think)". Another agent needs a list of tasks, not three paragraphs describing them.

The obvious fix, asking the model to "reply in JSON", works most of the time. Most of the time is the problem: one malformed response in a thousand is enough to crash a pipeline at 3 a.m. Structured outputs solve this by constraining the model so its response is guaranteed to match a schema you define. In this lesson you'll learn why prompt-only JSON breaks, the three ways to get structured data from a model, how to make a schema-constrained call in TypeScript, how to design schemas a model fills well, and what a schema can't guarantee.

Why "reply in JSON" breaks

JSON (JavaScript Object Notation) is the curly-brace format most software uses to exchange data. If you ask a model for JSON in your prompt, you'll get something that looks right on the first ten tries. Run it ten thousand times and you'll meet every one of these:

FailureWhat you getWhat it breaks
Chatty preamble"Here's the JSON you asked for:" before the dataJSON.parse throws
Code fencesThe JSON wrapped in triple backticksJSON.parse throws
Invalid syntaxA trailing comma, an unescaped quote, a commentJSON.parse throws
Missing fieldNo total because the document didn't show one clearlyYour code reads undefined
Invented value"status": "partially paid" when you expected paid or unpaidYour logic takes the wrong branch
Wrong type"total": "€1,370.00" instead of the number 1370Arithmetic quietly fails
TruncationThe response stops halfway through an arrayInvalid JSON, or silently incomplete data

You can patch each one: strip code fences with a regular expression, retry on parse errors, coerce strings to numbers. Teams that do this end up with a growing pile of fragile cleanup code that still fails in new ways. The better approach is to stop the bad output from being generated at all.