Skip to main content
Structured outputs ensure your LLM responses match a predefined schema, making them reliable and easy to parse. This tutorial shows you how to use OpenAI’s function calling and structured outputs while monitoring everything with Helicone.

What Are Structured Outputs?

Structured outputs force the model to return data in a specific format:

Function Calling

Model calls predefined functions with typed parameters

Response Format

Model returns JSON matching a specified schema
Both approaches use strict: true to guarantee schema compliance.

Prerequisites

  • Python 3.8+ or Node.js 18+
  • OpenAI API key
  • Helicone API key (sign up free)

Setup

Create .env:

What We’ll Build

A flight booking assistant that:
  1. Extracts search parameters using function calling
  2. Searches a database with extracted parameters
  3. Formats results using structured outputs
  4. Tracks everything in Helicone

Implementation

Step 1: Define Data Models

Step 2: Initialize OpenAI with Helicone

Step 3: Use Function Calling to Extract Parameters

Step 4: Search Flight Database

Simulate a database search:

Step 5: Format Response with Structured Outputs

Step 6: Handle Refusals

Structured outputs can refuse unsafe requests:

Step 7: Track Refusals in Helicone

Filter for refused requests in your dashboard:
  1. Go to Helicone Requests
  2. Add filter: refusal exists
  3. Review why requests were refused
This helps identify:
  • False positives (safe requests incorrectly refused)
  • Patterns in refused content
  • Opportunities to improve prompts

Complete Flight Assistant

Put everything together:

Monitoring in Helicone

View your structured outputs in the dashboard:

Session View

Each query creates a session with:
  1. Parameter extraction request
  2. Response formatting request
Click any session to see the complete flow and costs.

Filter by Refusals

To see refused requests:
  1. Go to Requests
  2. Add filter: refusal field exists
  3. Review and adjust prompts if needed

Track Tool Usage

Filter by Step property:
  • parameter-extraction - How often is extraction called?
  • response-formatting - How many results are formatted?

Best Practices

Setting strict: true guarantees schema compliance. Without it, the model may return invalid data.
Always check message.refusal and provide fallback responses. Track refusals in Helicone to identify patterns.
Complex nested schemas are harder for models to follow. Start simple and add complexity only when needed.
Clear field names and descriptions help the model understand what you want. Use description liberally.
Test with unusual inputs, missing data, and ambiguous queries. Track failures in Helicone.

Common Issues

Schema Validation Errors

If you see validation errors:

Refusals on Valid Requests

If safe requests are refused:
  1. Review refusal reasons in Helicone
  2. Adjust system prompt to be clearer
  3. Add examples of acceptable requests

Inconsistent Outputs

If outputs vary despite schemas:
  1. Check strict: true is set
  2. Use temperature 0 for deterministic results
  3. Provide clearer field descriptions

Next Steps

Agent Tracing

Build agents with multiple tool calls

Vercel AI Gateway

Add model routing and complexity classification

Custom Properties

Track structured output usage with metadata

OpenAI Docs

Deep dive into OpenAI’s structured outputs