97e91a83f3
Ruff / Ruff (push) Has been cancelled
Test / Core Tests (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.10) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.11) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.12) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.13) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.9) (push) Has been cancelled
Test / Full Coverage (Python 3.11) (push) Has been cancelled
Test / Core Provider Tests (OpenAI) (push) Has been cancelled
Test / Core Provider Tests (Anthropic) (push) Has been cancelled
Test / Core Provider Tests (Google) (push) Has been cancelled
Test / Core Provider Tests (Other) (push) Has been cancelled
Test / Anthropic Tests (push) Has been cancelled
Test / Gemini Tests (push) Has been cancelled
Test / Google GenAI Tests (push) Has been cancelled
Test / Vertex AI Tests (push) Has been cancelled
Test / OpenAI Tests (push) Has been cancelled
Test / Writer Tests (push) Has been cancelled
Test / Auto Client Tests (push) Has been cancelled
ty / type-check (push) Has been cancelled
202 lines
5.3 KiB
Markdown
202 lines
5.3 KiB
Markdown
---
|
|
title: Understanding Response Models in Instructor
|
|
description: Learn how to create response models with Pydantic to define structure, validation rules, and extract complex data from LLMs.
|
|
---
|
|
|
|
# Understanding Response Models
|
|
|
|
Response models are at the core of Instructor's functionality. They define the structure of the data you want to extract and provide validation rules. This guide explains how to create different types of response models for various use cases.
|
|
|
|
## Basic Models
|
|
|
|
Let's start with a simple model similar to what we've seen before:
|
|
|
|
```python
|
|
from pydantic import BaseModel
|
|
|
|
class User(BaseModel):
|
|
name: str
|
|
age: int
|
|
```
|
|
|
|
This defines a model with two required fields: `name` (a string) and `age` (an integer).
|
|
|
|
## Adding Field Metadata
|
|
|
|
You can add metadata to fields using the `Field` class:
|
|
|
|
```python
|
|
from pydantic import BaseModel, Field
|
|
|
|
class WeatherForecast(BaseModel):
|
|
"""Weather forecast for a specific location"""
|
|
|
|
temperature: float = Field(
|
|
description="Current temperature in Celsius"
|
|
)
|
|
condition: str = Field(
|
|
description="Weather condition (sunny, cloudy, rainy, etc.)"
|
|
)
|
|
humidity: int = Field(
|
|
description="Humidity percentage from 0-100"
|
|
)
|
|
```
|
|
|
|
Field descriptions help the LLM understand what information to extract for each field.
|
|
|
|
## Field Validation
|
|
|
|
You can add validation rules to ensure the extracted data meets your requirements:
|
|
|
|
```python
|
|
from pydantic import BaseModel, Field
|
|
|
|
class Product(BaseModel):
|
|
name: str = Field(min_length=3)
|
|
price: float = Field(gt=0) # greater than 0
|
|
quantity: int = Field(ge=0) # greater than or equal to 0
|
|
description: str = Field(max_length=500)
|
|
```
|
|
|
|
Common validation parameters include:
|
|
- `min_length`/`max_length`: For strings
|
|
- `ge`/`gt`/`le`/`lt`: For numbers (greater/less than or equal/than)
|
|
- `pattern`: For regex pattern matching
|
|
|
|
For more on validation, see the [Field Validation](../patterns/field_validation.md) and [Validation Basics](../validation/basics.md) guides.
|
|
|
|
## Nested Models
|
|
|
|
You can create complex data structures with nested models:
|
|
|
|
```python
|
|
from pydantic import BaseModel, Field
|
|
from typing import List, Optional
|
|
|
|
class Address(BaseModel):
|
|
street: str
|
|
city: str
|
|
state: Optional[str] = None
|
|
country: str
|
|
|
|
class User(BaseModel):
|
|
name: str
|
|
age: int
|
|
addresses: List[Address]
|
|
```
|
|
|
|
This allows you to extract hierarchical data structures. For more examples, check out the [Simple Nested Structure](../patterns/nested_structure.md) guide.
|
|
|
|
## Using Enums
|
|
|
|
Enums help when you want to restrict a field to a set of specific values:
|
|
|
|
```python
|
|
from enum import Enum
|
|
from pydantic import BaseModel
|
|
|
|
class UserType(str, Enum):
|
|
ADMIN = "admin"
|
|
REGULAR = "regular"
|
|
GUEST = "guest"
|
|
|
|
class User(BaseModel):
|
|
name: str
|
|
user_type: UserType
|
|
```
|
|
|
|
## Optional Fields
|
|
|
|
For fields that might not be present in the source text:
|
|
|
|
```python
|
|
from typing import Optional
|
|
from pydantic import BaseModel
|
|
|
|
class Contact(BaseModel):
|
|
name: str
|
|
email: str
|
|
phone: Optional[str] = None
|
|
address: Optional[str] = None
|
|
```
|
|
|
|
For more about working with optional fields, see the [Optional Fields](../patterns/optional_fields.md) guide.
|
|
|
|
## Lists and Arrays
|
|
|
|
To extract multiple items of the same type:
|
|
|
|
```python
|
|
from typing import List
|
|
from pydantic import BaseModel
|
|
|
|
class BlogPost(BaseModel):
|
|
title: str
|
|
content: str
|
|
tags: List[str]
|
|
```
|
|
|
|
For more about working with lists, see the [List Extraction](../patterns/list_extraction.md) guide.
|
|
|
|
## Using Your Models with Instructor
|
|
|
|
Once you've defined your model, you can use it for extraction:
|
|
|
|
```python
|
|
import instructor
|
|
client = instructor.from_provider("openai/gpt-5-nano")
|
|
|
|
forecast = client.create(
|
|
model="gpt-5.4-mini",
|
|
response_model=WeatherForecast,
|
|
messages=[
|
|
{"role": "user", "content": "What's the weather in New York today?"}
|
|
]
|
|
)
|
|
|
|
print(forecast.model_dump_json(indent=2))
|
|
```
|
|
|
|
## Model Documentation
|
|
|
|
You can add documentation to your models using docstrings and field descriptions:
|
|
|
|
```python
|
|
from pydantic import BaseModel, Field
|
|
|
|
class Investment(BaseModel):
|
|
"""Represents an investment opportunity with risk and return details."""
|
|
|
|
name: str = Field(description="Name of the investment")
|
|
amount: float = Field(description="Investment amount in USD")
|
|
expected_return: float = Field(description="Expected annual return percentage")
|
|
risk_level: str = Field(description="Risk level (low, medium, high)")
|
|
```
|
|
|
|
This documentation helps both the LLM understand what to extract and makes your code more maintainable.
|
|
|
|
## Advanced Validation with Validators
|
|
|
|
For more complex validation rules, you can use validator methods:
|
|
|
|
```python
|
|
from pydantic import BaseModel, Field, field_validator
|
|
from datetime import date
|
|
|
|
class Reservation(BaseModel):
|
|
check_in: date
|
|
check_out: date
|
|
guests: int = Field(ge=1)
|
|
|
|
@field_validator("check_out")
|
|
def check_dates(cls, v, values):
|
|
if "check_in" in values.data and v <= values.data["check_in"]:
|
|
raise ValueError("check_out must be after check_in")
|
|
return v
|
|
```
|
|
|
|
For more advanced validation techniques, check out the [Custom Validators](../validation/custom_validators.md) guide.
|
|
|
|
## Next Steps
|
|
|
|
In the next section, learn about [from_provider](../../concepts/from_provider.md) to configure different LLM providers and understand the various modes of operation. |