Skip to main content
Large language models are powerful but unpredictably creative. Ask for a customer ID and you might get a full sentence. Structured Outputs solve this by forcing the AI to return data in exact formats you define.

Understanding Structured Outputs

Structured Outputs define output variables with specific data types that the AI must populate when executing a tool. This transforms conversational responses into clean, typed data.
Tool configuration showing output variables
Why Use Structured Outputs:
  • Predictable formats: AI returns data in exact structure you define
  • Type safety: Guarantee data types match expectations
  • Easy linking: Output variables become inputs for downstream nodes
  • Reduced errors: Eliminate parsing and validation issues

Configuring Output Variables

Output variables are defined at the tool level in Custom GPT tool configuration.
1

Access Tool Configuration

Open your Custom GPT tool settings and navigate to the Output variables section.
2

Add Output Variable

Click “Add output” to create a new output variable.
Output variable configuration
Variable Name:
  • Use snake_case naming (e.g., customer_email, ticket_priority)
  • Must be unique within the tool
Description:
  • Clear instruction for the AI on what to extract
  • Be explicit and prescriptive
  • Example: “Extract the customer’s email address exactly as provided”
Data Type: Select from available types: String, Number, Boolean, Object, Enum
Data type selector
3

Configure Multiple Outputs

Add multiple output variables to structure complex data extraction.Example: Email Classification Tool
category (String) - Email category (SALES, SUPPORT, BILLING)
priority (Number) - Priority level from 1-5
requires_response (Boolean) - Whether email needs reply

Data Types

String: Text data of any length. Use for names, descriptions, categories. Number: Numeric values including integers and decimals. Use for IDs, quantities, amounts, scores. Boolean: True or false values. Use for flags, status indicators, yes/no determinations. Object: Nested JSON structures for complex, grouped data. Example:
Variable: customer_info
Type: Object
Description: Customer details as JSON with name, email, phone fields
Access nested fields:
${node_name.customer_info.name}
${node_name.customer_info.email}
Enum: Constrained to specific allowed values. Use for fixed categories, status values. Example:
Variable: priority_level
Type: Enum
Allowed values: HIGH, MEDIUM, LOW

Key Principles

Sequential Processing

All outputs in one tool are generated in a single LLM call, processed sequentially. Order matters. Recommended order:
  1. Context gathering (if needed)
  2. Reasoning/analysis fields
  3. Intermediate extractions
  4. Final answer fields
Example:
{
  "request_summary": "<String>",
  "urgency_analysis": "<String>",
  "is_urgent": "<Boolean>",
  "category_reasoning": "<String>",
  "category": "<String>",
  "priority": "<Number>"
}

Reason First

Always place reasoning fields before extraction fields. This forces the model to analyze before concluding. Poor Design:
{
  "category": "<String // The email category>"
}
Better Design:
{
  "category_reasoning": "<String // Analysis of why this category fits>",
  "category": "<String // The email category>"
}
Why it matters:
  • Dramatically improves accuracy
  • Makes logic transparent and debuggable
  • Reasoning can be stored for review

Descriptions Are Directives

The description is a direct instruction to the AI. Be explicit. Examples: Simple extraction:
"Extract the 7-digit customer ID, numbers only"
Conditional logic:
"Extract language as ISO-639-1 code. If unknown, return 'N/A'"
Constrained values:
"Classify as one of: EXACT_MATCH, SIMILAR_MATCH, MISMATCH, or N/A"

Unique Naming

Every output variable must have a unique name across your entire agent. Good naming:
  • email_classifier_category
  • invoice_extractor_total
  • customer_analysis_id
Avoid:
  • result, output, data (too generic, likely duplicated)

Linking Outputs to Downstream Nodes

Structured outputs create variables accessible in subsequent nodes.
Task execution showing structured output
Syntax:
${node_name.variable_name}
Example workflow:
Node 1: classify_email
  Outputs: category, priority, customer_email

Node 2: route_to_team
  Input: ${classify_email.category}

Node 3: send_notification
  Input: ${classify_email.customer_email}
See Variables & State for detailed linking patterns.

Common Patterns

Classification + Data Extraction:
{
  "classification": "<String // SALES, SUPPORT, or BILLING>",
  "customer_id": "<String // 7-digit customer ID>",
  "urgency_level": "<Number // 1-5 scale>"
}
Use: Branch workflow based on classification, pass customer_id to CRM lookup, use urgency_level for prioritization. Validation with Confidence:
{
  "extracted_value": "<String>",
  "confidence_score": "<Number // 0-100>",
  "needs_review": "<Boolean // true if confidence < 80>"
}
Use: Branch on needs_review - high confidence → automate, low confidence → human review. Handling Arrays: For multiple items, structure as an array within an Object type:
Variable: products
Type: Object
Description: Array of products, each with name, sku, price, in_stock fields
AI returns:
{
  "products": [
    {"name": "Wireless Mouse", "sku": "WM-2024", "price": 29.99, "in_stock": true},
    {"name": "USB Cable", "sku": "CABLE-6FT", "price": 12.99, "in_stock": false}
  ]
}

Best Practices

Naming Conventions:
  • Prefix with tool purpose: email_classifier_category, invoice_extractor_total
  • Use descriptive names: customer_priority_score not score
  • Avoid generic names: Don’t use result, output, data
Separation of Concerns: Don’t combine everything into one field. Split outputs logically:
{
  "customer_name": "<String // Customer's full name>",
  "customer_email": "<String // Customer's email address>",
  "order_id": "<String // 8-character order ID>",
  "priority": "<Number // Priority level 1-5>"
}
Error Handling: Design outputs to capture extraction confidence:
{
  "extracted_date": "<String // Date in YYYY-MM-DD format>",
  "date_confidence": "<String // HIGH, MEDIUM, LOW, or NONE>",
  "extraction_notes": "<String // Any issues or assumptions made>"
}
Performance Optimization: Minimize unnecessary reasoning fields in high-volume workflows. Use reasoning for critical extractions, skip for simple operations.

Troubleshooting

Issue: AI returns string when you expected numberSolutions:
  • Make description more explicit: “Extract as a number, digits only, no text”
  • Check if source data actually contains the expected type
  • Add validation in description: “If not a number, return 0”
Issue: AI returns dates in different formatsSolutions:
  • Be prescriptive: “Return date in YYYY-MM-DD format exactly”
  • Provide examples in description: “Format: 2024-01-15”
  • Use constrained values (Enum) when possible
Issue: Some outputs are empty or nullSolutions:
  • Add fallback instructions: “If not found, return ‘N/A’”
  • Check if AI has access to required input data
  • Verify previous nodes are passing data correctly
Issue: Downstream node can’t access structured outputSolutions:
  • Verify unique variable naming across entire agent
  • Check node execution completed successfully
  • Review exact variable name (case-sensitive)
  • Confirm data type compatibility

Next Steps