Think Build Implement Repeat
London, UK +44 7367 067226
WhatsApp FOLLOW f in X
AI Apps

Structured Output From LLMs: Getting Data You Can Trust

Last updated:

Why prose is the wrong output for a business system

Most LLM projects start with a chat window and end with a database. Somewhere between the two, someone has to turn a paragraph of friendly text into fields a system can store, and that step is where a surprising number of projects stall.

A model that replies 'The invoice total appears to be around 1,240 pounds, including VAT' has answered the question. It has also given you nothing a finance system can post. You need total: 1240.00, currency: GBP, vat_included: true, every time, in the same shape, or a clear signal that it could not find them.

Structured output is the discipline of getting that shape reliably. It is the foundation under extraction, classification, routing and most agent tools, so it is worth getting right before anything clever is built on top.

The three levels of structured output

There are roughly three ways to ask a model for data, and they are not equally dependable.

ApproachHow it worksReliability
Ask nicely in the promptInstructions say 'reply in JSON with these keys'Fine in a demo, breaks on odd inputs: stray text, missing keys, markdown fences
JSON modeThe provider guarantees syntactically valid JSONAlways parses, but keys and types can still drift
Schema-constrained output or tool callingYou supply a JSON Schema and generation is constrained to itShape is guaranteed; values still need checking

Use the third level wherever your provider supports it, and most major APIs and several open-weight serving stacks now do. It removes an entire class of bugs, the ones where a parser fails at 2am because the model decided to add a helpful sentence before the opening brace.

Designing a schema the model can actually fill

A schema is a prompt in disguise. The field names, descriptions and types all steer what comes back, so write them for a reader who has never seen your business.

  • Name fields plainly. delivery_postcode beats dpc. The model reads the names.
  • Describe every field. One sentence on what belongs there and what to do if it is absent.
  • Use enums for categories. A fixed list of eight allowed values is far more reliable than free text you normalise later.
  • Make absence explicit. Allow null and say when to use it. Otherwise the model will fill the field with something plausible.
  • Keep nesting shallow. Deeply nested objects fail more often and are harder to validate.
  • Add a confidence or evidence field where it matters, such as the exact quote the value came from.

The evidence field is underrated. Asking for the source text alongside each value makes hallucinated values easier to catch, because you can check in code that the quoted text really appears in the document.

Validation: the part that makes it production-grade

A response that matches the schema can still be wrong. The date can be in the future, the total can disagree with the line items, the postcode can be nonsense. Schema validation checks shape. Business validation checks sense.

  1. Parse and validate against the schema with a library such as Pydantic or Zod
  2. Run business rules: totals add up, dates fall in a sensible range, IDs exist in your system
  3. Check evidence: quoted source text is actually present in the input
  4. On a fixable failure, retry once with the validation error included in the prompt
  5. On a second failure, or a low-confidence result, route to a human queue

The retry with the error message is cheap and effective. Telling the model 'line items sum to 1,180 but total says 1,240' fixes a good share of arithmetic slips. Beyond one retry, returns diminish quickly and you are mostly paying to be told the same wrong answer again.

What still goes wrong

Even with constrained decoding, there are failure modes worth designing for rather than discovering in production.

  • Confident invention. The field is required, the document does not contain it, so the model supplies something. Allowing null fixes most of this.
  • Enum squeezing. An input that fits none of the categories gets forced into the nearest one. Add an 'other' or 'unclear' value.
  • Truncation. Long outputs hit a token limit mid-object. Set limits generously and treat a cut-off response as a failure, not a partial success.
  • Silent format drift. Dates as 03/04 read the American way. Specify ISO formats in the schema description.
A schema guarantees the answer has the right shape. It says nothing about whether the answer is true.

A worked example: purchase orders by email

Take a wholesaler receiving around 250 purchase orders a week as PDF attachments from forty-odd customers, each with its own layout. Illustratively, a schema-constrained extraction with business checks might post most orders automatically and send the rest to a person, who now checks a pre-filled form instead of typing from scratch.

The checks do the heavy lifting. Customer account numbers are matched against the ERP, product codes against the catalogue, and quantities against sensible ranges for that customer. An order that passes all three is far safer to post than one that merely parsed. We cover the wider pipeline in our piece on turning documents into structured data.

How we approach it

When SpiderHunts builds extraction or classification into a system, the schema and the validation layer are written and tested before any prompt tuning happens. We collect a few hundred real examples, define what correct looks like for each field, and measure field-level accuracy rather than a single overall score, because 'the total is right 99% of the time but the delivery date only 80%' is the kind of finding that changes the design.

If this sits inside a wider integration, our AI integration work usually pairs it with a review queue and a feedback loop, so every human correction becomes a new test case. That loop matters more than the choice of model.

Frequently asked questions

What is the difference between JSON mode and structured outputs?

JSON mode guarantees the response is valid JSON but not that it has the keys or types you expect. Structured outputs constrain generation to a schema you supply, so required fields and types are enforced. Use schema-constrained output where it is available.

Do I still need validation if the model follows a schema?

Yes. The schema guarantees shape, not correctness. You still need business rules, range checks and lookups against your own systems to catch values that are well-formed but wrong.

Is tool calling the same as structured output?

Close enough for most purposes. A tool definition is a schema, and the arguments the model produces are structured output. Many teams use a single 'record_result' tool as a way of getting schema-constrained data.

Can small or open-weight models produce structured output reliably?

Often, yes, particularly with constrained decoding in the serving layer. Smaller models tend to be weaker on judgement inside the fields, so test accuracy per field on your own data before choosing.

Keep reading

Getting prose back when you need fields?

Send us a few real inputs and the fields you need out of them. We will tell you how reliably they can be extracted and what checks the pipeline needs around it.

Book a free 30-minute call Get a project estimate WhatsApp us

Related services

What we build for problems like this one

AI AgentsCustom Software DevelopmentSaaS Development