devtools.codes

Writing a JSON Schema for structured output

Your tool input is processed locally in your browser and is not intentionally uploaded to our servers. Advertising and analytics providers may still process normal page, device, cookie and network information.

A schema for structured output does two jobs at once. It constrains what your code will accept, and it instructs the model on what to produce. Those are different jobs, and the second is the one people underinvest in.

Descriptions carry more weight than constraints. A model reads the schema as part of its instructions, and a property described as "one sentence, under twenty words, no trailing full stop" produces markedly better results than the same property with no description and a maxLength. The constraint catches the failure; the description prevents it.

Keep the structure shallow. Deeply nested objects are harder for models to produce reliably, and each level of nesting increases the chance of a malformed response. If you find yourself four levels deep, consider whether the task should be two calls rather than one.

Set additionalProperties to false unless you have a specific reason not to. Models add helpful-looking fields, and without this keyword they pass validation and reach your code. With it, they become an error you can see and act on.

Use enum wherever the answer belongs to a fixed set. It is the most effective single constraint available, because it removes the possibility of a plausible-but-wrong category rather than detecting one after the fact. List the allowed values in the prompt too, since belt and braces costs nothing here.

Be deliberate about what is required. Marking everything required guarantees intermittent failures whenever the model genuinely has nothing to put in a field. Marking nothing required means you handle undefined everywhere in your code. The right answer is usually a small required core and a larger optional remainder.

Finally, test the schema against a real response before you ship it. A schema that compiles is not the same as a schema that describes what the model actually returns.

More on writing a JSON Schema for structured output

How long should a property description be?

One line that states the format and any rule a reader could get wrong. "The publication date as an ISO 8601 date, no time component" earns its place; "the date" does not. Length is not the measure — specificity is. If a description could describe two different acceptable outputs, it needs another clause.

Should every property be required?

Only in strict modes that demand it, and even then use a nullable type for the genuinely optional ones. Otherwise mark a small core required and leave the rest optional. Requiring a field the model sometimes has nothing to put in guarantees intermittent failures that look like model unreliability but are a schema decision.

How deep can I nest objects?

Two or three levels is comfortable; beyond that reliability falls off noticeably. Each level adds structure the model has to hold together across a long generation, and the failure modes get harder to diagnose. If the shape genuinely needs four levels, consider whether it is really two tasks that should be two calls.

Does the schema affect cost?

Yes, in both directions. The schema is sent as part of the request on every call, so a large one with long descriptions adds input tokens each time. Against that, a schema that produces valid output first time avoids retries, and a retry costs far more than a few hundred tokens of description.

The tool behind this, and related guides