Article

Structured Output in Production: Using Constrained Decoding to Make LLMs Return Reliable JSON

A practical guide to structured output and constrained decoding for LLMs. Learn how to use JSON Schema, strict mode, post-hoc validation, retry strategies, and production monitoring to ensure stable, parseable structured results for information extraction, agent state management, and automated workflows, reducing online risks at the source.

The Problem

Many LLM applications appear stable during demos but expose a very specific issue in production: the model’s output is not a reliable data interface.

Typical failures include:

  • A required field is missing, causing backend deserialization to fail.
  • Enum values have inconsistent spelling, leading the state machine down the wrong branch.
  • Explanatory text is mixed in around the JSON, causing the parser to error out.
  • Tool call parameter structures are correct, but field semantics violate business constraints.
  • Repeated retries after parse failures increase latency, cost, and queue pressure.

The common past approach was to ask the model to “please return only JSON,” then use regex, string trimming, JSON repair, and retry logic on the backend. These methods solve some formatting issues, but they are fundamentally post-hoc fixes. As long as the model can drift toward an incorrect structure during sampling, the downstream can only remediate, not prevent the generation of erroneous tokens.

The value of Structured Outputs and Constrained Decoding is this: they elevate “output format” from a natural language prompt to a runtime constraint, limiting the model to legal structures during the generation phase. For scenarios like information extraction, ticket classification, automated tool parameter generation, agent intermediate state recording, and RAG citation output, this is a significant step from prompt engineering to an engineering contract.

Core Principles

Structured Outputs: Turning Output into a Contract

The core of Structured Outputs isn’t “making the model more obedient,” but explicitly declaring the output structure as an executable contract. This contract is typically expressed using JSON Schema, including:

  • Object field names
  • Field types
  • Required fields
  • Enum values
  • Array structures
  • Whether additional fields are allowed
  • Nested objects and constraints

JSON Schema itself is a declarative language for defining the structure and constraints of JSON data, and validators can check if instance data conforms to the schema. In an LLM application, it serves as the “model output interface definition.”

A simplified information extraction schema looks like this:

{
  "type": "object",
  "properties": {
    "customer_name": { "type": "string" },
    "urgency": { "type": "string", "enum": ["low", "medium", "high"] },
    "issue_summary": { "type": "string" },
    "needs_human_review": { "type": "boolean" }
  },
  "required": ["customer_name", "urgency", "issue_summary", "needs_human_review"],
  "additionalProperties": false
}

The purpose of this schema is not to hint to the model to “output this way if possible,” but to provide a structural boundary for the inference service, SDK, or decoder.

Constrained Decoding: Blocking Illegal Paths During Token Generation

During normal decoding, the model selects the next token from its vocabulary at each step. The model can output any token, so it might generate explanatory text before the JSON object is closed, or produce values outside the schema for an enum field.

Constrained Decoding calculates “which tokens are still legal” at each step based on the currently generated content and the target schema, then masks or down-weights illegal tokens. In other words, it doesn’t wait for the model to finish generating to validate; it continuously maintains a legal state during the generation process.

OpenAI, in their introduction to Structured Outputs, categorizes this as constrained sampling / constrained decoding: default sampling is unconstrained, and the model might choose a token that breaks the JSON at any point; constrained decoding dynamically determines which tokens are still valid in the current state.

Common implementation methods include:

MethodDescription
CFG-based dynamic constraintsUses a context-free grammar to limit the set of legal tokens at each step
FSM / Regex-based finite state constraintsCompiles the schema into a finite state machine, tracking the current legal state
JSON Schema → Grammar compilationCompiles JSON Schema into a grammar or token filtering rules
Inference framework grammar backendIntegrates structured output capabilities via xgrammar, guidance, Outlines, or SGLang

It Solves Format Reliability, Not Factual Correctness

It must be emphasized: constrained decoding improves structural compliance rates, but it does not guarantee business semantic correctness.

For example, if the schema requires urgency to be only low | medium | high, constrained decoding can prevent the model from outputting urgent or critical. However, it cannot guarantee the model will correctly classify a truly urgent ticket as high. This still requires:

  • High-quality prompts
  • Clear field descriptions
  • Post-hoc business rule validation
  • Offline evaluation sets
  • Online monitoring and human feedback

Therefore, structured output should be viewed as one layer of LLM application reliability engineering, not a complete quality system.

Engineering Implementation

1. Design the Schema Starting from the Interface Contract

Don’t treat the schema as an afterthought to the prompt. In production systems, it’s better to treat the schema as an interface contract, with the same care you’d give to designing a REST API DTO or a database table structure.

Follow these principles when designing:

PrincipleDescription
Use business-readable, stable English field namesAvoid ambiguous names like field1, result2
Write clear judgment criteria in field descriptionsDon’t just state the type; explain how to extract it from the context
Keep enum values few and stableDon’t hardcode temporary business states into model output
Define clear array length limitsAvoid unbounded output
Don’t make object hierarchies too deepDeep nesting increases constraint difficulty and latency
Disallow additional fields by defaultadditionalProperties: false
Ensure optional fields have clear meaningsPrevent the model from filling them in randomly

OpenAI’s documentation also recommends naming keys clearly and intuitively, creating clear title and description for important fields, and using evals to determine if the structure is suitable for the use case.

2. Distinguish Between “Output Structuring” and “Tool Calling”

Structured Outputs and Function Calling are often used interchangeably, but their engineering roles are different:

FeatureFunction CallingStructured Outputs
RoleModel decides whether to call a tool and generate argumentsModel directly returns a structured response
Typical ScenarioCalling a refund API, querying a databaseInformation extraction, RAG citations, Agent state recording
Control MethodFunction signature definitionJSON Schema definition

For example:

  • A smart customer service bot needs to call a refund API → Prefer tool calling.
  • Extracting ticket fields from an email → Use structured output.
  • An agent needs to record plan / action / observation at each step → Suitable for structured output.
  • A RAG answer needs to return answer, citations, confidence, missing_info → Use structured output.

3. Establish a Unified Response Pipeline at the Service Layer

In production, don’t scatter schema, parsing, and retry logic throughout your business code. A more robust approach is to encapsulate a Structured Output Gateway:

Business Request → Select Task Schema → Construct Prompt & Input Data
→ Call Model or Inference Framework Supporting Structured Outputs
→ JSON Schema Validation → Business Rule Validation
→ Failure Classification & Retry/Degradation → Record Observability Data → Return Standard Object

This gateway should uniformly handle:

  • Schema versioning
  • Model and provider differences
  • Strict mode configuration
  • Refusal and safety filtering
  • Timeouts and retries
  • Structural validation errors
  • Business validation errors
  • Log sanitization
  • Metric reporting

The benefit is: business teams only care about “which structure do I need,” and the platform team is responsible for “how to reliably get that structure.”

4. Use Post-hoc Validation to Supplement Semantic Reliability

Even if the model returns perfectly schema-compliant JSON, you should still perform business validation. For example:

from pydantic import BaseModel, Field, ValidationError
from typing import Literal

class TicketExtraction(BaseModel):
    customer_name: str = Field(min_length=1)
    urgency: Literal["low", "medium", "high"]
    issue_summary: str = Field(min_length=10, max_length=500)
    needs_human_review: bool

def validate_ticket(payload: dict) -> TicketExtraction:
    ticket = TicketExtraction.model_validate(payload)
    # Business rule: refund-related tickets need human review even if urgency is low
    if ticket.urgency == "low" and "refund" in ticket.issue_summary.lower():
        ticket.needs_human_review = True
    return ticket

The key layers here are:

  • Schema controls structure.
  • Pydantic / Zod / JSON Schema validator controls data types and boundaries.
  • Business rules control semantics.
  • Human review acts as a safety net for high-risk samples.

5. Establish Schema Versioning and Regression Testing

Many teams neglect schema version management. In reality, schema changes affect prompts, model output, downstream parsing, frontend display, and data analysis.

It’s recommended to at least retain the following metadata:

FieldDescription
schema_nameSchema name
schema_versionSchema version number
model_nameModel used
prompt_versionPrompt version
structured_output_modeStructured output mode
validation_resultValidation result
fallback_reasonReason for degradation
raw_response_hashHash of the raw response

Before deployment, run regression tests with a fixed sample set, focusing on:

  • Schema compliance rate
  • Field missing rate
  • Enum misclassification rate
  • Business rule failure rate
  • Average latency and P95 latency
  • Retry rate
  • Human review ratio

Applicable Scenarios

Information Extraction

Extracting structured fields from contracts, emails, customer service records, resumes, and expense reports is the most typical scenario for Structured Outputs. The schema can stabilize the output into business objects, reducing backend parsing costs.

Agent Intermediate State

Agents shouldn’t just output large blocks of natural language logs. A better approach is to have them return a structured state at each step, for example:

{
  "thought_summary": "need to verify invoice date",
  "next_action": "search_document",
  "tool_args": { "query": "invoice date" },
  "stop_reason": "need_more_evidence"
}

This makes it easier for the scheduler, auditing system, and replay tools to understand the agent’s behavior.

RAG Citation Output

RAG systems can require the model to return:

  • answer
  • citations
  • unsupported_claims
  • missing_information
  • confidence_level

This is much easier to integrate into quality evaluation and frontend display than asking the model to “please cite sources” within a natural language answer.

Automated Workflows

When LLM output drives downstream processes—such as approval classification, ticket routing, auto-tagging, or rule configuration generation—structured output reduces process interruptions caused by “unparseable output.”

Common Misconceptions

Misconception 1: Using Structured Outputs Means No Validation is Needed

False. Structured Outputs solve format and schema compliance issues, not factual correctness, business correctness, or security compliance. Post-hoc validation is still necessary in production.

Misconception 2: More Complex Schemas Are Better

Complex schemas increase the difficulty of constraint enforcement and can lead to higher latency and reduced model quality. Research like JSONSchemaBench also points out that real-world schema constraint types and complexity vary greatly, and structured generation needs to balance compliance, efficiency, and output quality.

Misconception 3: Put All Business Rules into the Schema

Schemas are suitable for expressing structure and basic constraints, not for carrying all business logic. Complex rules should be placed in the business validation layer, a rules engine, or a human review process.

Misconception 4: Field Names Don’t Matter

Field names themselves influence model understanding. OpenAI’s documentation recommends clear and intuitive key naming; recent research has also begun to focus on the instructional role of schema key wording in structured generation. Avoid ambiguous fields like field1, result2, or flag.

Pre-Deployment Checklist

Before going live, confirm each item:

  • Clearly identify which tasks require structured output and which only need natural language.
  • The schema is versioned and traceable to the prompt and model versions.
  • All required fields have clear descriptions.
  • Enum values are stable; temporary business states are not hardcoded into the model output.
  • additionalProperties is disabled by default.
  • Model refusal, safety filtering, and empty outputs are handled.
  • Structural failures, business validation failures, and downstream system failures are differentiated.
  • Maximum output tokens and timeouts are configured.
  • Offline evaluation samples are established.
  • Schema compliance rate, parse failure rate, retry rate, fallback rate, P95 latency, and cost are monitored.
  • High-risk outputs go through a human review or degradation process.
  • Schema changes require regression testing before release.

Does Constrained Decoding Increase Latency?

It can. Maintaining grammar state and calculating the set of legal tokens during decoding adds overhead, which is more noticeable with complex schemas. The actual impact depends on the model, inference framework, schema complexity, and concurrency pattern, and should be confirmed through load testing.

Can Open-Source Inference Frameworks Support Similar Capabilities?

Yes. The vLLM documentation indicates support for structured outputs using xgrammar or a guidance backend. The SGLang documentation shows it can constrain output using JSON schema, regular expressions, or EBNF. Outlines also provides cross-model structured generation capabilities.

References

  1. OpenAI API Docs - Structured model outputs
  2. OpenAI Blog - Introducing Structured Outputs in the API
  3. vLLM Docs - Structured Outputs
  4. SGLang Docs - Structured Outputs
  5. Outlines Docs
  6. JSON Schema - What is JSON Schema?
  7. Generating Structured Outputs from Language Models: Benchmark and Studies
  8. SGLang: Efficient Execution of Structured Language Model Programs

FAQ

What is the difference between Structured Outputs and JSON mode?
JSON mode primarily guarantees the output is valid JSON. Structured Outputs further require the output to adhere to a given JSON Schema, including required fields, enum values, and object structure.
Can constrained decoding guarantee business semantic correctness?
No. Constrained decoding mainly ensures format and structural compliance. Business facts, field meanings, and enum choices still require validation, evaluation, and human oversight.
Is retry on parse failure still needed in production?
Yes. Even with strict schemas, you must handle refusal, timeouts, provider limitations, unsupported schemas, field semantic errors, and downstream validation failures.
Can Structured Outputs completely replace prompt engineering?
No. It only makes the output structure a hard constraint. Field meanings, task objectives, judgment criteria, and context selection still rely on prompts and system design.