Structured Output with JSON Schema

Overview

The structured output feature allows you to control and validate LLM responses using JSON Schema. This enables predictable, type-safe responses that can be directly used in your application logic without complex parsing or error handling.

Key benefits include:

  1. Type Safety - Enforce response structure with strong typing
  2. Validation - Ensure responses match expected formats and value constraints
  3. Consistency - Get reliable, predictable outputs for programmatic use
  4. Simplicity - Eliminate complex parsing of free-form text

For additional details and implementation guidelines, see the OpenAI Structured Outputs Guide.

How It Works

  1. Define a JSON Schema describing the expected response format
  2. Convert the schema to a string using .toString()
  3. Pass the schema to an LLM function like #askGPT using the response_format option
  4. Parse the structured response using standard JSON parsing
  5. Use the strongly typed result directly in your application logic

Usage

Here's a basic example of using structured output:

// Define the schema with strong typing var schema = { name: "result", strict: true, description: "A categorization result", schema: { @type: "object", properties: { category: { @type: "string", description: "The category of the input", enum: ["Type A", "Type B", "Type C"] }, confidence: { @type: "number", description: "Confidence score between 0 and 1" } }, additionalProperties: false, required: ["category", "confidence"] } }.toString(); // Call GPT with the structured output format var ask = #askGPT($prompt, { model: "openai/gpt-4.1-nano", function_call: "none", history_length: 0, save_response_in_history: false, response_format: schema }, promptName: "categorizer"); // Parse and use the result with proper typing var result = ask.responseText.parseJSON() as { category: string; confidence: number; }; if ((result?.confidence ?? 0) > 0.8) { #log("High confidence classification: " + (result?.category?.toString()??"-")); } else { #log("Low confidence classification: " + (result?.category?.toString()??"-")); }

Schema Components

A properly structured schema includes:

ComponentDescription
nameName identifier for the schema
strictBoolean flag to enforce strict validation
descriptionHuman-readable description of the schema purpose
schemaThe actual JSON Schema definition

The schema definition follows standard JSON Schema syntax with the following common elements:

  • @type - Specifies the data type (object, string, number, boolean, array)
  • properties - Defines the object properties (for object types)
  • required - Lists required properties. For best results, include all defined properties
  • additionalProperties - Controls whether extra properties are allowed. Should always be set to false to ensure strict validation
  • Type-specific validators (enum for example)

Advanced Example

Here's a more complex example for a multi-field form:

var schema = { name: "formData", strict: true, description: "Extracted form information", schema: { @type: "object", properties: { firstName: { @type: "string", description: "Customer's first name" }, lastName: { @type: "string", description: "Customer's last name" }, reason: { @type: "string", description: "Reason for contact", enum: ["Support", "Sales", "Billing", "Other"] }, urgency: { @type: "integer", description: "Urgency level from 1-5" }, callback: { @type: "boolean", description: "Whether customer wants a callback" } }, required: ["firstName", "lastName", "reason", "urgency", "callback"], additionalProperties: false } }.toString(); var result = #askGPT(#getFormattedTranscription(), { model: "openai/gpt-4.1", response_format: schema, function_call: "none", history_length: 0, save_response_in_history: false }); var formData = result.responseText.parseJSON() as { firstName: string; lastName: string; reason: "Support" | "Sales" | "Billing" | "Other"; urgency: number; callback: boolean; }; #log(formData); // Now use the structured data in your application #sayText("Thank you " + (formData?.firstName??"") + ", we'll handle your " + (formData?.reason?.toString()?.toLowerCase() ?? "") + " request."); if (formData?.callback == true) { #sayText("We'll call you back as soon as possible."); }

Best Practices

For optimal results with structured output:

  1. Be Specific - Define schemas with precise types and constraints
  2. Include Descriptions - Add clear descriptions for each field to guide the LLM
  3. Use Enums - Restrict string values to specific options when possible
  4. Set Required Fields - Always include all defined properties in the required array
  5. Disable Additional Properties - Always set additionalProperties: false to prevent unexpected fields
  6. Handle Parsing - Always handle potential parsing failures gracefully
  7. Use Type Assertions - Leverage TypeScript-style type assertions for type safety

Troubleshooting

If you encounter issues with structured output:

  1. Check Schema Syntax - Ensure your JSON Schema is valid
  2. Verify Conversion - Make sure .toString() is called on the schema object
  3. Review LLM Response - Look at the raw responseText for format issues
  4. Test with Simpler Schemas - Start with basic schemas and add complexity
  5. Try Different Models - Some models handle structured output better than others

Limitations

Be aware of these limitations:

  1. Requires model support for structured output (works best with GPT-4 and newer models)
  2. Complex schemas may reduce response quality
  3. Very strict schemas might cause model completion failures
  4. The strict option may reject valid responses if not perfectly formatted
Found a mistake? Let us know.

Enroll in beta

Request invite to our private Beta program for developers to join the waitlist. No spam, we promise.