Skip to content
AI-Native PM
7 min · 0 of 8 in The Model Layer

Get output you can build on

Your fridge feature works in testing, then a real user tries it and the screen shows a paragraph instead of a list. The model replied, "Sure! It looks like you have milk, a dozen eggs, and some spinach in there," which reads perfectly to a person and breaks your code, because your code was written to display a list of items and got a friendly sentence instead. Nothing is wrong with the model. You asked a person's question and tried to use the answer as data.

When your code consumes a model's output, you cannot rely on free-flowing text; you constrain the reply to a fixed structure, called a schema, so your code can read it the same way every time.

Free text versus structured outputThe model can return the same answer two ways. As free text, it reads well to a person but your code has to guess where each item is, which is brittle. As JSON matched to a schema, your code reads the list of items directly, which is reliable. Caption: free text is for people, structured output is for your code.TWO WAYS TO GET THE ANSWER BACKTHEMODELFREE TEXT“Sure! You’ve got milk, adozen eggs, and some spinach.”YOUR CODEhas to guess whereeach item isJSON, TO A SCHEMA{ "items": ["milk", "eggs", "spinach"] }YOUR CODEreads the listdirectlyFree text is for people; structured output is for your code.

Free text is for people, structured data is for code

A person reading "you've got milk and eggs" understands it instantly. Code does not, and the usual workaround, hunting through the sentence for the words you expect, fails the first time the model phrases the same answer differently, which it will. The reliable approach is to stop asking for prose and start asking for data: a list, or an object with named fields, the exact structure your code already expects from any other API or database row.

Ask for a structure, and have it enforced

You describe the structure you need as a small schema, naming each field and its type. For the fridge list, that is one field, items, holding a list of strings:

{
  "items": ["milk", "eggs", "spinach"]
}

You do not have to hope the model matches that structure. The major providers offer a feature, OpenAI's Structured Outputs, Anthropic's structured outputs, and Google's structured output, that takes your schema and constrains the model so the reply always fits it. With it on, the output is guaranteed to parse: the same field names, the same types, no stray "Sure!" in front. This is the single biggest jump in reliability you can make in this chapter, and it is one setting on the call.

A valid structure is not a correct value

Here is the trap that catches people who just turned on structured output and relaxed. The feature guarantees the structure of the answer, never the truth of it. A reply of { "items": ["caviar"] } is perfectly valid JSON, and perfectly wrong if there is no caviar in the photo. The model produces a well-formed answer with the same confidence whether the contents are right or invented.

So you validate the values, not just the structure. After the output parses, your code checks the things your feature actually depends on: that a price is a positive number, that a date is real, that a category is one of the ones you allow, that a count is not absurd. Structured output stops your code from crashing on a sentence; value checks stop it from acting on a confident wrong answer.

When you do not need structure

Structure is for output your code consumes. When the model's reply goes straight to a person, a chat answer, a draft email, a summary they will read and edit, free text is the right call and a schema only gets in the way. The test is simple: if code reads the output, give it a structure and check the values; if a person reads it, let it be prose.

Try it now

No setup: Take one output your feature would use and write down the exact JSON your code needs: the field names and their types. In a provider console, ask for that JSON on a real input and confirm it parses cleanly. Then write an input where a correct structure could still carry a wrong value, run it, and see for yourself that "valid" and "true" are not the same thing.

With your tools: Ask Claude Code to convert your feature's response to a defined schema using your provider's structured-output setting, then add a check that the values make sense, rejecting or retrying anything out of range, before the result is used. If your tools are not set up yet, The Setup Clinic gets you there in one sitting. In Codex or Cursor the move is the same: define the schema, turn on structured output, and add a value check after it parses.

Chapter Summary

  • A model reply that reads well to a person can still be useless to your code, because code needs a predictable structure, not a friendly sentence.
  • When your code consumes the output, ask for data in a fixed structure, a schema, instead of free text.
  • The major providers can enforce your schema so the reply always parses, which is the biggest reliability gain in this chapter and is a single setting on the call.
  • A guaranteed structure is not a guaranteed value: the model can return schema-perfect JSON that is simply wrong.
  • After the output parses, check the values your feature depends on, like ranges, real dates, and allowed options, before acting on them.
  • When the output goes straight to a person to read, free text is fine; reach for structure only when code consumes the result.
  • Next up, Give the model the facts it wasn't trained on makes the model's answers right, not just well-formed.

Sources

  • OpenAI Structured Outputs, Anthropic structured outputs, and Google Gemini structured output documentation, 2026.
Marks this chapter complete on your course map. Reaching the end does this for you.