JSON Schemas
The contract, in declarative form
A JSON Schema declaratively describes allowed output: types, required fields, enums, nested objects. Schemas are the contract LLMs validate against — and over-complex schemas break them.
What you will learn
- Write a JSON Schema for a model output
- Limit schema complexity that causes failures
- Version schemas as code
What is this?
A JSON Schema specifies the expected shape with types, required lists, enums, strings formats and nested structures. LLM platforms accept schemas as constraints (structured output) or guidance (prompt-injected). The pragmatic rule: the simpler the schema, the higher the compliance — enormous required-field trees are where models stumble.
Why do you need it?
- The schema is the single source of truth for every consumer.
- Enums and types catch drift before it reaches the UI or DB.
- Validators and SDKs consume the same schema — one definition, many uses.
- Schema complexity directly trades against model compliance rate.
Mental model
A customs declaration form
JSON Schema
The form says 'name: text, quantity: integer, value: number, country: from a list'. The traveller (model) fills it; a bad form either gets rejected at the window or — if the window accepts anything — chaos downstream. Clear fields, few of them, guarantee a fast pass.
How it works
- Define top-level type 'object' with properties, required, additionalProperties.
- Use type, enum, format, minItems/uniqueItems for tight control.
- Nest objects/arrays modestly; avoid deep recursion.
- Platforms map schemas to constrained decoding (structured mode).
- Validators everywhere: server-side parse, UI type guards, test fixtures.
One schema, many enforcers.
Examples
A compact schema
const schema = { type: "object", properties: { intent: { type: "string", enum: ["refund", "complaint", "question"] }, confidence: { type: "number", minimum: 0, maximum: 1 }, entities: { type: "array", items: { type: "string" }, maxItems: 10, }, }, required: ["intent", "confidence", "entities"], additionalProperties: false,};Three fields, tight enums, bounded arrays — model-compliant and validator-happy.
In production
- Platform structured mode consumes this exact object.
- API responses are typed from the same schema via codegen.
- Eval fixtures assert output conforms to a schema version.
Best practices
- Minimize required fields; give notable fields sensible defaults.
- Bound enumerations (intent lists), arrays, and string lengths.
- Set additionalProperties: false where strictness matters.
- Version schemas in the repo with consumers and fixtures together.
Common mistakes
- Deeply nested required-object graphs the model never completes.
- Enums that don't cover realistic model outputs (validation purgatory).
- Schemas drifting from the validator and SDK (three truths).
Common issues
Model violates the enumEnum too narrow or prompt not showing options
Widen enum or inject the allowed values into the prompt.
Deep required nesting always partialGenerative step can't plan the whole tree
Split into separate calls or flatten objects.
Debugging tips
- Compliance falls with complexity → flatten, drop rarely-needed requireds.
- Enum values mismatch real outputs → log actual values, extend the enum.
- Schema drift between files → derive TS types and validators from one schema.
Interview checkpoint
Quick quiz
A JSON Schema declares…
Deeper and larger schemas always give better output.