Structured Output Prompting Best Practices
For years, developers integrating Large Language Models (LLMs) into production pipelines faced a frustrating problem: unpredictable formatting. You would write a massive system prompt begging the model to “Return ONLY valid JSON,” only for the model to prefix its response with “Sure! Here is the JSON you requested:“—instantly breaking your application’s JSON.parse() logic.
Today, this problem is solved through Structured Outputs (sometimes called Constrained Decoding or Tool Use). Instead of prompt engineering your way into formatting compliance, you enforce the schema at the API level.
In this guide, we cover the best practices for implementing Structured Outputs across different providers.
1. Stop Begging in the System Prompt
The biggest mistake developers make when migrating to Structured Outputs is leaving their old prompt-engineering hacks in the system prompt.
Bad Prompt:
“You are an entity extractor. You must extract the user’s name and age. Return a JSON object with the keys ‘name’ and ‘age’. Do not include markdown. Do not include any conversational text. If the age is missing, return null. Ensure all brackets are closed.”
Good Prompt:
“Extract the user’s name and age from the text.”
When you use native Structured Outputs, the API provider automatically parses your JSON schema and forces the model’s token sampling to strictly adhere to it. The model cannot output invalid JSON. Therefore, all the extra tokens spent describing the schema in natural language are wasted compute and latency.
2. Leverage Descriptions in the JSON Schema
While you shouldn’t describe the JSON format in the main prompt, you must heavily describe the semantic meaning of the fields inside the JSON Schema itself. The LLM reads the schema keys and descriptions to understand what data belongs there.
{
"name": "extract_user_info",
"description": "Extracts demographic data from the text.",
"parameters": {
"type": "object",
"properties": {
"full_name": {
"type": "string",
"description": "The user's full legal name. If only a first name is provided, leave this null."
},
"age": {
"type": "integer",
"description": "The user's age in years. Must be derived from their birth date if not explicitly stated."
}
},
"required": ["full_name", "age"]
}
}
Notice how the business logic (e.g., “leave this null if only a first name is provided”) is placed directly in the description field of the specific property. This creates an incredibly tight coupling between the instruction and the output target.
3. Handle ‘Thinking’ Tokens Separately
One major downside of Structured Outputs is that forcing the model directly into a JSON format prevents it from using “Chain of Thought” reasoning. If the first token it is forced to generate is {, it cannot write a paragraph of logical deduction first.
If your extraction task requires complex logic, you should add a reasoning field to the top of your JSON schema.
"properties": {
"reasoning_step": {
"type": "string",
"description": "Explain your step-by-step logic before extracting the data."
},
"final_answer": { ... }
}
Note: The order matters! In JSON Schema, order isn’t guaranteed, but most LLM providers process the schema top-down. Put the reasoning field first so the model generates it before committing to the final answer.
4. Use Enums for Categorization
If you are using an LLM for classification or tagging, do not rely on string types and hope the model chooses the right category. Use the JSON Schema enum type.
"category": {
"type": "string",
"enum": ["urgent", "routine", "spam"],
"description": "Categorize the support ticket."
}
When you use an enum, the constrained decoding engine (like Outlines in vLLM) mathematically masks the probabilities of all tokens except those that form the words “urgent”, “routine”, or “spam”. This guarantees 100% adherence to your expected categories.
Conclusion
Structured Outputs represent a shift from “prompt engineering” to “schema engineering.” By moving your instructions out of the natural language prompt and into tightly typed, heavily described JSON schemas, you can eliminate parsing errors and build highly deterministic AI data pipelines.


