Overview
Instructor is a Python library that makes it easy to get structured outputs from LLMs using Pydantic models. It handles prompt engineering, retry logic, and validation automatically, ensuring your LLM outputs match your expected schema. Works with OpenAI, Anthropic, Gemini, and other providers. Ideal for building reliable data extraction and classification pipelines.
Features
- ✓Pydantic-based type-safe structured outputs
- ✓Automatic retry on validation failure
- ✓Support for 10+ LLM providers
- ✓Built-in prompt templates
- ✓Streaming with partial updates
- ✓Async and sync API support
- ✓Custom validation rules
Installation
pip install instructorPros
- +Guaranteed valid structured outputs
- +Simple Pydantic-based API
- +Automatic retry and correction
- +Works with any Pydantic model
- +Excellent for data extraction tasks
Cons
- −Python only
- −Not a full agent framework
- −Requires Pydantic knowledge
- −Some providers have limited support
Alternatives
Documentation
Instructor
Overview
Instructor is a Python library that makes it easy to get structured outputs from LLMs using Pydantic models. Instead of parsing raw text responses, Instructor ensures your LLM outputs match your expected schema through automatic retry, validation, and prompt engineering.
It's the go-to solution for building reliable data extraction, classification, and structured generation pipelines.
Features
- Pydantic-Based Type Safety: Define schemas with Pydantic models
- Automatic Retry: Retries on validation failure with corrected prompts
- Multi-Provider Support: OpenAI, Anthropic, Gemini, Cohere, and more
- Built-in Prompt Templates: Pre-built templates for common patterns
- Streaming with Partial Updates: Get partial results as they arrive
- Async and Sync API: Choose based on your needs
- Custom Validation: Leverage Pydantic's validation ecosystem
Installation
pip install instructor
Quick Start
import instructor
from pydantic import BaseModel
from openai import OpenAI
# Patch the OpenAI client
client = instructor.from_openai(OpenAI())
# Define your schema
class UserExtract(BaseModel):
name: str
age: int
email: str | None
interests: list[str]
# Extract structured data
user = client.chat.completions.create(
model="gpt-4o",
response_model=UserExtract,
messages=[
{"role": "user", "content": "John Doe is 30 years old and loves hiking and coding."}
]
)
print(user.name) # "John Doe"
print(user.age) # 30
print(user.interests) # ["hiking", "coding"]
Advanced Features
Nested Models
class Address(BaseModel):
street: str
city: str
zip_code: str
class Person(BaseModel):
name: str
age: int
address: Address
person = client.chat.completions.create(
model="gpt-4o",
response_model=Person,
messages=[
{"role": "user", "content": "Jane Smith, 25, lives at 123 Main St, New York, 10001"}
]
)
Streaming
for chunk in client.chat.completions.create(
model="gpt-4o",
response_model=UserExtract,
messages=[{"role": "user", "content": "Extract user info..."}],
stream=True
):
print(chunk) # Partial results as they arrive
Custom Retries
from instructor import RetryConfig
user = client.chat.completions.create(
model="gpt-4o",
response_model=UserExtract,
messages=[{"role": "user", "content": "..."}],
retries=RetryConfig(
max_retries=5,
backoff_factor=1.0
)
)
Multiple Providers
# Anthropic
from anthropic import Anthropic
client = instructor.from_anthropic(Anthropic())
# Google Gemini
from google import genai
client = instructor.from_google(genai.Client())
# Together AI
from together import Together
client = instructor.from_together(Together())
Use Cases
Data Extraction
class Article(BaseModel):
title: str
summary: str
keywords: list[str]
sentiment: str
article = client.chat.completions.create(
model="gpt-4o",
response_model=Article,
messages=[{"role": "user", "content": news_article_text}]
)
Classification
from enum import Enum
class Sentiment(Enum):
POSITIVE = "positive"
NEGATIVE = "negative"
NEUTRAL = "neutral"
class ReviewAnalysis(BaseModel):
sentiment: Sentiment
confidence: float
reasons: list[str]
analysis = client.chat.completions.create(
model="gpt-4o",
response_model=ReviewAnalysis,
messages=[{"role": "user", "content": review_text}]
)
JSON Mode Alternative
# Instructor provides better reliability than raw JSON mode
user = client.chat.completions.create(
model="gpt-4o",
response_model=UserExtract,
messages=[{"role": "user", "content": "..."}],
mode=instructor.Mode.JSON # or Mode.TOOLS, Mode.MD_JSON
)
Pros
- ✅ Guaranteed valid structured outputs
- ✅ Simple Pydantic-based API
- ✅ Automatic retry and correction
- ✅ Works with any Pydantic model
- ✅ Excellent for data extraction tasks
- ✅ Streaming support for partial results
Cons
- ❌ Python only
- ❌ Not a full agent framework
- ❌ Requires Pydantic knowledge
- ❌ Some providers have limited support
When to Use
- Extracting structured data from unstructured text
- Building classification pipelines
- When you need guaranteed output schemas
- Creating APIs that return structured data
- Data validation and transformation workflows
Use Cases
| Use Case | Why Instructor |
|---|---|
| Data Extraction | Extract structured data from unstructured text reliably |
| Classification Pipelines | Classify text with guaranteed output schemas |
| API Responses | Return validated Pydantic models from APIs |
| Data Validation | Validate and transform data with Pydantic ecosystem |
Comparison with Alternatives
| Feature | Instructor | Guidance | Outlines | Raw JSON Mode |
|---|---|---|---|---|
| Type Safety | ✅ Pydantic | ⚠️ Manual | ⚠️ Manual | ❌ No |
| Automatic Retry | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Streaming | ✅ Yes | ⚠️ Limited | ❌ No | ⚠️ Yes |
| Multi-Provider | ✅ Yes | ✅ Yes | ⚠️ Limited | ✅ Yes |
| Learning Curve | Low | High | Medium | Low |
| Best for | Production extraction | Research/control | Structured output | Quick prototypes |
Best Practices
- Define clear schemas — Use Pydantic models with descriptive field names
- Use nested models — Structure complex data with nested Pydantic models
- Enable retries — Use
RetryConfigfor unreliable models - Stream when possible — Use streaming for faster partial results
- Validate early — Catch validation errors at schema definition time
Troubleshooting
| Issue | Solution |
|---|---|
| Validation fails repeatedly | Simplify schema or increase retry count |
| Streaming returns incomplete data | Use partial updates feature |
| Provider not supported | Check Instructor docs for provider compatibility |
| Slow extraction | Use smaller model for extraction, larger for reasoning |
