AI engineering path · How models behave · Topic 4 of 12

Structured outputs your code can trust

Not started

When a model's answer feeds into code (an extraction pipeline, a routing decision, a form pre-fill), you need a value with a known shape, not prose. There are three layers to getting one: ask for a precise structure, let the provider enforce it where it can, and validate the result yourself before anything else touches it.

Why it matters: As soon as code, not a person, reads the model's answer, "usually the right shape" becomes a production incident. Schemas and validation turn free text into a typed value or a clear error.

  1. 1Ask for a schema, not "JSON please"

    Describe the exact shape with a JSON Schema. Where the provider supports it, let it enforce the schema while generating.

  2. 2Validate anyway

    A schema guarantees shape, not truth. Check types, ranges, enums and business rules in your own code.

  3. 3Retry with the error

    When validation fails, send the specific error back and ask for a corrected answer, a bounded number of times.

  4. 4Fail closed

    After the last retry, return a typed failure your code handles, never a half-parsed guess.

1

How it works

The explanation, with examples you can run.

Layer 1: describe the shape

JSON Schema is the common language. Name every field, give it a type, list allowed values with enum, mark what is required, and forbid extra properties. Field descriptions are part of the prompt: the model reads them, so say what each field means and what to put there when the information is absent (often null rather than a made-up value).

{  "type": "object",  "properties": {    "category": { "type": "string", "enum": ["billing", "bug", "feature", "other"] },    "priority": { "type": "integer", "minimum": 1, "maximum": 4 },    "order_id": { "type": ["string", "null"], "description": "As written in the ticket, or null if none is given" }  },  "required": ["category", "priority", "order_id"],  "additionalProperties": false}

Layer 2: let the provider enforce it

Several APIs now accept a schema and use constrained decoding: at each step, tokens that would break the schema are not allowed, so the output always parses and fits. Older "JSON mode" options only promise valid JSON, not your fields. Tool or function calling is another route: the arguments of a tool call follow the tool's schema (see the next topic).

Check the provider's list of supported schema keywords; some features (certain formats, recursive schemas, very large enums) may be unsupported or limited. Also handle the cases that are not schema output at all: a refusal, or an answer cut off by the token limit.

Layer 3: validate and retry

Schema-valid is not the same as correct. Validate with a real validator (Zod, Pydantic, Ajv or similar), then apply business rules: totals add up, dates are plausible, ids exist in your database. When something fails and you have retries left, send the error back so the model can fix that specific problem.

The example uses a fake model that gets it wrong twice before producing a valid answer, so you can watch the loop.

⌘/Ctrl + Enter
OutputNot run yet

Press Run to see what your code prints, in order.

Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.

A few practical rules:

  • Keep the retry budget small (one or two). If an input fails repeatedly, the prompt or schema needs fixing, and the failure belongs in your evaluation set.
  • Do not regex JSON out of prose as a long-term solution. It hides problems that schema enforcement or a better prompt would remove.
  • Version your schemas with your prompts. Adding a required field is a breaking change for every stored example and test.
  • Keep schemas small and flat where you can. Deeply nested, many-field schemas are harder for models to fill correctly; split one big extraction into a few focused calls if accuracy suffers.
2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.A provider's structured output mode guarantees the response matches your schema. Which check do you still need?
  2. 2.Validation failed on the second retry as well. What should the code do?
  3. 3.What is the difference between a JSON mode and schema-enforced structured outputs?

0 of 3 right so far. Get all three to finish this topic.