Skip to main content
Instructor is a Python library that makes it easy to get structured, validated outputs from LLMs. Instead of parsing raw text responses, you define Pydantic models and Instructor handles the extraction, validation, and type conversion automatically. This guide shows you how to use Instructor with Cerebras’s ultra-fast inference.

Prerequisites

Before you begin, ensure you have:
  • Cerebras API Key - Get a free API key here
  • Python 3.10 or higher - Instructor requires Python 3.10+ for modern typing syntax
  • Basic familiarity with Pydantic - Instructor uses Pydantic models for validation

Why Use Instructor with Cerebras?

Combining Instructor with Cerebras gives you:
  • Type Safety - Define your expected output structure with Pydantic models
  • Automatic Validation - Instructor validates responses and retries if needed
  • Ultra-Fast Inference - Cerebras’s hardware acceleration for rapid structured outputs
  • Developer Experience - Clean, Pythonic API with full IDE support

Configure Instructor

1

Install Instructor with Cerebras support

Install Instructor with the Cerebras Cloud SDK integration. This installs both Instructor and the Cerebras Cloud SDK with all required dependencies.
pip install "instructor[cerebras-cloud-sdk]" python-dotenv
2

Set up your environment variables

Create a .env file in your project directory to store your API key securely. This keeps your credentials out of your code and version control.
CEREBRAS_API_KEY=your-cerebras-api-key-here
Then load it in your Python code:
import os
from dotenv import load_dotenv

load_dotenv()
Never commit your .env file to version control. Add it to your .gitignore file.
3

Initialize the Instructor client

import instructor
from cerebras.cloud.sdk import Cerebras
import os

# Initialize with Cerebras provider
client = instructor.from_cerebras(
    client=Cerebras(
        api_key=os.getenv("CEREBRAS_API_KEY"),
    )
)
4

Define your data model

Create a Pydantic model that describes the structure you want to extract. Instructor will ensure the LLM’s response matches this schema.
from pydantic import BaseModel, Field

class User(BaseModel):
    name: str = Field(description="The person's full name")
    age: int = Field(description="The person's age in years")
    email: str | None = Field(default=None, description="Email address if mentioned")
Pydantic’s Field allows you to add descriptions that help guide the LLM’s extraction.
5

Extract structured data

Now you can make requests and get back validated Pydantic objects instead of raw text. The response is automatically validated and converted to your Pydantic model.
import instructor
from cerebras.cloud.sdk import Cerebras
from pydantic import BaseModel, Field
import os

# Initialize with Cerebras provider
client = instructor.from_cerebras(
    client=Cerebras(
        api_key=os.getenv("CEREBRAS_API_KEY"),
    )
)

class User(BaseModel):
    name: str = Field(description="The person's full name")
    age: int = Field(description="The person's age in years")
    email: str | None = Field(default=None, description="Email address if mentioned")

# Extract structured data from text
user = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {
            "role": "user",
            "content": "Extract: John Smith is 29 years old and can be reached at [email protected]"
        }
    ],
    response_model=User,
)

print(user.name)  # "John Smith"
print(user.age)   # 29
print(user.email) # "[email protected]"
The response_model parameter tells Instructor what structure to extract.

Working with Complex Structures

Instructor excels at extracting nested and complex data structures. Here’s an example with nested models and lists:
from pydantic import BaseModel
import instructor
from cerebras.cloud.sdk import Cerebras
import os

client = instructor.from_cerebras(
    client=Cerebras(
        api_key=os.getenv("CEREBRAS_API_KEY"),
    )
)

class Address(BaseModel):
    street: str
    city: str
    state: str
    zip_code: str

class Person(BaseModel):
    name: str
    age: int
    addresses: list[Address]

# Extract complex nested structure
person = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {
            "role": "user",
            "content": """Extract information: Sarah Johnson, 34, lives at 
            123 Main St, Boston, MA 02101 and has a vacation home at 
            456 Beach Rd, Miami, FL 33101"""
        }
    ],
    response_model=Person,
)

print(f"{person.name} has {len(person.addresses)} addresses")
for addr in person.addresses:
    print(f"  - {addr.city}, {addr.state}")

Async Support

Instructor fully supports async/await for high-performance applications. This is ideal when you need to handle multiple requests concurrently or integrate with async frameworks.
import instructor
import asyncio
import os
from cerebras.cloud.sdk import AsyncCerebras
from pydantic import BaseModel

# Initialize async client
client = instructor.from_cerebras(
    client=AsyncCerebras(
        api_key=os.getenv("CEREBRAS_API_KEY"),
    )
)

class User(BaseModel):
    name: str
    age: int

async def extract_user():
    user = await client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {
                "role": "user",
                "content": "Extract: Alice Williams is 31 years old"
            }
        ],
        response_model=User,
    )
    return user

# Run async function
user = asyncio.run(extract_user())
print(user)

Validation and Retry Logic

Instructor automatically validates responses and can retry if validation fails. This ensures you always get data that matches your schema.
from pydantic import BaseModel, Field, field_validator
import instructor
from cerebras.cloud.sdk import Cerebras
import os

client = instructor.from_cerebras(
    client=Cerebras(
        api_key=os.getenv("CEREBRAS_API_KEY"),
    )
)

class User(BaseModel):
    name: str
    age: int = Field(gt=0, lt=120)  # Age must be between 0 and 120
    
    @field_validator('name')
    @classmethod
    def name_must_be_capitalized(cls, v: str) -> str:
        if not v[0].isupper():
            raise ValueError('Name must start with a capital letter')
        return v

# Instructor will retry if validation fails
user = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {
            "role": "user",
            "content": "Extract: john doe is 25 years old"
        }
    ],
    response_model=User,
    max_retries=3,  # Retry up to 3 times on validation errors
)

print(user.name)  # Will be properly capitalized after retry

Using Different Cerebras Models

Cerebras offers several models optimized for different use cases. Choose the model that best fits your needs:
import instructor
from cerebras.cloud.sdk import Cerebras
from pydantic import BaseModel
import os

class YourModel(BaseModel):
    pass

# For fastest inference (smaller model)
fast_client = instructor.from_cerebras(
    client=Cerebras(api_key=os.getenv("CEREBRAS_API_KEY"))
)
result = fast_client.chat.completions.create(
    model="llama3.1-8b",
    messages=[{"role": "user", "content": "..."}],
    response_model=YourModel,
)

# For most capable responses (larger model)
capable_result = fast_client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "..."}],
    response_model=YourModel,
)

# For balanced performance
balanced_result = fast_client.chat.completions.create(
    model="qwen-3-32b",
    messages=[{"role": "user", "content": "..."}],
    response_model=YourModel,
)

FAQ

If you’re seeing validation errors, check:
  1. Model capability - Smaller models may struggle with complex structures. Try llama-3.3-70b for better accuracy
  2. Field descriptions - Add clear descriptions to your Pydantic fields to guide extraction
  3. Retry limit - Increase max_retries to give the model more attempts
  4. Input clarity - Ensure your prompt clearly describes what to extract
Example with better guidance:
from pydantic import BaseModel, Field

class User(BaseModel):
    name: str = Field(description="Full name in 'First Last' format")
    age: int = Field(description="Age in years as a number", gt=0, lt=120)
Use Python’s union syntax with None to make fields optional:
from pydantic import BaseModel, Field

class User(BaseModel):
    name: str
    age: int
    email: str | None = Field(default=None)  # Optional field
    phone: str | None = None  # Also optional
Instructor will extract these fields if present, or set them to None if not found in the input text.
Use async clients when you need to:
  • Handle multiple requests concurrently
  • Integrate with async frameworks (FastAPI, aiohttp, etc.)
  • Maximize throughput in high-performance applications
Use sync clients for:
  • Simple scripts and notebooks
  • Sequential processing
  • Easier debugging and testing
Both provide the same functionality, just different execution models. Initialize async clients with AsyncCerebras instead of Cerebras.
Instructor automatically retries requests when validation fails. You can control this behavior with the max_retries parameter:
from pydantic import BaseModel, Field, field_validator
import instructor
from cerebras.cloud.sdk import Cerebras
import os

client = instructor.from_cerebras(
    client=Cerebras(
        api_key=os.getenv("CEREBRAS_API_KEY"),
    )
)

class User(BaseModel):
    name: str
    age: int

user = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "Extract: john doe is 25 years old"}],
    response_model=User,
    max_retries=3,  # Try up to 3 times
)
On each retry, Instructor sends the validation error back to the model, allowing it to correct its response. This significantly improves accuracy for complex extractions.

Next Steps