What is structured output?

Structured output is a model answer constrained to a schema the caller declared, so the result parses reliably instead of being read out of prose.

Every system that puts a model in the middle of a pipeline meets the same wall. The model answers in sentences. The next step needs a value.

Structured output is the fix. You declare the shape before you ask, and the answer arrives in it: a JSON object against a schema, one option from a named set, a number on a scale you defined, a function call with typed arguments. The caller owns the shape. The model fills it in.

What it solves: parsing prose is the oldest bug in AI plumbing

Without it, connecting a model to code means reading English with a regular expression. That works for a week. Then it stops, in three ways worth naming because each one is silent:

None of these raise an alert. Each produces a plausible run, a written record and a wrong outcome. A schema removes the category, because the shape of the answer is something you decided rather than something you have to discover.

Three ways it gets done, in increasing order of guarantee

ApproachWho enforces the shapeWhat still goes wrong
Ask in the prompt: "reply as JSON with these keys"Nobody. It is a requestProse around the block, a missing key, an invented key, a trailing comma
Constrain the decoder to a grammar or schema (JSON mode, function calling)The sampler, which can only emit tokens the grammar permitsNothing at the parse layer. A required field can still be filled with something plausible and empty
A model whose entire output surface is a schemaThe model has no free-text channel to leave the schema throughThe pick can be wrong, and with no no-match option it must pick something

The first row enforces nothing. The second is what most teams use on a general purpose model. The third is a different class of model: System One models such as TypeSafe's Jev, which TypeSafe put into public early access on 2026-09-15, answer only in declared types and, on the vendor's own account, cannot write a sentence at all. Their documentation describes the mechanism as returning "a full probability distribution over those options rather than inventing a value outside the schema". Vendor-published, and a description of the mechanism rather than a measurement.

The guarantee, and exactly where it stops

Here is the sentence the rest of this page hangs off: **a schema guarantees the interface, not the truth.**

Constrained decoding makes one class of failure impossible. The answer parses, the enum value is one of yours, the number is in range. It says nothing about whether the answer is right, and a model will return a perfectly valid, perfectly typed, completely wrong one.

That is worse than a parse error, not better, and the reason is downstream. A parse error is loud: it throws, you catch it, something logs, a person looks. A well formed wrong answer looks exactly like a right one to every line of code after it. It gets branched on, written into the record, and the ticket sits in the wrong queue until a customer complains.

So structured output does not reduce your risk. It moves it from the parser to the judgement, which is where it always was. Three things put a handle on what is left:

What a typed answer buys you when nobody is watching

What comes backWhat your code does with itWhat prose cost you
One option from a declared setBranch straight to the queue, owner or label it namesMatching wording that changes between model versions
A number on a declared scaleCompare against a threshold, sort the pile by itTurning "fairly urgent" into an order
A confidence between 0 and 1Hold anything under your floor for a personNothing. Prose has no uncertainty field to read
A declared no-match optionDetect the refusal and stop rather than guessSpotting "I am not sure" in forty phrasings
The same shape on every runA run receipt whose fields line up week over weekDiffing paragraphs

The last row is the quiet one. Unattended work is only reviewable if two runs can be compared, and comparing typed fields is arithmetic while comparing paragraphs is reading.

Always declare a no-match option

A closed set is the guarantee, and it is also the trap. The model cannot answer outside your options, so when the right answer is not in the list it returns the closest wrong one, with no signal that it did.

TypeSafe's documentation gives the rule for its Choice question: add an other or none of the above option when the list might not cover every input. That page also caps a Choice at 255 options. The advice generalises to any schema: every enum needs an escape hatch, and every escape hatch needs a branch in your code that does something other than carry on.

Where this touches a worker

A tool call is structured output. When a worker files a ticket or updates a CRM field, the model did not describe an API request in English. It emitted a named tool with typed arguments, validated against what that app exposes over MCP.

That is what makes permission enforceable. Because the intended action is a typed value before it is an action, the app firewall can check it against the level you granted, Off, Read or Write, and refuse it. Prose cannot be checked that way, which is why access control on the Connected apps page sits at the call, not in the instruction.

Most real jobs are both halves at once. [Support Inbox Triager](/kit/support-inbox-triager) classifies each thread by urgency and topic, which is typed, then drafts a reply, which is prose. [Inbox Triage Assistant](/kit/inbox-triage-assistant) sorts every thread into one of three buckets before it drafts anything. Kits ship the instruction, not the model, so you pick which model runs both halves at deploy time, from the per-model grades on each kit page, and tokens bill at provider list price with no markup.

Where a job is only the typed half, with no reply to write, WorkerKit runs it as a decision worker. A model with no free-text channel cannot drive an agent loop, so a decision worker has none: items fetched, each judged with typed questions, the routing done in code. Every read and every action goes through the same firewall door an agent worker uses. That is a different class of worker rather than a model option, which is why Jev is not in the deploy-time model picker.

When structured output is the wrong tool

FAQ

What is structured output in AI?

It is a model answer constrained to a shape the caller declared in advance: a JSON schema, a set of allowed options, a number on a defined scale, or a function call with typed arguments. Code can branch on the result directly instead of reading it out of a paragraph with string matching.

Does structured output stop hallucination?

No. It removes one kind, since a value outside the schema cannot be expressed, so an option you never declared cannot appear. It does nothing about the answer being wrong. A valid, typed, confidently returned answer can still be incorrect, and that is harder to catch than a parse error because nothing downstream notices.

Is JSON mode the same as structured output?

JSON mode is one implementation: the decoder is constrained so the output is always valid JSON, sometimes against a schema you supply. Structured output is the broader idea, covering function and tool calling, enum-only answers, and models whose entire answer surface is typed.

Are tool calls structured output?

Yes. A tool call is a named function with typed arguments, validated against the tool's declared schema before anything runs. That is why permissions can be enforced at all: the intended action exists as a checkable value before it becomes an action, so a firewall can compare it to the access level granted and refuse it.

What happens if the right answer is not one of the options?

The model returns the nearest option anyway, because the schema leaves it no other move, and nothing in the response marks it as a stretch. The fix is a no-match option such as other or none of the above in every closed set, with its own branch that stops and asks rather than proceeding.