Key takeaways
Structured outputs make an LLM return data that follows a defined schema instead of an unpredictable block of prose. They eliminate entire classes of formatting and parsing failures, but they do not prove that the values are true, authorized, or safe to use.
In this guide
The direct answer What structured outputs are Free text vs JSON vs schema Why they improve reliability What they do not solve How to design the schema TypeScript implementation The validation stack Function and tool calling Versioning contracts Evals and monitoring Production lessons Implementation roadmap FAQ Explore Agentic AI ↗The direct answer
Structured outputs turn a model response into a typed contract that software can reliably consume. Instead of asking the model to return JSON and hoping it follows the instructions, the application supplies a schema that defines required fields, allowed values, arrays, nested objects, and failure states.
That solves the format problem. It does not solve the truth problem. Production systems still need source validation, business rules, authorization, state checks, evaluations, and human review for high-impact decisions.
A contract between generation and software
Structured outputs are model responses constrained to a predefined data shape. The shape is commonly expressed through JSON Schema or a language-native schema library such as Zod in TypeScript or Pydantic in Python.
JSON Schema is a declarative language for defining the structure and constraints of JSON data. A schema can specify that a field must be a string, integer, array, nested object, enum, or null. It can also require properties and reject unexpected keys.
Defines the task, but not a machine-enforceable response contract.
JSON requestMay produce parseable JSON while omitting fields or changing types.
Structured outputConstrains keys, types, enums, arrays, and supported nested objects.
Validated resultAdds source checks, business rules, permissions, and workflow validation.
OpenAI’s current documentation distinguishes schema-constrained output from ordinary JSON mode: both produce JSON, but only Structured Outputs are designed to adhere to the supplied schema. The supported feature set is a subset of JSON Schema, so schemas must be tested against the exact API and model used.
Choose the right output mode
| Capability | Free text | JSON mode | Structured outputs |
|---|---|---|---|
| Machine parseable | Not reliably | Yes, as JSON | Yes, as schema-conforming JSON |
| Required keys | Prompt-dependent | Not guaranteed | Defined by the schema |
| Field types | Uncontrolled | May vary | Constrained to supported types |
| Enum values | Can drift | Can invent alternatives | Limited to approved values |
| Unexpected keys | Common | Possible | Can be rejected by the contract |
| Integration | Parsing and repair required | Schema validation still needed | Typed parsing with fewer formatting retries |
| Factual accuracy | Not guaranteed | Not guaranteed | Still not guaranteed |
| Best use | Human-facing drafts | Simple or legacy JSON needs | Extraction, agents, tools, and workflows |
A user-facing explanation can remain natural language while the application receives a separate object containing status, evidence, fields, proposed actions, and review requirements.
Remove ambiguity at the system boundary
The application no longer needs to strip markdown, repair commas, rename keys, or guess whether “three” is a string or number.
02A contract can include supported, uncertain, refused, blocked, and requires-review states instead of forcing false success.
03SDK helpers can map the response into typed objects, reducing hand-written parsing and making downstream code easier to test.
04Enums give the application a finite set of expected states rather than interpreting arbitrary prose.
05Tests can assert exact fields, statuses, citations, and actions instead of grading whether a paragraph looks right.
06Teams can track nulls, uncertain states, validation errors, retries, and schema versions across production traffic.
“The patient probably takes 10 mg daily.
The record ID may be PT-183.
You should update the medication list.”{
"status": "requires_review",
"patient_id": null,
"dose_mg": 10,
"frequency": "daily",
"proposed_action": "none"
}Shape is not truth
A schema can guarantee that a field is a string. It cannot guarantee that the string identifies a real patient. It can constrain a code to a pattern. It cannot prove that the code is supported by the source.
A valid-looking ID, code, date, or citation may still be invented.
A correct tool call can still target the wrong tenant or resource.
An ISO date may still violate scheduling, contract, or case rules.
The model may return generic values when evidence is missing.
A perfectly structured result can still be unsafe or outside scope.
Never execute a tool call merely because it passed schema validation. Treat model output as untrusted input until identity, authorization, resource state, business rules, duplicate risk, and approval requirements have been checked.
Good schemas encode operating decisions
A schema should reflect what the application needs to decide next. It should not mirror the entire database or become a dumping ground for every possible explanation.
Prefer requires_human_review over flag, and evidence_status over vague confidence.
Supported, uncertain, and blocked are easier to handle than arbitrary labels.
03Distinguish not found, not applicable, not authorized, and not requested.
04Explanations, extracted data, and proposed actions need different validation rules.
05Store source IDs, passage IDs, timestamps, or input spans for critical fields.
06Allow the model to say what is missing and what is required to continue.
A practical response contract
A current TypeScript pattern
The example below uses Zod to define the contract and the OpenAI Responses API parser to request a schema-conforming result. Select and evaluate the model for the workflow rather than copying a model name blindly.
import OpenAI from "openai";
import { zodTextFormat } from "openai/helpers/zod";
import { z } from "zod";
const openai = new OpenAI();
const IntakeResult = z.object({
status: z.enum(["supported", "uncertain", "blocked"]),
patientName: z.string().nullable(),
dateOfBirth: z.string().nullable(),
requestedService: z.string().nullable(),
missingFields: z.array(z.string()),
requiresHumanReview: z.boolean(),
});
const response = await openai.responses.parse({
model: "YOUR_EVALUATED_MODEL",
input: [
{
role: "system",
content: "Extract only stated information. Use null for missing values."
},
{ role: "user", content: transcript },
],
text: {
format: zodTextFormat(IntakeResult, "intake_result"),
},
});
const result = response.output_parsed;
if (!result) throw new Error("No parsed output was returned.");
The response is easier to consume, but the application still needs to validate it. Dates must be parsed. Patients must be matched through an approved identity workflow. Requested services must map to a valid catalog entry. Final actions must be authorized separately.
const validatedDate = result.dateOfBirth
? parseAndValidateDate(result.dateOfBirth)
: null;
const service = result.requestedService
? await serviceCatalog.findApproved(result.requestedService)
: null;
const canContinue =
result.status === "supported" &&
validatedDate !== null &&
service !== null &&
result.requiresHumanReview === false;
if (!canContinue) return routeToReviewQueue(result);
Current OpenAI documentation notes that Structured Outputs support much, but not all, of JSON Schema. In strict function-calling mode, object schemas require additionalProperties: false, and defined properties are treated as required, with nullable types used where needed.
Reliability begins after parsing
Required keys, types, enums, arrays, and unexpected properties.
02Dates, codes, identifiers, URLs, and format-specific fields.
03Does the patient, product, code, account, or source actually exist?
04Does the record belong to the tenant and match the current context?
05Do cited passages or input spans support the generated value?
06Is the user allowed to view, propose, approve, or execute the result?
Structured arguments make tools safer, not automatically safe
Function calling uses schemas to define the arguments a model can propose for a tool. Strict mode improves adherence to that schema. The application still decides whether the call is authorized and safe.
The model selects an approved tool and generates schema-conforming arguments.
→ 02The server checks identity, permission, resource state, and duplicate risk.
→ 03High-impact, clinical, financial, or irreversible actions stop for review.
→ 04The application uses controlled credentials and records the result.
Expose only tools required for the current workflow.
Least privilegeReturn and modify the minimum data necessary.
IdempotencyRetries must not create duplicate messages, tasks, or charges.
ConcurrencyRe-check state immediately before executing a write.
ApprovalSeparate proposed action from authorized action.
AuditRecord input, arguments, decision, executor, result, and schema version.
Schemas become production APIs
Once services, dashboards, queues, analytics jobs, and agent steps consume a structured output, the schema becomes an API contract. A small rename can break downstream systems or silently change decisions.
Add a nullable field or new branch while preserving existing meaning.
v1 → v2Rename or remove a field, change a type, or reinterpret an enum.
MigrationSupport old and new versions through adapters and feature flags.
EvidenceStore schema version with model, prompt, source index, validator, and release.
Measure more than parse success
Schema conformance is a baseline metric, not the success metric. A system can achieve perfect parse success while returning the wrong entity, unsupported values, excessive nulls, or unusable results.
Track refusal, truncation, incomplete output, and parse failures.
Field accuracyMeasure precision and recall for entities, codes, statuses, and relationships.
Evidence supportCheck whether source passages support critical generated fields.
Null behaviorEvaluate false fills, excessive nulls, and clarification quality.
Action validityTrack tool selection, argument validity, conflicts, and approval rate.
Operational valueMeasure correction time, completion, escalation, latency, cost, and adoption.
Structured outputs belong inside the wider guardrail stack. See AI Guardrails: How to Stop LLMs from Hallucinating in Production for prevention, validation, monitoring, and escalation.
What 16+ production agents taught us
A response can look right while downstream code accumulates regex, markdown stripping, fallback key names, and silent coercion.
Large contracts encourage vague fields and excess nulls. Narrow schemas produce cleaner generations and simpler validation.
A code can fit the expected string pattern while remaining nonexistent, unsupported, outdated, or wrong for the source.
Without an uncertainty state, the model is pressured to fill required fields even when evidence is missing.
Dashboards, queues, analytics, and agents can all depend on one field. Versioning prevents a prompt change from becoming an incident.
Staff need to see evidence, correct values, approve actions, and feed decisions back into evaluation.
Structured outputs do not make the model trustworthy. They make the model testable, and testability is where production reliability begins.
Trilops production engineering principleA practical adoption sequence
Start where parsing, missing fields, or manual review creates measurable cost.
Phase 02Identify what software must display, validate, store, route, or approve.
Phase 03Use clear names, bounded enums, evidence, and explicit uncertainty.
Phase 04Check existence, relationships, policies, state, sources, and permissions.
Phase 05Include normal, missing, contradictory, unexpected, and adversarial cases.
Phase 06Compare generated objects with real decisions before adding autonomy.
Phase 07Track field accuracy, null behavior, failures, corrections, latency, and cost.
Phase 08Reuse proven patterns without creating one universal, unmaintainable schema.
Turning an AI demo into a dependable workflow?
Trilops builds production agents with structured outputs, domain validation, controlled tools, evaluation, observability, and human review.
Frequently asked questions
No. JSON mode is intended to produce valid JSON, but it does not guarantee your exact field structure. Structured outputs constrain the result to a supported JSON Schema.
They prevent many formatting and invalid-enum failures, but not factual errors. A fabricated ID or unsupported code can still fit the schema.
No. Open-ended conversation and human-readable drafts can remain text. Use schemas when software must parse, validate, store, route, compare, or act on the response.
Represent it explicitly through nulls, missing-field arrays, uncertainty status, or a clarification request. Do not pressure the model to fabricate values.
Yes. Function arguments can be constrained by schemas, and strict mode improves adherence. The application must still authorize every proposed action.
As small as the downstream decision allows. Split broad workflows into multiple typed steps when one schema becomes difficult to explain or validate.
Treat them as API changes. Version the contract, run consumer and regression tests, use shadow traffic or adapters, monitor the rollout, and keep rollback available.
API capabilities and supported schema features change over time. Verify implementation details against the current documentation for the exact model, endpoint, SDK, and provider used by your application.
Trilops develops AI agents with schema-constrained outputs, domain validation, evidence tracking, controlled tools, evaluation, monitoring, and review workflows.