By Sagar Shankaran, Founder of CallSphere
A deep dive into structured output techniques for LLMs — from JSON mode and function calling to constrained decoding with Outlines and grammar-guided generation.
Key takeaways
Every production LLM application eventually hits the same wall: you need the model to return data in a specific format, and free-form text is not good enough. Whether you are extracting entities from documents, generating API parameters, or building agent tool calls, you need structured, parseable output — not prose.
The industry has evolved rapidly from fragile regex parsing to robust constrained generation. Here is the landscape in early 2026.
The simplest approach is asking the model to return JSON in the prompt and parsing the result.
flowchart LR
INPUT(["User intent"])
PARSE["Parse plus<br/>classify"]
PLAN["Plan and tool<br/>selection"]
AGENT["Agent loop<br/>LLM plus tools"]
GUARD{"Guardrails<br/>and policy"}
EXEC["Execute and<br/>verify result"]
OBS[("Trace and metrics")]
OUT(["Outcome plus<br/>next action"])
INPUT --> PARSE --> PLAN --> AGENT --> GUARD
GUARD -->|Pass| EXEC --> OUT
GUARD -->|Fail| AGENT
AGENT --> OBS
style AGENT fill:#4f46e5,stroke:#4338ca,color:#fff
style GUARD fill:#f59e0b,stroke:#d97706,color:#1f2937
style OBS fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
style OUT fill:#059669,stroke:#047857,color:#fff
prompt = """Extract the following fields as JSON:
- name (string)
- age (integer)
- email (string)
Input: "John Smith is 34 years old, reach him at john@example.com"
"""
This works surprisingly often but fails at the worst times. Models occasionally wrap JSON in markdown code fences, add trailing commas, or include explanatory text before the JSON. Post-processing with regex cleanup handles some cases but is inherently brittle.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
OpenAI's JSON mode (and equivalent features from Anthropic and Google) guarantees the output is valid JSON, but does not guarantee it matches your schema. You get syntactically valid JSON but still need to validate the structure.
response = client.chat.completions.create(
model="gpt-4o",
response_format={"type": "json_object"},
messages=[{"role": "user", "content": prompt}]
)
data = json.loads(response.choices[0].message.content)
# Still need to validate schema
OpenAI's Structured Outputs feature, launched in mid-2024 and now widely adopted, lets you pass a JSON Schema and guarantees the output conforms to it. Anthropic introduced similar tool-use-based structured output.
from pydantic import BaseModel
class PersonInfo(BaseModel):
name: str
age: int
email: str
response = client.beta.chat.completions.parse(
model="gpt-4o",
response_format=PersonInfo,
messages=[{"role": "user", "content": prompt}]
)
person = response.choices[0].message.parsed # Typed PersonInfo
This is now the recommended approach for most applications. The model is constrained at the API level to only produce tokens that satisfy the schema.
For self-hosted models, libraries like Outlines (by .txt) and Guidance (by Microsoft) implement constrained decoding at the token level. They modify the sampling process to mask out tokens that would violate the target schema or grammar.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
import outlines
model = outlines.models.transformers("mistralai/Mistral-7B-v0.3")
schema = '''{
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0},
"sentiment": {"enum": ["positive", "negative", "neutral"]}
},
"required": ["name", "age", "sentiment"]
}'''
generator = outlines.generate.json(model, schema)
result = generator("Analyze: Sarah (28) loved the product")
Outlines converts JSON Schema to a finite-state machine that guides token generation. Every generated token is guaranteed to be part of a valid output. There is no retry loop, no parsing failure — correctness is structural.
llama.cpp introduced GBNF (GGML BNF) grammars that let you define arbitrary output grammars beyond JSON. This is useful for generating SQL, code in specific languages, or custom DSLs.
Constrained decoding adds computational overhead. Benchmarks from the Outlines team show a 5-15 percent slowdown compared to unconstrained generation for complex schemas. For most applications this is negligible, but for latency-sensitive real-time systems, simpler constraints (like JSON mode) may be preferable.
The field is converging toward structured generation as a default rather than an afterthought. In 2026, shipping an LLM application without structured output is like shipping a REST API without request validation — technically possible, but asking for trouble.
Sources:

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
A clean before/after of agent architecture in 2026. The control loop moved from your framework code into the model's reasoning chain. What that looks like.
Google's May 2026 MCP 1.0 + A2A developers guide is the cleanest protocol picker we have seen. The takeaways, in plain English, with a CallSphere lens.
Workspace Studio puts a Gemini-powered AI agent builder inside Google Workspace. A walkthrough of what it does, who it is for, and where it fits in 2026.
Gemini 3.1 Ultra ships with a 2-million token context window and full text, image, audio, and video multimodality. What changes and how to build for it.
A 'did the agent answer correctly?' pass/fail hides broken tool calls, wasted tokens, and silent retries. Here is how to evaluate intermediate steps.
Run offline evals as a CI gate. GitHub Actions wiring, threshold gates, LangSmith Experiments, and how to block merges on agent regression — with real YAML.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco