Structured Outputs

Structured outputs allow you to constrain AI model responses to follow a specific JSON schema, ensuring reliable and predictable data formats. This feature is essential for building robust applications that need to parse and process AI responses programmatically.

Universal Support: All chat models on Tinfoil support structured outputs with JSON schema validation, enabling consistent data extraction across different models.

Benefits

  • Guaranteed Format: Responses always match your specified JSON schema
  • Type Safety: Enforce specific data types, required fields, and constraints
  • Reliable Parsing: No need for complex text parsing or error handling
  • API Integration: Perfect for building APIs that need consistent response formats
  • Data Extraction: Extract structured information from unstructured text

Basic Example

Here’s how to use structured outputs to extract contact information:

from tinfoil import TinfoilAI
import os
import json

# Load environment variables
try:
    from dotenv import load_dotenv
    load_dotenv()
except ImportError:
    pass

# Initialize client (works with any chat model)
client = TinfoilAI(
    enclave="qwen2-5-72b.model.tinfoil.sh",
    repo="tinfoilsh/confidential-qwen2-5-72b",
    api_key=os.getenv("TINFOIL_API_KEY")
)

# Create a JSON schema prompt
schema_prompt = """
Extract contact information and return it as JSON with this exact structure:
{
    "name": "string (required)",
    "email": "string or null",
    "phone": "string or null",
    "company": "string or null"
}

Text to extract from: John Smith works at Acme Corp, his email is [email protected] and phone is +1-555-0123

Return only the JSON object:
"""

# Extract structured data
response = client.chat.completions.create(
    model="qwen2-5-72b",
    messages=[
        {"role": "user", "content": schema_prompt}
    ],
    temperature=0.1  # Lower temperature for more consistent formatting
)

# Parse the JSON response
contact_json = json.loads(response.choices[0].message.content)
print(f"Name: {contact_json['name']}")
print(f"Email: {contact_json.get('email')}")
print(f"Company: {contact_json.get('company')}")
print(f"Phone: {contact_json.get('phone')}")

Complex Schema Example

For more complex data structures with nested objects and arrays:

# Create a detailed JSON schema prompt
company_prompt = """
Create a company profile and return it as JSON with this exact structure:
{
    "name": "string",
    "founded_year": integer,
    "employees": [
        {
            "name": "string",
            "age": integer,
            "email": "string or null",
            "addresses": [
                {
                    "street": "string",
                    "city": "string", 
                    "state": "string",
                    "zip_code": "string"
                }
            ],
            "is_employed": boolean
        }
    ],
    "headquarters": {
        "street": "string",
        "city": "string",
        "state": "string", 
        "zip_code": "string"
    }
}

Company details:
- Name: TechCorp
- Founded in 2020
- Headquarters: 123 Tech St, San Francisco, CA 94105
- Employees: Alice Johnson (age 30, [email protected], employed) and Bob Smith (age 25, no email, employed)
- Alice lives at 456 Oak Ave, Palo Alto, CA 94301

Return only the JSON object:
"""

# Initialize client for complex example
client = TinfoilAI(
    enclave="mistral-small-3-1-24b-p.model.tinfoil.sh",
    repo="tinfoilsh/confidential-mistral-small-3-1-24b-prod",
    api_key=os.getenv("TINFOIL_API_KEY")
)

# Extract complex structured data
response = client.chat.completions.create(
    model="mistral-small-3-1-24b",
    messages=[{"role": "user", "content": company_prompt}],
    temperature=0.1
)

company = json.loads(response.choices[0].message.content)
print(f"Company: {company['name']}")
print(f"Founded: {company['founded_year']}")
print(f"HQ: {company['headquarters']['city']}, {company['headquarters']['state']}")
print(f"Employees: {len(company['employees'])}")

Data Analysis Example

Perfect for analyzing and structuring data from text:

# Create analysis prompt with schema
analysis_prompt = """
Analyze these product reviews and return a JSON analysis with this exact structure:
{
    "product_name": "string",
    "overall_rating": number,
    "reviews": [
        {
            "rating": integer (1-5),
            "sentiment": "positive" | "negative" | "neutral",
            "key_points": ["string", "string"],
            "would_recommend": boolean
        }
    ],
    "summary": "string"
}

Reviews for the "SuperPhone X":

Review 1: "Amazing phone! Great camera quality and fast performance. Battery lasts all day. Definitely recommend! 5 stars."

Review 2: "Phone is okay but overpriced. Camera is good but not revolutionary. Battery life is average. 3 stars."

Review 3: "Worst phone ever! Crashes constantly, terrible battery life, customer service is awful. Save your money! 1 star."

Return only the JSON object:
"""

# Initialize client for analysis example
client = TinfoilAI(
    enclave="llama3-3-70b-p.model.tinfoil.sh",
    repo="tinfoilsh/confidential-llama3-3-70b-prod",
    api_key=os.getenv("TINFOIL_API_KEY")
)

# Analyze product reviews
response = client.chat.completions.create(
    model="llama3-3-70b",
    messages=[{"role": "user", "content": analysis_prompt}],
    temperature=0.1
)

analysis = json.loads(response.choices[0].message.content)
print(f"Product: {analysis['product_name']}")
print(f"Overall Rating: {analysis['overall_rating']}/5")
print(f"Number of Reviews: {len(analysis['reviews'])}")
for i, review in enumerate(analysis['reviews'], 1):
    print(f"Review {i}: {review['rating']} stars, {review['sentiment']}")

Model Recommendations

ModelBest ForStructured Output Quality
Qwen 2.5 72BComplex schemas, data processing, API responsesExcellent
Mistral Small 3.1 24BSimple to moderate schemas, fast responsesVery Good
DeepSeek R1 70BAnalytical data, research outputsVery Good
Llama 3.3 70BContent analysis, conversational dataGood

Best Practices

  1. Define Clear Schemas: Use Zod or JSON Schema to define your data structure precisely
  2. Use Descriptive Field Names: Choose field names that clearly indicate their purpose
  3. Handle Nullable Fields: Use .nullable() in Zod for optional fields that can be null
  4. Set Appropriate Types: Use specific types (string, number, boolean) rather than generic ones
  5. Validate Constraints: Add validation rules like .min(), .max(), .email() where appropriate
  6. Handle Errors: Always wrap JSON parsing in try-catch blocks
  7. Use Nullish Coalescing: Handle null values gracefully with ?? operator

Error Handling

import os
import json
from tinfoil import TinfoilAI

# Load environment variables
try:
    from dotenv import load_dotenv
    load_dotenv()
except ImportError:
    pass

try:
    client = TinfoilAI(
        enclave="qwen2-5-72b.model.tinfoil.sh",
        repo="tinfoilsh/confidential-qwen2-5-72b",
        api_key=os.getenv("TINFOIL_API_KEY")
    )
    
    schema_prompt = """
    Extract contact information and return it as JSON with this exact structure:
    {
        "name": "string (required)",
        "email": "string or null",
        "phone": "string or null",
        "company": "string or null"
    }
    
    Text: Extract data...
    
    Return only the JSON object:
    """
    
    response = client.chat.completions.create(
        model="qwen2-5-72b",
        messages=[{"role": "user", "content": schema_prompt}],
        temperature=0.1
    )
    
    # Try to parse JSON response
    try:
        contact = json.loads(response.choices[0].message.content)
        print(f"Successfully parsed: {contact['name']}")
        print(f"Email: {contact.get('email')}")
        print(f"Company: {contact.get('company')}")
    except json.JSONDecodeError:
        print("JSON parsing failed, raw response:")
        print(response.choices[0].message.content)
        
except Exception as e:
    print(f"Error: {e}")

Use Cases

  • API Development: Create consistent API responses
  • Data Extraction: Extract structured data from documents
  • Form Processing: Parse form submissions and surveys
  • Content Analysis: Analyze reviews, feedback, and comments
  • Report Generation: Create structured reports from unstructured data
  • Database Integration: Generate database-ready records
  • Workflow Automation: Structure data for automated processing