Output Reliability: Format, Length, and Schema
The most common cause of silent production failures is not a bad prompt - it is a good prompt whose output cannot be parsed by the code that receives it.
The Format Contract
Every LLM call that feeds a downstream system has an implicit contract: the caller expects a specific output format, and the model is expected to honor it. When the contract is broken, the downstream system fails - and the failure is often silent. A JSON parse exception that is caught and swallowed returns an empty result. A regex that doesn’t match returns nothing. The user sees a broken feature; the logs show no error.
Making this contract explicit at every layer - in the prompt, in the API call, and in the parser - is the single most impactful improvement most teams can make to their production LLM reliability.
JSON Mode: What It Guarantees and What It Doesn’t
Both Anthropic (Claude) and OpenAI offer mechanisms for constrained structured output. These are different from simply asking the model to “return JSON” in the prompt.
Anthropic’s recommended approach for structured output is tool use: defining the expected output schema as a tool, then calling it. This forces the model’s output to conform to the schema at the API level, not just as a best-effort instruction. The official documentation explains the tool use approach at docs.anthropic.com/en/docs/build-with-claude/tool-use.
OpenAI provides a response_format: { type: "json_object" } parameter for JSON mode, and a response_format: { type: "json_schema", json_schema: {...} } option for schema-constrained output. The official documentation is at platform.openai.com/docs/guides/structured-outputs.
XML Tag Extraction: The More Reliable Alternative
For models that support tool use, tool use is the most reliable structured output mechanism. For cases where you want to extract specific fields from a primarily prose response, XML tag extraction is more reliable than asking the model to return a JSON object in its prose output.
The pattern: instruct the model to wrap specific output fields in named XML tags. Your parser then extracts content between those tags, regardless of what else appears in the output.
Analyze the customer message and provide: 1. A brief response to the customer 2. An internal classification for routing Format your output EXACTLY like this: <customer_response> [Your response to the customer here] </customer_response> <internal_classification> category: [billing|technical|account|other] priority: [low|medium|high] </internal_classification>
Why XML tags are reliable: the model treats XML-like tags as structural markers it must preserve. Extraction is simple string parsing - no JSON parsing, no exception handling for malformed output, no dependency on the model producing valid syntax. The content between the tags is always extractable even if the surrounding prose changes.
Length Control: max_tokens Is Not Optional
Prompt instructions to “keep responses under 200 words” reduce average length but do not enforce a hard limit. The model will occasionally produce longer output, especially on inputs it treats as complex. For any application where response length affects the user experience or downstream processing, use the API’s max_tokens parameter as a hard cap.
max_tokens is your safety net, not your trim target.Schema Enforcement Patterns
Even without model-level JSON schema enforcement, you can enforce schema compliance in the prompt and parser:
Return ONLY a JSON object matching this exact schema. Do not add any fields not listed.
Do not include null values - omit fields that don't apply.
Do not wrap the JSON in markdown code blocks.
{
"summary": string (max 100 chars),
"action_required": boolean,
"category": "billing" | "technical" | "account" | "other",
"escalate_to_human": boolean
}
And always validate in code:
const result = JSON.parse(llmOutput);
const required = ['summary', 'action_required', 'category', 'escalate_to_human'];
for (const field of required) {
if (!(field in result)) throw new ValidationError(`Missing field: ${field}`);
}
if (!['billing', 'technical', 'account', 'other'].includes(result.category)) {
throw new ValidationError(`Invalid category: ${result.category}`);
}
The Five Parser Failure Modes
When output parsing fails in production, it is almost always one of five patterns:
| Failure Mode | Example | Fix |
|---|---|---|
| Preamble wrapping | Output starts with “Here is the JSON:” | Add “no preamble” instruction; strip/extract in parser |
| Markdown code fencing | JSON wrapped in ```json ... ``` | Explicitly forbid; add strip-fence logic in parser |
| Schema drift | Model adds extra fields or renames fields | Use tool use / schema enforcement; validate after parse |
| String escaping errors | Unescaped quotes break JSON validity | Use tool use; if prompt-based, validate with try/catch |
| Max-tokens cutoff | JSON truncated mid-object | Set max_tokens high enough; detect truncation by checking for closing brace |
Ready to Go Deeper?
Live instructor-led courses from our partners. Affiliate disclosure.
AI & ML Courses - 30% Off
Live instructor-led AI, machine learning, data science, and cloud courses for working professionals. Use code Limited30 at checkout.
EdurekaDataCamp - AI & Data Science
Hands-on Python, machine learning, and AI courses with interactive exercises and real projects.
DataCampedX - Top AI Courses
University-level AI courses from MIT, Harvard, Stanford. Earn certificates that employers recognize.
edX