Introduction
Structured Output Prompting is a prompting technique used to make an AI model return information in a fixed and predictable structure.
Instead of receiving a normal paragraph, the user can ask the model to return data as:
- JSON objects
- Arrays
- Tables
- XML documents
- YAML documents
- CSV records
- Key-value pairs
- Schema-based objects
Structured responses are useful when AI output must be read by software, stored in a database, validated, displayed in a user interface, or passed to another API.
For example, a normal AI response may look like this:
Java is a programming language created for platform-independent application development. It is commonly used for backend systems.
A structured version of the same information may look like this:
{
"language": "Java",
"type": "Programming language",
"main_use": "Backend application development",
"platform_independent": true
}
The structured version is easier for an application to read because every value has a clear field name.
Structured Output Prompting does not only tell the model what information to generate. It also defines how that information must be organized.
Learning Objectives
After completing this chapter, you will understand:
- What structured outputs are
- Why structured responses are useful
- How to define fields and data types
- How to mark fields as required or optional
- How to create nested objects
- How to define arrays and lists
- How to restrict values using enumerations
- How to handle null and missing values
- How schema validation works
- How JSON Schema defines a data structure
- How to handle schema violations
- How to retry invalid responses
- How to create reliable structured output prompts
What Are Structured Outputs?
Structured outputs are AI responses organized according to a predefined format.
A structured output contains named fields, fixed data types, defined relationships, and clear rules.
For example, consider a prompt asking an AI model to analyze a job candidate.
An unstructured response may look like this:
The candidate has five years of Java experience and strong Spring Boot knowledge. The candidate appears suitable for a senior backend developer role.
A structured response may look like this:
{
"candidate_name": "Rahul Patil",
"experience_years": 5,
"primary_skill": "Java",
"frameworks": ["Spring Boot", "Hibernate"],
"recommended_role": "Senior Backend Developer",
"suitable": true
}
The structured response contains predictable fields that can be used directly by an application.
Main Characteristics of Structured Outputs
- Every data item has a defined field name.
- Each field can have a defined data type.
- The response follows a fixed format.
- Required values can be enforced.
- Allowed values can be restricted.
- Nested data can be represented.
- Lists of similar items can be returned.
- The response can be validated automatically.
Structured Output Prompt
Analyze the candidate information.
Return the result as one JSON object.
Include candidate_name as a string.
Include experience_years as an integer.
Include primary_skill as a string.
Include frameworks as an array of strings.
Include recommended_role as a string.
Include suitable as a boolean.
Do not include text before or after the JSON object.
Candidate information: Rahul has five years of Java experience and works with Spring Boot and Hibernate.
Expected Output
{
"candidate_name": "Rahul",
"experience_years": 5,
"primary_skill": "Java",
"frameworks": [
"Spring Boot",
"Hibernate"
],
"recommended_role": "Senior Backend Developer",
"suitable": true
}
Important Point
A response is not considered properly structured only because it uses JSON syntax. It must also follow the required field names, data types, allowed values, and validation rules.
Benefits of Structured Responses
Structured responses provide consistency, reliability, and easier integration with software systems.
Predictable Output
A structured prompt defines exactly which fields should appear.
Without structure, the model may use different wording each time.
For example, one response may use:
"experience": 5
Another response may use:
"years_of_experience": 5
A structured prompt can force the model to use one consistent field:
"experience_years": 5
Easy Application Integration
Applications can directly read structured fields.
For example:
candidate["experience_years"]
This is easier than searching a paragraph to find the candidate’s experience.
Easier Validation
A schema validator can check:
- Whether required fields exist
- Whether values use the correct data type
- Whether values belong to an allowed list
- Whether nested objects follow the correct structure
- Whether extra fields are present
Better Database Storage
Structured output can be mapped directly to database columns.
Example database mapping:
| Structured Field | Database Column |
|---|---|
| candidate_name | candidate_name |
| experience_years | experience_years |
| primary_skill | primary_skill |
| suitable | suitable |
Better User Interface Rendering
A frontend application can display different fields in different components.
For example:
- candidate_name in a heading
- experience_years in a badge
- frameworks in a list
- suitable as a status indicator
Reliable Automation
Structured responses are useful in automated workflows such as:
- Resume screening
- Invoice extraction
- Product categorization
- Customer support routing
- Sentiment analysis
- Code review
- Document processing
- Report generation
- API data preparation
Reduced Parsing Errors
Unstructured text requires complex text processing. Structured data can be processed using standard JSON, XML, YAML, or CSV parsers.
Clearer Prompt Requirements
A structured output definition makes the expected result clear to both the model and the developer.
Defining Fields
A field is a named data element in a structured response.
Each field represents one specific piece of information.
For example:
{
"product_name": "Laptop",
"price": 65000,
"available": true
}
This object contains three fields:
- product_name
- price
- available
Good Field Naming Rules
Field names should be:
- Clear
- Specific
- Consistent
- Easy for software to process
- Free from unnecessary spaces
- Written using one naming style
Common Naming Styles
Snake case:
customer_name
Camel case:
customerName
Pascal case:
CustomerName
Kebab case:
customer-name
Snake case and camel case are commonly used for JSON fields.
Avoid Unclear Field Names
Weak field name:
info
Better field name:
product_description
Weak field name:
value
Better field name:
monthly_revenue
Weak field name:
result
Better field name:
eligibility_status
Define the Meaning of Each Field
A good prompt explains what each field represents.
Extract invoice information.
Return invoice_number as the unique invoice identifier.
Return invoice_date as the date printed on the invoice.
Return supplier_name as the company that issued the invoice.
Return total_amount as the final amount after taxes.
Return currency as the three-letter currency code.
Expected Output
{
"invoice_number": "INV-2026-1042",
"invoice_date": "2026-08-06",
"supplier_name": "ABC Technologies",
"total_amount": 24500,
"currency": "INR"
}
Avoid Duplicate Meaning
Do not define multiple fields that represent the same information unless they serve different purposes.
Poor design:
{
"price": 1000,
"product_price": 1000,
"final_price": 1000
}
Better design:
{
"base_price": 1000,
"discount_amount": 100,
"final_price": 900
}
Field Definition Template
Return the result as a JSON object.
Include field_name as a data_type.
Use field_name to represent a clear meaning.
Do not rename the field.
Do not add undefined fields.
Defining Data Types
A data type defines what kind of value a field can contain.
Correct data types are important because applications treat text, numbers, booleans, arrays, and objects differently.
Common Structured Data Types
| Data Type | Purpose | Example |
|---|---|---|
| String | Text value | "Java" |
| Integer | Whole number | 10 |
| Number | Integer or decimal | 89.5 |
| Boolean | True or false | true |
| Object | Group of related fields | {"city": "Pune"} |
| Array | Ordered list of values | ["Java", "Python"] |
| Null | No available value | null |
String
A string represents text.
{
"employee_name": "Amit"
}
Prompt instruction:
Return employee_name as a string.
Integer
An integer represents a whole number.
{
"experience_years": 6
}
Prompt instruction:
Return experience_years as an integer.
Do not include words such as years in the value.
Incorrect:
{
"experience_years": "6 years"
}
Correct:
{
"experience_years": 6
}
Number
A number can contain an integer or decimal value.
{
"rating": 4.5
}
Prompt instruction:
Return rating as a number between 0 and 5.
Boolean
A boolean contains only true or false.
{
"eligible": true
}
Prompt instruction:
Return eligible as a boolean.
Use true or false only.
Do not use yes or no.
Incorrect:
{
"eligible": "Yes"
}
Correct:
{
"eligible": true
}
Object
An object contains a group of related fields.
{
"address": {
"city": "Pune",
"state": "Maharashtra",
"country": "India"
}
}
Array
An array contains multiple values.
{
"skills": [
"Java",
"Spring Boot",
"MySQL"
]
}
Null
Null represents an unavailable, unknown, or non-applicable value.
{
"middle_name": null
}
Data Type Prompt Example
Analyze the employee record.
Return employee_name as a string.
Return age as an integer.
Return salary as a number.
Return permanent_employee as a boolean.
Return skills as an array of strings.
Return address as an object.
Return resignation_date as a string or null.
Do not convert numbers into strings.
Do not use yes or no for boolean values.
Required and Optional Fields
A required field must appear in every valid response.
An optional field may be included only when the information is available or relevant.
Required Fields
Required fields usually represent information that the application must have.
Example:
{
"customer_id": "C1001",
"customer_name": "Sneha",
"email": "sneha@example.com"
}
If customer_id is required, the response is invalid when customer_id is missing.
Optional Fields
Optional fields represent information that may not always exist.
Example:
{
"customer_id": "C1001",
"customer_name": "Sneha",
"email": "sneha@example.com",
"secondary_phone": null
}
The secondary_phone field may be optional.
Prompt Example
Extract customer information.
customer_id is required.
customer_name is required.
email is required.
secondary_phone is optional.
company_name is optional.
Include all required fields in every response.
Use null for an optional field when the field is included but its value is unavailable.
Do not create information that is not present in the source.
Required Field Strategies
There are two common ways to handle unavailable required data.
Strategy One: Use Null
{
"customer_id": null,
"customer_name": "Sneha",
"email": "sneha@example.com"
}
This keeps the response structure stable.
Strategy Two: Return an Error Object
{
"success": false,
"error_code": "MISSING_REQUIRED_FIELD",
"missing_fields": [
"customer_id"
]
}
This is useful when the application cannot continue without the field.
Required and Optional Field Design
Use required fields when:
- The application cannot work without the value
- The field identifies the record
- The field controls important logic
- The field is always expected in the input
Use optional fields when:
- The value may not exist
- The value is not required for processing
- The value depends on a specific condition
- The value is only useful in some cases
Important Point
Do not mark every field as required. Too many required fields can cause unnecessary failures when source data is incomplete.
Nested Objects
A nested object is an object stored inside another object.
Nested objects are used to group related fields.
Flat Structure
{
"employee_name": "Ravi",
"address_city": "Pune",
"address_state": "Maharashtra",
"address_country": "India"
}
Nested Structure
{
"employee_name": "Ravi",
"address": {
"city": "Pune",
"state": "Maharashtra",
"country": "India"
}
}
The nested structure is easier to understand because all address-related fields are grouped under address.
When to Use Nested Objects
Use nested objects when:
- Multiple fields belong to one logical entity
- The response contains related sub-sections
- The same group may be reused
- The data has parent-child relationships
- The application expects hierarchical data
Example: Product Information
{
"product_id": "P1001",
"product_name": "Wireless Keyboard",
"pricing": {
"base_price": 1500,
"discount": 200,
"final_price": 1300,
"currency": "INR"
},
"inventory": {
"in_stock": true,
"available_quantity": 24,
"warehouse": "Pune"
}
}
Nested Object Prompt
Analyze the product information.
Return product_id as a string.
Return product_name as a string.
Return pricing as an object.
Inside pricing, include base_price as a number.
Inside pricing, include discount as a number.
Inside pricing, include final_price as a number.
Inside pricing, include currency as a string.
Return inventory as an object.
Inside inventory, include in_stock as a boolean.
Inside inventory, include available_quantity as an integer.
Inside inventory, include warehouse as a string.
Do not move nested fields to the root object.
Do not add fields that are not defined.
Deep Nesting
Deep nesting means placing objects inside several levels of other objects.
Example:
{
"company": {
"department": {
"team": {
"team_lead": "Anita"
}
}
}
}
Deep nesting should be used carefully because it can make data harder to read and process.
Best Practice
Use enough nesting to group related information, but avoid unnecessary levels.
Arrays and Lists
An array is an ordered collection of values.
Arrays are useful when the response may contain multiple items of the same type.
Array of Strings
{
"skills": [
"Java",
"Spring Boot",
"Docker"
]
}
Array of Numbers
{
"monthly_sales": [
45000,
52000,
61000
]
}
Array of Objects
{
"employees": [
{
"employee_id": "E101",
"employee_name": "Ajay"
},
{
"employee_id": "E102",
"employee_name": "Pooja"
}
]
}
Defining Array Item Types
The prompt should clearly explain what each array item contains.
Weak instruction:
Return the skills.
Better instruction:
Return skills as an array of strings.
Include one skill per array item.
Do not combine multiple skills in one string.
Incorrect:
{
"skills": [
"Java, Spring Boot, MySQL"
]
}
Correct:
{
"skills": [
"Java",
"Spring Boot",
"MySQL"
]
}
Defining Minimum and Maximum Items
You can control array length.
Return key_points as an array of strings.
Include at least three items.
Include no more than five items.
Keep every item under twenty words.
Empty Arrays
Use an empty array when no items are found.
{
"certifications": []
}
Do not replace an expected array with null unless the schema allows null.
Incorrect:
{
"certifications": null
}
Correct when no certifications are found:
{
"certifications": []
}
Duplicate Items
The prompt can prevent repeated values.
Return technologies as an array of unique strings.
Do not include duplicate technology names.
Array Ordering
The prompt can define an order.
Sort skills alphabetically.
Sort transactions by transaction_date in ascending order.
Order recommendations from highest priority to lowest priority.
Array Prompt Example
Extract all projects from the resume.
Return projects as an array of objects.
Each project object must contain project_name as a string.
Each project object must contain role as a string.
Each project object must contain technologies as an array of strings.
Each project object must contain duration_months as an integer or null.
Return an empty array when no projects are found.
Do not invent missing projects.
Do not include duplicate projects.
Enumerated Values
An enumerated value is a value selected from a fixed list of allowed options.
Enumeration is commonly called enum.
Enums prevent the model from returning different words for the same category.
Without Enumeration
A model may return:
- High
- Very important
- Urgent
- Critical priority
- Top priority
These values may represent similar meanings but are difficult for software to process consistently.
With Enumeration
The prompt can restrict the field to:
- low
- medium
- high
- critical
Example:
{
"priority": "high"
}
Enum Prompt Example
Classify the support ticket.
Return priority as one of low, medium, high, or critical.
Return category as one of billing, technical, account, or general.
Return status as one of open, pending, resolved, or closed.
Do not return values outside the allowed lists.
Expected Output
{
"priority": "high",
"category": "technical",
"status": "open"
}
Case Consistency
Enum values should use consistent capitalization.
Poor design:
- Low
- medium
- HIGH
Better design:
- low
- medium
- high
Unknown Enum Values
Include a fallback option when the model may not be able to select a valid category.
Example allowed values:
- positive
- negative
- neutral
- unknown
Enum Design Rules
- Keep values clear and mutually exclusive.
- Avoid values that overlap in meaning.
- Use simple machine-friendly strings.
- Define an unknown or other option when necessary.
- Explain how to choose between similar values.
- Keep capitalization consistent.
Example with Decision Rules
Return severity as one of low, medium, high, or critical.
Use low when the issue has little impact.
Use medium when the issue affects one user but has a workaround.
Use high when the issue affects multiple users or blocks an important task.
Use critical when the complete system is unavailable or data is at risk.
Null and Missing Values
Null and missing values are not the same.
A null value means the field is present but does not contain a usable value.
A missing value means the field does not appear in the response.
Null Field
{
"termination_date": null
}
This means termination_date is part of the structure, but no date is available.
Missing Field
{
"employee_name": "Anil"
}
The termination_date field does not exist in the object.
When to Use Null
Use null when:
- The field is part of a fixed schema
- The value is unknown
- The value is unavailable
- The value does not apply
- The application expects the field to exist
When to Omit a Field
Omit a field when:
- The field is optional
- The application supports missing properties
- Including the field would add no value
- The schema clearly allows the field to be absent
Do Not Use Placeholder Strings
Avoid placeholder strings such as:
- "N/A"
- "Not available"
- "Unknown"
- "-"
- "None"
These are text values, not null values.
Incorrect:
{
"middle_name": "N/A"
}
Correct:
{
"middle_name": null
}
Null Data Type Definition
A field that allows text or null can be defined as:
"type": [
"string",
"null"
]
Prompt Example
Extract the employee details.
Return employee_id as a string.
Return employee_name as a string.
Return middle_name as a string or null.
Return resignation_date as a string or null.
Use null when the source does not provide the value.
Do not use N/A, unknown, none, or an empty string.
Do not invent missing values.
Empty String vs Null
An empty string is still a string.
{
"middle_name": ""
}
Null represents no value.
{
"middle_name": null
}
Use null when the value is unknown. Use an empty string only when the application specifically requires it.
Empty Array vs Null
Use an empty array when a list is valid but contains no items.
{
"certifications": []
}
Use null only when the list itself is unknown or not applicable and the schema allows null.
Schema Validation
Schema validation checks whether structured output follows a predefined set of rules.
Validation can check:
- Object structure
- Required fields
- Optional fields
- Data types
- Allowed values
- String formats
- Number ranges
- Array sizes
- Nested objects
- Extra properties
Example Schema Requirements
Suppose a candidate evaluation must follow these rules:
- candidate_name must be a string
- experience_years must be an integer
- experience_years cannot be negative
- recommendation must be selected from hire, reject, or review
- skills must be an array of strings
- candidate_name, experience_years, and recommendation are required
Valid Output
{
"candidate_name": "Meera Joshi",
"experience_years": 4,
"recommendation": "hire",
"skills": [
"Java",
"Spring Boot"
]
}
Invalid Output with Wrong Data Type
{
"candidate_name": "Meera Joshi",
"experience_years": "four",
"recommendation": "hire",
"skills": [
"Java",
"Spring Boot"
]
}
The experience_years field should be an integer, not a string.
Invalid Output with Unsupported Enum
{
"candidate_name": "Meera Joshi",
"experience_years": 4,
"recommendation": "strongly recommended",
"skills": [
"Java",
"Spring Boot"
]
}
The recommendation value is invalid because it is not one of the allowed values.
Invalid Output with Missing Field
{
"candidate_name": "Meera Joshi",
"skills": [
"Java",
"Spring Boot"
]
}
The required fields experience_years and recommendation are missing.
Validation Process
- Receive the model response.
- Parse the structured data.
- Compare the output with the schema.
- Identify validation errors.
- Accept the output when it is valid.
- Retry or reject the output when it is invalid.
Syntax Validation vs Schema Validation
Syntax validation checks whether the JSON format is valid.
Schema validation checks whether the content follows the required structure.
This JSON is syntactically valid:
{
"age": "thirty"
}
However, it fails schema validation when age must be an integer.
Validation Prompt Instruction
Return only valid JSON.
Follow the exact field names.
Follow the defined data types.
Include all required fields.
Use only allowed enum values.
Do not add undefined fields.
Validate the response against the schema before returning it.
Important Point
Prompt instructions improve reliability, but application-side validation is still necessary for important systems.
JSON Schema Fundamentals
JSON Schema is a standard way to describe the expected structure and validation rules of JSON data.
It defines:
- The root data type
- Available properties
- Property data types
- Required properties
- Allowed values
- String patterns
- Number ranges
- Array rules
- Nested object rules
- Whether extra properties are allowed
Basic JSON Schema
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer"
}
},
"required": [
"name",
"age"
]
}
This schema requires an object with name and age fields.
Type
The type keyword defines the expected data type.
{
"type": "string"
}
Common type values include:
- object
- array
- string
- integer
- number
- boolean
- null
Properties
The properties keyword defines fields inside an object.
{
"type": "object",
"properties": {
"product_name": {
"type": "string"
},
"price": {
"type": "number"
}
}
}
Required
The required keyword lists the fields that must exist.
{
"required": [
"product_name",
"price"
]
}
Fields defined under properties are not automatically required.
Additional Properties
The additionalProperties keyword controls whether undefined fields are allowed.
{
"additionalProperties": false
}
This prevents the model from adding extra fields.
Enum
The enum keyword restricts a value to a fixed list.
{
"type": "string",
"enum": [
"low",
"medium",
"high"
]
}
Minimum and Maximum
Number ranges can be defined using minimum and maximum.
{
"type": "integer",
"minimum": 0,
"maximum": 100
}
Minimum and Maximum String Length
{
"type": "string",
"minLength": 2,
"maxLength": 100
}
String Format
Some validators support common formats.
{
"type": "string",
"format": "email"
}
Common formats include:
- date
- date-time
- uri
- hostname
- ipv4
- ipv6
- uuid
Format support may depend on the validator being used.
Pattern
The pattern keyword validates a string using a regular expression.
{
"type": "string",
"pattern": "^[A-Z]{3}-[0-9]{4}$"
}
Valid example:
ABC-1024
Array Items
The items keyword defines the type of each array element.
{
"type": "array",
"items": {
"type": "string"
}
}
Array Length
{
"type": "array",
"minItems": 1,
"maxItems": 5
}
Unique Items
{
"type": "array",
"uniqueItems": true
}
Nested Object Schema
{
"type": "object",
"properties": {
"employee_name": {
"type": "string"
},
"address": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"state": {
"type": "string"
}
},
"required": [
"city",
"state"
],
"additionalProperties": false
}
},
"required": [
"employee_name",
"address"
],
"additionalProperties": false
}
Complete Candidate Evaluation Schema
{
"type": "object",
"properties": {
"candidate_name": {
"type": "string",
"minLength": 1
},
"experience_years": {
"type": "integer",
"minimum": 0
},
"skills": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"recommendation": {
"type": "string",
"enum": [
"hire",
"reject",
"review"
]
},
"summary": {
"type": [
"string",
"null"
]
}
},
"required": [
"candidate_name",
"experience_years",
"skills",
"recommendation",
"summary"
],
"additionalProperties": false
}
JSON Schema Prompt
Analyze the candidate profile.
Return one JSON object that follows the provided JSON Schema.
Use the exact property names from the schema.
Include every required property.
Do not include additional properties.
Use null only where the schema allows null.
Use only values allowed by enum.
Return only the JSON object.
Validate the object before returning it.
Handling Schema Violations
A schema violation occurs when the model output does not follow one or more schema rules.
Common Schema Violations
- Missing required field
- Incorrect field name
- Incorrect data type
- Invalid enum value
- Extra undefined field
- Incorrect nested structure
- Invalid number range
- Invalid string format
- Too many array items
- Too few array items
- Duplicate array items
- Null used where null is not allowed
Example Schema Requirement
{
"name": "string",
"age": "integer",
"status": "active or inactive"
}
Violation: Missing Field
{
"name": "Kiran",
"age": 29
}
The required status field is missing.
Violation: Wrong Type
{
"name": "Kiran",
"age": "29",
"status": "active"
}
The age field should be an integer.
Violation: Wrong Enum
{
"name": "Kiran",
"age": 29,
"status": "working"
}
The status field must be active or inactive.
Violation: Additional Field
{
"name": "Kiran",
"age": 29,
"status": "active",
"department": "Development"
}
This is invalid when additional properties are not allowed.
Violation Handling Strategies
Reject the Response
Reject the response when correctness is critical.
Examples:
- Financial transactions
- Medical records
- Legal documents
- Security decisions
- Database updates
Retry the Model
Send the validation errors back to the model and request a corrected response.
Repair Simple Errors
An application may safely repair small formatting problems.
Examples:
- Removing text before JSON
- Converting a numeric string into an integer
- Removing trailing commas
Automatic repair should be used carefully because it may change the intended meaning.
Return a Safe Error Object
{
"success": false,
"error_code": "SCHEMA_VALIDATION_FAILED",
"message": "The generated response did not match the required schema.",
"validation_errors": [
{
"field": "age",
"issue": "Expected integer but received string"
}
]
}
Error Feedback Prompt
The previous response failed schema validation.
Correct only the reported validation errors.
Keep all valid values unchanged.
Include every required field.
Remove all undefined fields.
Follow the exact data types.
Return only the corrected JSON object.
Validation errors: age must be an integer.
Previous response: {"name":"Kiran","age":"29","status":"active"}
Expected Corrected Output
{
"name": "Kiran",
"age": 29,
"status": "active"
}
Preventing Repeated Violations
- Keep the schema simple.
- Use clear field descriptions.
- Define allowed enum values.
- Explain null handling.
- Disallow extra fields.
- Include a valid example.
- Validate every response.
- Return specific error feedback during retries.
Retrying Invalid Responses
Retrying means asking the model to generate a corrected response after validation fails.
A retry should include clear information about what was wrong.
Weak Retry Prompt
Try again.
This prompt does not explain the problem.
Better Retry Prompt
The previous response is invalid.
The experience_years field must be an integer.
The recommendation field must be hire, reject, or review.
Remove the extra confidence_text field.
Return only the corrected JSON object.
Do not change valid fields.
Basic Retry Workflow
- Send the original prompt.
- Receive the structured response.
- Parse the response.
- Validate it against the schema.
- Collect validation errors.
- Build a correction prompt.
- Send the invalid response and errors to the model.
- Validate the corrected response.
- Stop after a defined retry limit.
Retry Prompt Template
Correct the previous structured response.
Follow the original schema exactly.
Fix every listed validation error.
Keep valid field values unchanged.
Do not add explanations.
Do not include markdown formatting.
Return only one valid JSON object.
Validation errors: {validation_errors}
Previous response: {previous_response}
Retry Limit
Do not retry forever.
A common strategy is:
- First generation attempt
- First correction attempt
- Second correction attempt
- Return an error when all attempts fail
Why Retry Limits Are Important
Retry limits prevent:
- Infinite processing loops
- Uncontrolled API costs
- Long response times
- Repeated invalid output
- Application instability
Retry with Original Context
The retry request should preserve important original information.
For example:
Original task: Extract invoice details.
Validation error: total_amount must be a number.
Previous response: {"invoice_number":"INV-101","total_amount":"₹5,000"}
Correction rule: Remove currency symbols from numeric fields.
Return only corrected JSON.
Expected Output
{
"invoice_number": "INV-101",
"total_amount": 5000
}
Do Not Regenerate Unrelated Fields
A retry should normally fix invalid fields without changing valid information.
Prompt instruction:
Modify only fields that failed validation.
Keep all other field values unchanged.
Fallback After Failed Retries
When all retry attempts fail, return a controlled error.
{
"success": false,
"error_code": "STRUCTURED_OUTPUT_GENERATION_FAILED",
"message": "A valid structured response could not be generated.",
"retry_count": 2
}
Structured Output Examples
Structured Output Prompting can be used in many practical situations.
Example One: Sentiment Analysis
Prompt
Analyze the customer review.
Return one JSON object.
Include sentiment as one of positive, negative, neutral, or mixed.
Include confidence as a number between 0 and 1.
Include key_reasons as an array of strings.
Include requires_follow_up as a boolean.
Return only JSON.
Review: The product quality is excellent, but delivery was delayed by six days.
Expected Output
{
"sentiment": "mixed",
"confidence": 0.94,
"key_reasons": [
"The customer praised the product quality.",
"The customer reported a six-day delivery delay."
],
"requires_follow_up": true
}
Explanation
- sentiment uses a fixed enum.
- confidence uses a numeric range.
- key_reasons uses an array of strings.
- requires_follow_up uses a boolean.
Example Two: Resume Information Extraction
Prompt
Extract candidate information from the resume text.
Return candidate_name as a string or null.
Return email as a string or null.
Return phone as a string or null.
Return total_experience_years as a number or null.
Return primary_role as a string or null.
Return technical_skills as an array of unique strings.
Return education as an array of objects.
Each education object must contain degree as a string or null.
Each education object must contain institution as a string or null.
Each education object must contain completion_year as an integer or null.
Use null when a single value is unavailable.
Use an empty array when no list items are found.
Do not invent missing information.
Return only JSON.
Expected Output
{
"candidate_name": "Arjun Deshmukh",
"email": "arjun@example.com",
"phone": null,
"total_experience_years": 4.5,
"primary_role": "Java Developer",
"technical_skills": [
"Java",
"Spring Boot",
"Hibernate",
"MySQL"
],
"education": [
{
"degree": "Bachelor of Engineering",
"institution": "Pune University",
"completion_year": 2021
}
]
}
Example Three: Support Ticket Classification
Prompt
Analyze the support ticket.
Return ticket_category as one of billing, technical, account, delivery, or general.
Return priority as one of low, medium, high, or critical.
Return summary as a string under thirty words.
Return detected_products as an array of strings.
Return requires_human_agent as a boolean.
Return suggested_action as a string.
Return only one JSON object.
Ticket: I cannot log in after changing my password. The reset link also shows an expired token message.
Expected Output
{
"ticket_category": "account",
"priority": "high",
"summary": "The customer cannot access the account because the password reset link returns an expired token error.",
"detected_products": [],
"requires_human_agent": true,
"suggested_action": "Verify the account and issue a new secure password reset link."
}
Example Four: Product Comparison
Prompt
Compare the two products.
Return products as an array of objects.
Each product object must contain name as a string.
Each product object must contain price as a number.
Each product object must contain advantages as an array of strings.
Each product object must contain disadvantages as an array of strings.
Return recommended_product as a string.
Return recommendation_reason as a string.
Return only JSON.
Product A costs 50000 and has better battery life.
Product B costs 45000 and has better display quality.
Expected Output
{
"products": [
{
"name": "Product A",
"price": 50000,
"advantages": [
"Better battery life"
],
"disadvantages": [
"Higher price"
]
},
{
"name": "Product B",
"price": 45000,
"advantages": [
"Better display quality",
"Lower price"
],
"disadvantages": [
"Lower battery performance than Product A"
]
}
],
"recommended_product": "Product B",
"recommendation_reason": "Product B provides a lower price and better display quality, making it suitable for users who value screen quality and cost."
}
Example Five: Code Review Result
Prompt
Review the Java method.
Return language as the string Java.
Return valid_code as a boolean.
Return issue_count as an integer.
Return issues as an array of objects.
Each issue object must contain line_number as an integer or null.
Each issue object must contain severity as one of low, medium, high, or critical.
Each issue object must contain category as one of syntax, logic, security, performance, readability, or maintainability.
Each issue object must contain description as a string.
Each issue object must contain suggested_fix as a string.
Return corrected_code as a string or null.
Return only JSON.
Java code: public int divide(int a, int b) { return a / b; }
Expected Output
{
"language": "Java",
"valid_code": true,
"issue_count": 1,
"issues": [
{
"line_number": 1,
"severity": "high",
"category": "logic",
"description": "The method does not handle division by zero.",
"suggested_fix": "Check whether b is zero before performing division."
}
],
"corrected_code": "public int divide(int a, int b) { if (b == 0) { throw new IllegalArgumentException(\"Divisor cannot be zero\"); } return a / b; }"
}
Example Six: Invoice Extraction
Prompt
Extract invoice data.
Return invoice_number as a string or null.
Return invoice_date as a date string in YYYY-MM-DD format or null.
Return supplier as an object.
Inside supplier, include name as a string or null.
Inside supplier, include tax_id as a string or null.
Return items as an array of objects.
Each item must contain description as a string.
Each item must contain quantity as a number.
Each item must contain unit_price as a number.
Each item must contain line_total as a number.
Return subtotal as a number or null.
Return tax_amount as a number or null.
Return total_amount as a number or null.
Return currency as a three-letter currency code or null.
Do not include currency symbols in number fields.
Do not calculate missing values unless explicitly instructed.
Return only JSON.
Expected Output
{
"invoice_number": "INV-2026-4401",
"invoice_date": "2026-08-06",
"supplier": {
"name": "CodeTech Services",
"tax_id": "27ABCDE1234F1Z5"
},
"items": [
{
"description": "Website Development",
"quantity": 1,
"unit_price": 30000,
"line_total": 30000
}
],
"subtotal": 30000,
"tax_amount": 5400,
"total_amount": 35400,
"currency": "INR"
}
Example Seven: Article Metadata Generation
Prompt
Generate metadata for the article.
Return title as a string between forty and sixty characters.
Return meta_description as a string under one hundred sixty characters.
Return slug as a lowercase hyphen-separated string.
Return primary_keyword as a string.
Return secondary_keywords as an array of five unique strings.
Return category as one of prompt-engineering, artificial-intelligence, programming, or career.
Return reading_time_minutes as an integer.
Return only JSON.
Article topic: Structured Output Prompting for beginners.
Expected Output
{
"title": "Structured Output Prompting: Complete Beginner Guide",
"meta_description": "Learn structured output prompting, JSON schemas, validation, required fields, nested objects, arrays, and reliable AI response design.",
"slug": "structured-output-prompting-beginner-guide",
"primary_keyword": "structured output prompting",
"secondary_keywords": [
"JSON output prompting",
"schema-based prompting",
"structured AI responses",
"JSON Schema",
"prompt validation"
],
"category": "prompt-engineering",
"reading_time_minutes": 12
}
Complete Structured Output Prompt Template
Role: You are a data extraction assistant.
Task: Analyze the provided input and return structured data.
Output format: Return one valid JSON object.
Field rule: Use only the field names defined below.
Type rule: Follow the specified data type for every field.
Required rule: Include every required field.
Optional rule: Include optional fields only according to the defined missing-value policy.
Null rule: Use null only for fields that explicitly allow null.
Array rule: Use an empty array when no list items are found.
Enum rule: Use only values from the allowed enum lists.
Nested object rule: Keep nested fields inside their defined parent object.
Additional field rule: Do not add undefined fields.
Accuracy rule: Do not invent missing information.
Validation rule: Validate the response against the schema before returning it.
Response rule: Do not include explanations, headings, markdown, or text outside the JSON object.
Schema: {insert_schema_here}
Input: {insert_input_here}
Structured Output Prompt with Field Definitions
Analyze the customer request.
Return customer_name as a string or null.
Return request_type as one of complaint, question, refund, cancellation, or feedback.
Return priority as one of low, medium, high, or critical.
Return products as an array of strings.
Return problem_summary as a string under fifty words.
Return requested_resolution as a string or null.
Return requires_human_support as a boolean.
Use null when a single value is unavailable.
Use an empty array when no products are mentioned.
Do not invent names, products, or requested actions.
Do not add fields.
Return only one valid JSON object.
Customer request: {insert_customer_request_here}
Structured Output Prompt with JSON Schema
Analyze the provided text.
Generate output that follows the JSON Schema exactly.
Use exact field names.
Include all required fields.
Follow all field data types.
Follow all enum restrictions.
Follow all minimum and maximum limits.
Do not add undefined fields.
Use null only where allowed.
Return only one valid JSON object.
JSON Schema:
{
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": [
"technical",
"billing",
"account",
"general"
]
},
"priority": {
"type": "string",
"enum": [
"low",
"medium",
"high",
"critical"
]
},
"summary": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"requires_follow_up": {
"type": "boolean"
}
},
"required": [
"category",
"priority",
"summary",
"requires_follow_up"
],
"additionalProperties": false
}
Input: {insert_input_here}
Structured Output Validation Example in JavaScript
The following JavaScript example checks a simple response object manually.
// Validate the structured candidate response
function validateCandidate(data) {
const errors = [];
if (typeof data !== "object" || data === null || Array.isArray(data)) {
errors.push("Response must be an object.");
return errors;
}
if (typeof data.candidate_name !== "string" || data.candidate_name.trim() === "") {
errors.push("candidate_name must be a non-empty string.");
}
if (!Number.isInteger(data.experience_years) || data.experience_years < 0) {
errors.push("experience_years must be a non-negative integer.");
}
const allowedRecommendations = ["hire", "reject", "review"];
if (!allowedRecommendations.includes(data.recommendation)) {
errors.push("recommendation must be hire, reject, or review.");
}
if (!Array.isArray(data.skills) || !data.skills.every(skill => typeof skill === "string")) {
errors.push("skills must be an array of strings.");
}
return errors;
}
// Test the response
const candidate = {
candidate_name: "Neha",
experience_years: 5,
recommendation: "hire",
skills: ["Java", "Spring Boot"]
};
const validationErrors = validateCandidate(candidate);
console.log(validationErrors.length === 0 ? "Valid response" : validationErrors);
Structured Output Validation Example in Python
# Validate a structured employee response
def validate_employee(data):
errors = []
if not isinstance(data, dict):
return ["Response must be an object."]
if not isinstance(data.get("employee_id"), str) or not data.get("employee_id"):
errors.append("employee_id must be a non-empty string.")
if not isinstance(data.get("age"), int) or data.get("age") < 18:
errors.append("age must be an integer greater than or equal to 18.")
if data.get("status") not in ["active", "inactive"]:
errors.append("status must be active or inactive.")
if not isinstance(data.get("skills"), list):
errors.append("skills must be an array.")
elif not all(isinstance(skill, str) for skill in data["skills"]):
errors.append("Every skill must be a string.")
return errors
# Test the structured response
employee = {
"employee_id": "E1001",
"age": 28,
"status": "active",
"skills": ["Java", "SQL"]
}
validation_errors = validate_employee(employee)
print("Valid response" if not validation_errors else validation_errors)
Structured Output Validation Example in Java
// Validate a structured product object
public class ProductValidator {
public static boolean isValidProduct(Product product) {
if (product == null) {
return false;
}
if (product.getProductName() == null || product.getProductName().isBlank()) {
return false;
}
if (product.getPrice() < 0) {
return false;
}
if (product.getCategory() == null) {
return false;
}
return true;
}
}
Java Product Model
// Represent structured product data
public class Product {
private String productName;
private double price;
private String category;
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
Common Mistakes in Structured Output Prompting
Requesting JSON Without Defining Fields
Weak prompt:
Return the answer in JSON.
The model does not know which fields are expected.
Better prompt:
Return one JSON object.
Include topic as a string.
Include summary as a string.
Include key_points as an array of strings.
Mixing Numbers and Text
Incorrect:
{
"price": "5000 INR"
}
Better:
{
"price": 5000,
"currency": "INR"
}
Using Undefined Enum Values
Incorrect:
{
"priority": "very urgent"
}
Better:
{
"priority": "critical"
}
Adding Extra Explanations
Incorrect response:
Here is the requested JSON:
{
"status": "success"
}
Better response:
{
"status": "success"
}
Using Empty Strings for Missing Values
Incorrect:
{
"phone": ""
}
Better:
{
"phone": null
}
Returning Objects Instead of Arrays
Incorrect:
{
"skills": {
"first": "Java",
"second": "Python"
}
}
Better:
{
"skills": [
"Java",
"Python"
]
}
Changing Field Names
Expected:
experience_years
Incorrect:
years_of_experience
Structured systems depend on exact field names.
Creating Unsupported Fields
Expected fields:
- name
- age
- status
Incorrect additional field:
{
"name": "Rohit",
"age": 30,
"status": "active",
"description": "Experienced employee"
}
Use additionalProperties as false when extra fields must be rejected.
Overly Complex Schema
A deeply nested schema with many optional rules can reduce output reliability.
Start with a simple schema and increase complexity only when needed.
Best Practices for Structured Output Prompting
Use Clear Field Names
Choose names that clearly represent their values.
Define Every Data Type
Do not assume the model will choose the correct type automatically.
Separate Values from Units
Use:
{
"weight": 75,
"weight_unit": "kg"
}
Instead of:
{
"weight": "75 kg"
}
Define Required Fields
Clearly state which fields must always be present.
Define Missing-Value Rules
Tell the model whether to use null, an empty array, or omit an optional field.
Use Enumerations
Restrict category fields to a fixed set of values.
Control Additional Fields
Tell the model not to add undefined properties.
Include Valid Examples
One correct example can make the required structure clearer.
Avoid Contradictory Rules
Do not say:
Always include every field.
Omit fields when values are unavailable.
These instructions conflict unless the difference between required and optional fields is clearly explained.
Validate Every Important Response
Never assume that generated data is valid only because it looks correct.
Use Retry Limits
Define how many correction attempts the system allows.
Keep Schemas Practical
Use only the fields required by the application.
Use Stable Naming
Do not switch between snake case and camel case in the same schema.
Define Array Item Structure
Do not only say that a field is an array. Explain what each item must contain.
Prevent Fabricated Data
Include a direct instruction:
Do not invent values that are not supported by the input.
Structured Output Design Checklist
Before using a structured output prompt, verify the following points:
- Is the output format clearly defined?
- Are all field names specific and consistent?
- Is the data type of every field defined?
- Are required fields identified?
- Are optional fields identified?
- Is the missing-value policy defined?
- Are nested objects logically grouped?
- Are array item types defined?
- Are minimum and maximum array sizes needed?
- Are enum values clearly listed?
- Are number ranges defined?
- Are string formats defined?
- Are extra fields allowed or rejected?
- Is a valid example included?
- Is the response validated after generation?
- Are validation errors returned clearly?
- Is a retry limit defined?
- Is there a fallback error response?
- Does the prompt prevent invented information?
- Does the model return only the required structure?
Final Structured Output Prompting Template
Role: You are a structured data generation assistant.
Objective: Convert the provided input into a validated structured response.
Output format: Return one valid JSON object.
Field names: Use the exact field names defined in the schema.
Data types: Follow the required data type for every field.
Required fields: Include every property listed as required.
Optional fields: Follow the defined rule for unavailable optional values.
Missing values: Use null only when the schema allows null.
Empty collections: Use an empty array when no valid list items are found.
Enumerations: Use only values listed in enum definitions.
Nested objects: Keep child fields inside their defined parent object.
Arrays: Follow the defined item structure and length rules.
Number rules: Follow all minimum and maximum limits.
String rules: Follow all length, pattern, and format rules.
Extra properties: Do not add properties that are not defined.
Accuracy: Use only information supported by the provided input.
Validation: Check the complete response against the schema before returning it.
Correction: Fix all schema violations before producing the final response.
Response restriction: Do not include headings, explanations, markdown, or text outside the JSON object.
JSON Schema: {insert_json_schema_here}
Input Data: {insert_input_data_here}
Conclusion
Structured Output Prompting makes AI responses predictable, machine-readable, and easier to validate.
A strong structured output prompt defines:
- Exact field names
- Correct data types
- Required and optional fields
- Nested object relationships
- Array item structures
- Allowed enum values
- Null and missing-value rules
- Validation requirements
- Retry and error-handling rules
The main purpose of structured output is not only to make the response look organized. Its purpose is to make the response reliable enough for software systems to process.
For important applications, prompting and validation should work together. The prompt tells the model what structure to generate, while the schema validator checks whether the generated response follows that structure.
A well-designed structured output prompt reduces parsing problems, prevents inconsistent field names, improves application integration, and creates more dependable AI-powered workflows.
Frequently Asked Questions
What is structured output prompting?
Structured output prompting asks an AI model to return information in a fixed, predictable structure - JSON, XML, YAML, or a schema-based object - with named fields and defined data types, instead of a free-form paragraph.
What are the main benefits of structured responses over plain text?
Structured responses give predictable field names, are easy for applications to read directly, are easier to validate automatically, map cleanly to database columns, and reduce the parsing errors that come with extracting data from unstructured text.
What is the difference between a null value and a missing field?
A null value means the field is present in the structure but has no usable value, such as "termination_date": null. A missing field means the property does not appear in the object at all. The two should not be used interchangeably in a schema.
How do required and optional fields work in a structured output prompt?
Required fields must appear in every valid response, usually because the application cannot function without them. Optional fields may be included only when the information is available. Marking too many fields as required can cause unnecessary failures when source data is incomplete.
What is an enum and why is it useful in structured prompting?
An enum (enumerated value) restricts a field to a fixed list of allowed options, such as low, medium, high, or critical for priority. It prevents the model from returning inconsistent wording for the same concept, such as "urgent" versus "top priority."
What is JSON Schema and what does it define?
JSON Schema is a standard way to describe the expected structure of JSON data - the root type, properties and their data types, which properties are required, allowed enum values, string patterns, number ranges, array rules, and whether extra properties are allowed.
What's the difference between syntax validation and schema validation?
Syntax validation only checks whether the JSON itself can be parsed. Schema validation checks whether the content follows the required structure - for example, {"age": "thirty"} is syntactically valid JSON but fails schema validation if age must be an integer.
What should happen when a model's output violates the schema?
Depending on how critical correctness is, the application can reject the response, send the validation errors back to the model for a retry, safely repair small formatting issues, or return a structured error object - application-side validation is still required even with a good prompt.
How should a retry prompt be written after a validation failure?
A good retry prompt states exactly what was wrong (e.g. "experience_years must be an integer"), includes the previous invalid response, instructs the model to keep valid fields unchanged, and asks for only the corrected JSON object - "try again" alone is not enough.
Does using JSON automatically mean the output is well-structured?
No. A response isn't properly structured just because it uses JSON syntax - it must also follow the required field names, data types, allowed enum values, and null-vs-missing rules defined by the schema.