chore: import upstream snapshot with attribution
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

This commit is contained in:
wehub-resource-sync
2026-07-13 13:36:38 +08:00
commit 97e91a83f3
978 changed files with 159975 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
---
title: LLM Validation Basics with Instructor
description: Master the fundamentals of validating LLM outputs to ensure reliable, business-compliant structured data from GPT-4, Claude, and other models.
---
# LLM Validation Tutorial: Ensure Data Quality with Instructor
Master the fundamentals of validating LLM outputs in this comprehensive tutorial. Learn how to use Instructor's validation system to ensure GPT-4, Claude, and other language models produce reliable, business-compliant structured data.
## Why LLM Output Validation is Critical
When extracting structured data from LLMs, validation ensures:
1. **Data Integrity**: LLM outputs contain all required fields with correct formats
2. **Business Compliance**: Extracted data adheres to your domain rules and constraints
3. **Production Reliability**: LLM responses meet quality standards before entering your system
```
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ LLM │ -> │ Instructor │ -> │ Validated │
│ Generates │ │ Validates │ │ Structured │
│ Response │ │ Structure │ │ Data │
└─────────────┘ └──────────────┘ └─────────────┘
│ If validation fails
┌─────────────┐
│ Retry with │
│ Feedback │
└─────────────┘
```
## Basic LLM Validation Example
See how Instructor validates LLM outputs automatically:
```python
from pydantic import BaseModel, Field
import instructor
# Define validation rules for LLM extraction
class UserProfile(BaseModel):
name: str
age: int = Field(ge=13, description="User's age in years")
# Extract and validate LLM output
client = instructor.from_provider("openai/gpt-5-nano")
response = client.create(
model="gpt-5.4-mini", # Works with GPT-4, Claude, Gemini
messages=[
{"role": "user", "content": "My name is Jane Smith and I'm 25 years old."}
],
response_model=UserProfile # Automatic validation
)
print(f"User: {response.name}, Age: {response.age}")
```
Key validation features in this LLM tutorial:
- **Constraint Validation**: Age must be ≥ 13 years
- **Automatic Retry**: If LLM output fails validation, Instructor retries with error context
- **Type Safety**: Ensures LLM returns proper data types
## Essential LLM Validation Patterns
Common validation rules for LLM outputs:
| Validation | Example | What It Does |
|------------|---------|-------------|
| Type checking | `age: int` | Ensures value is an integer |
| Required fields | `name: str` | Field must be present |
| Optional fields | `middle_name: Optional[str] = None` | Field can be missing |
| Minimum value | `age: int = Field(ge=18)` | Value must be ≥ 18 |
| Maximum value | `rating: float = Field(le=5.0)` | Value must be ≤ 5.0 |
| String length | `username: str = Field(min_length=3)` | String must be at least 3 chars |
## How LLM Output Validation Works
The LLM validation pipeline in Instructor:
1. **LLM Generation**: Language model produces structured output
2. **Schema Matching**: Instructor maps LLM response to your Pydantic model
3. **Validation Check**: Pydantic validates against defined constraints
4. **Smart Retry**: On failure, errors are sent back to the LLM with context
5. **Success or Timeout**: Process continues until valid output or retry limit
## Enhance LLM Validation with Custom Messages
Guide LLMs with specific error messages for better corrections:
```python
from pydantic import BaseModel, Field
class Product(BaseModel):
name: str
price: float = Field(
gt=0,
description="Product price in USD",
json_schema_extra={"error_msg": "Price must be greater than zero"}
)
```
## Common LLM Validation Use Cases
- **Age Verification**: Ensure extracted ages meet minimum requirements
- **Price Validation**: Verify LLM-extracted prices are positive numbers
- **Email Format**: Validate email addresses from unstructured text
- **Date Constraints**: Ensure dates are within valid ranges
- **Business Rules**: Enforce domain-specific constraints on LLM outputs
## Continue Your LLM Validation Journey
- **[Custom Validators](custom_validators.md)** - Build complex validation logic for LLM outputs
- **[Retry Mechanisms](retry_mechanisms.md)** - Configure how Instructor handles validation failures
- **[Field-Level Validation](field_level_validation.md)** - Validate individual fields in LLM responses
Master validation to ensure your LLM applications produce reliable, production-ready data!
@@ -0,0 +1,220 @@
---
title: Custom Validators for LLM Outputs
description: Learn to build custom validators for LLM outputs using rule-based and semantic validation techniques with Instructor.
---
# Custom LLM Validators Tutorial: Advanced Data Quality Control
Learn how to build custom validators for LLM outputs in this advanced tutorial. Master both rule-based and semantic validation techniques to ensure GPT-4, Claude, and other language models produce data that meets your exact requirements.
## Basic Custom Validator
Custom validators are functions that validate field values and can be applied using Pydantic's field validators.
```python
from pydantic import BaseModel, field_validator
import instructor
# Initialize the client
client = instructor.from_provider("openai/gpt-5-nano")
class Person(BaseModel):
name: str
age: int
@field_validator('age')
@classmethod
def validate_age(cls, value):
if value < 0 or value > 120:
raise ValueError("Age must be between 0 and 120")
return value
# Extract data with validation
response = client.create(
model="gpt-5.4-mini",
messages=[
{"role": "user", "content": "The person's name is John and they are 150 years old."}
],
response_model=Person
)
```
If the model returns an age outside the valid range, Instructor will retry the request with specific feedback about the validation failure.
For more information on how Instructor handles validation and retries, see [Validation Basics](../../concepts/validation.md) and the [Retrying](../../concepts/retrying.md) concepts page.
## Complex Validation
You can create more complex validators that check multiple fields or have conditional logic:
```python
from pydantic import BaseModel, field_validator, model_validator
import instructor
from typing import List, Optional
from datetime import date
client = instructor.from_provider("openai/gpt-5-nano")
class Employee(BaseModel):
name: str
hire_date: date
termination_date: Optional[date] = None
skills: List[str]
@field_validator('skills')
@classmethod
def validate_skills(cls, skills):
if len(skills) < 1:
raise ValueError("Employee must have at least one skill")
return skills
@model_validator(mode='after')
def validate_dates(self):
if self.termination_date and self.termination_date < self.hire_date:
raise ValueError("Termination date cannot be before hire date")
return self
```
For more advanced validation approaches, check out [Field-level Validation](../../concepts/fields.md) and the [Validators](../../concepts/reask_validation.md) concepts page.
## Handling Complex Data Types
Custom validators can also process more complex data types and perform transformations:
```python
from pydantic import BaseModel, field_validator
import instructor
import re
client = instructor.from_provider("openai/gpt-5-nano")
class Contact(BaseModel):
name: str
email: str
phone: str
@field_validator('email')
@classmethod
def validate_email(cls, value):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
if not re.match(pattern, value):
raise ValueError("Invalid email format")
return value
@field_validator('phone')
@classmethod
def validate_phone(cls, value):
# Remove non-digit characters and validate
digits_only = re.sub(r'\D', '', value)
if len(digits_only) < 10:
raise ValueError("Phone number must have at least 10 digits")
return digits_only # Return the cleaned version
```
For a practical example of extraction with validation, see the [Contact Information Extraction](../../examples/extract_contact_info.md) example.
## Using External Services for Validation
You can also use external services or APIs for validation:
```python
from pydantic import BaseModel, field_validator
import instructor
import requests
client = instructor.from_provider("openai/gpt-5-nano")
class Address(BaseModel):
street: str
city: str
state: str
zip_code: str
@field_validator('zip_code')
@classmethod
def validate_zip_code(cls, value):
# Example of validation using an external service (simplified)
# In a real app, you might use a postal code validation API
if not (value.isdigit() and len(value) == 5):
raise ValueError("Zip code must be 5 digits")
return value
```
## Semantic Validation with LLMs
For complex validation scenarios where rule-based validation is difficult, Instructor provides semantic validation capabilities using LLMs via the `llm_validator` function. For a comprehensive guide on this topic, see the dedicated [Semantic Validation](../../concepts/semantic_validation.md) page:
```python
from typing import Annotated
from pydantic import BaseModel, BeforeValidator
import instructor
from instructor import llm_validator
client = instructor.from_provider("openai/gpt-5-nano")
class ProductDescription(BaseModel):
product_name: str
description: Annotated[
str,
BeforeValidator(
llm_validator(
"The description must be professional, accurate, and free of hyperbole. "
"It should not make unsubstantiated claims or use superlatives excessively.",
client=client
)
)
]
# This would fail validation because it uses excessive hyperbole
try:
product = ProductDescription(
product_name="SuperClean 3000",
description="The absolute BEST cleaning product in the world! Will change your life FOREVER! Makes every other cleaning product completely OBSOLETE!"
)
except ValueError as e:
print(e) # The validation error would explain the issue with the hyperbolic language
```
Semantic validation is particularly useful for validating against criteria that are:
1. **Subjective** - Such as tone, style, or appropriateness
2. **Contextual** - Requiring understanding of relationships between elements
3. **Complex** - Where multiple interrelated factors need to be evaluated together
4. **Hard to formalize** - When rules would be too numerous or complex to express programmatically
Unlike rule-based validators that check against predefined criteria, semantic validators leverage LLMs to evaluate content based on natural language instructions. They can understand nuance and context in ways that traditional validation cannot.
### When to Use Semantic Validation
Consider using semantic validation when:
- You need to enforce style guidelines or content policies
- Validating natural language content against subjective criteria
- Checking for consistency across multiple fields or complex relationships
- Traditional validation would require hundreds of individual rules
Remember that semantic validation requires additional API calls, which adds cost and latency to your application. Use it strategically for high-value validation needs rather than for simple constraints that can be handled with standard validators.
## Handling Validation Failures
When validation fails, Instructor can handle it in different ways. Learn more about:
- [Retry Mechanisms](../../concepts/retrying.md) for automatic retries with feedback
- [Self-Correction](../../examples/self_critique.md) for AI model self-correction techniques
## Best Practices for Custom Validators
1. **Be specific in error messages**: Provide clear error messages that explain exactly what went wrong
2. **Validate early**: Apply validators to individual fields when possible before model-level validation
3. **Keep validators focused**: Each validator should have a single responsibility
4. **Use type hints**: Proper type hints help both Pydantic and Instructor understand your data better
5. **Consider both validation and transformation**: Validators can both validate and transform data
6. **Choose appropriate validation type**: Use rule-based validation for simple, objective criteria and semantic validation for complex, subjective, or context-dependent validation
7. **Balance cost and benefits**: Consider the additional cost and latency of semantic validation against the value it provides
For more information on validation in general, check out the [Validation](../../concepts/validation.md) concepts page.
## Related Resources
- [Fields](../../concepts/fields.md) - Learn about field definitions and properties
- [Models](../../concepts/models.md) - Understand model creation and configuration
- [Types](../../concepts/types.md) - Explore the different data types you can use
Custom validators are a powerful way to ensure the data you extract meets your specific requirements, improving the reliability and quality of structured outputs from LLMs.
@@ -0,0 +1,128 @@
---
title: Field-level Validation with Instructor
description: Learn how to create specific validation rules for individual fields in your Pydantic models to ensure data quality.
---
# Field-level Validation
Field-level validation lets you create specific rules for individual fields in your data models. This guide shows how to use field-level validation with Instructor.
## What is Field-level Validation?
Field-level validation in Instructor uses Pydantic's validation features to:
1. Check individual fields with custom rules
2. Transform field values (like formatting or cleaning data)
3. Apply business rules to specific fields
4. Give clear feedback when values are invalid
Validation happens when your model is being processed, and if it fails, Instructor will retry with better instructions.
## Basic Field Validation
You can apply simple validation using Pydantic's Field constraints:
```python
from pydantic import BaseModel, Field
import instructor
client = instructor.from_provider("openai/gpt-5-nano")
class User(BaseModel):
name: str = Field(..., min_length=2, description="User's full name")
age: int = Field(..., ge=18, le=120, description="User's age in years")
email: str = Field(
...,
pattern=r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
description="Valid email address"
)
```
For more details, see the [Fields](../../concepts/fields.md) concepts page.
## Custom Field Validators
For more complex rules, use the `field_validator` decorator:
```python
from pydantic import BaseModel, field_validator
import instructor
import re
client = instructor.from_provider("openai/gpt-5-nano")
class Product(BaseModel):
name: str
sku: str
price: float
@field_validator('name')
@classmethod
def validate_name(cls, v):
if len(v.strip()) < 3:
raise ValueError("Product name must be at least 3 characters long")
return v.strip().title() # Clean up and format
@field_validator('sku')
@classmethod
def validate_sku(cls, v):
pattern = r'^[A-Z]{3}-\d{4}$'
if not re.match(pattern, v):
raise ValueError("SKU must be in format XXX-0000 (3 uppercase letters, dash, 4 digits)")
return v
```
## Validating Multiple Fields Together
Sometimes one field's validity depends on other fields. Use `model_validator` for this:
```python
from pydantic import BaseModel, model_validator
import instructor
from datetime import date
client = instructor.from_provider("openai/gpt-5-nano")
class Reservation(BaseModel):
check_in: date
check_out: date
room_type: str
guests: int
@model_validator(mode='after')
def validate_dates(self):
if self.check_out <= self.check_in:
raise ValueError("Check-out date must be after check-in date")
if self.room_type == "Standard" and self.guests > 2:
raise ValueError("Standard rooms can only fit 2 guests")
return self
```
## How Validation Errors Are Handled
When validation fails, Instructor adds error details to help the AI fix the problem:
```
The following errors occurred during validation:
- product_sku: Product not found
- quantity: Quantity must be at least 1
Please fix these errors and ensure the response is valid.
```
## Best Practices
1. **Order matters**: Validators run in the order they're defined
2. **Clear messages**: Write specific error messages
3. **Clean first**: Handle data cleaning before validation
4. **Validate early**: Check fields before model-level validation
5. **Transform wisely**: Field validators can both check and change values
## Related Resources
- [Fields](../../concepts/fields.md) - Basic field properties
- [Custom Validators](../../concepts/reask_validation.md) - Creating custom validation logic
- [Validation Basics](../../concepts/validation.md) - Fundamental validation concepts
- [Retry Mechanisms](../../concepts/retrying.md) - How validation retries work
- [Fallback Strategies](../../concepts/error_handling.md) - Handling persistent validation failures
- [Types](../../concepts/types.md) - Understanding data types in Pydantic models
@@ -0,0 +1,206 @@
# Retry Mechanisms
Retry mechanisms in Instructor handle validation failures by giving the LLM another chance to generate valid responses. This guide explains how retries work and how to customize them for your use case.
## How Retries Work
When validation fails, Instructor:
1. Captures the validation error(s)
2. Formats them as feedback
3. Adds the feedback to the prompt context
4. Asks the LLM to try again with this new information
This creates a feedback loop that helps the LLM correct its output until it produces a valid response.
## Basic Retry Example
Here's a simple example showing retries in action:
```python
import instructor
from pydantic import BaseModel, Field, field_validator
# Initialize the client with max_retries
client = instructor.from_provider(
"openai/gpt-4o",
max_retries=2 # Will try up to 3 times (initial + 2 retries)
)
class Product(BaseModel):
name: str
price: float = Field(..., gt=0)
@field_validator('name')
@classmethod
def validate_name(cls, v):
if len(v) < 3:
raise ValueError("Product name must be at least 3 characters")
return v
# This will automatically retry if validation fails
response = client.create(
model="gpt-5.4-mini",
messages=[
{"role": "user", "content": "Product: Pen, Price: -5"}
],
response_model=Product
)
```
In this example, the initial response will likely fail validation because:
- The price is negative (violating the `gt=0` constraint)
- Instructor will automatically retry with feedback about these issues
For more details on max_retries configuration, see the [Retrying](../../concepts/retrying.md) concepts page.
## Customizing Retry Behavior
You can customize retry behavior when initializing the Instructor client:
```python
import instructor
# Customize retry behavior
client = instructor.from_provider(
"openai/gpt-4o",
max_retries=3, # Maximum number of retries
retry_if_parsing_fails=True, # Retry on JSON parsing failures
throw_error=True # Throw an error if all retries fail
)
```
### Retry Configuration Options
| Option | Description | Default |
|--------|-------------|---------|
| `max_retries` | Maximum number of retry attempts | 0 |
| `retry_if_parsing_fails` | Whether to retry if JSON parsing fails | True |
| `throw_error` | Whether to throw an error if all retries fail | True |
## Handling Retry Failures
When all retries fail, Instructor raises an `InstructorRetryException` that contains comprehensive information about all failed attempts:
```python
from instructor.core.exceptions import InstructorRetryException
try:
response = client.create(
model="gpt-5.4-mini",
messages=[{"role": "user", "content": "Product: Invalid data"}],
response_model=Product,
max_retries=3
)
except InstructorRetryException as e:
print(f"Failed after {e.n_attempts} attempts")
print(f"Total usage: {e.total_usage}")
# New: Access detailed information about each failed attempt
for attempt in e.failed_attempts:
print(f"Attempt {attempt.attempt_number}: {attempt.exception}")
if attempt.completion:
# Analyze the raw completion that failed validation
print(f"Raw response: {attempt.completion}")
```
The `InstructorRetryException` now includes:
- `failed_attempts`: A list of `FailedAttempt` objects containing:
- `attempt_number`: The retry attempt number
- `exception`: The specific exception that occurred
- `completion`: The raw LLM response (when available)
- `n_attempts`: Total number of attempts made
- `total_usage`: Total token usage across all attempts
- `last_completion`: The final failed completion
- `messages`: The conversation history
This comprehensive tracking enables better debugging and analysis of retry patterns.
For more on handling validation failures, see [Fallback Strategies](../../concepts/error_handling.md).
## Error Messages and Feedback
Instructor provides detailed error messages to the LLM during retries:
```
The following errors occurred during validation:
- price: ensure this value is greater than 0
- name: Product name must be at least 3 characters
Please fix these errors and ensure the response is valid.
```
This feedback helps the LLM understand exactly what needs to be fixed.
## Retry Limitations
While retries are powerful, they have some limitations:
1. **Retry Budget**: Each retry consumes tokens and time
2. **Persistent Errors**: Some errors might not be fixable by the LLM
3. **Model Limitations**: Some models may consistently struggle with certain validations
For complex validation scenarios, consider implementing [Custom Validators](custom_validators.md) or [Field-level Validation](field_level_validation.md).
## Advanced Retry Pattern: Progressive Validation
For complex schemas, you can implement a progressive validation pattern:
```python
import instructor
from pydantic import BaseModel, Field
# Initialize with moderate retries
client = instructor.from_provider(
"openai/gpt-4o",
max_retries=2
)
# Basic validation first
class BasicProduct(BaseModel):
name: str
price: float = Field(..., gt=0)
# Advanced validation second
class DetailedProduct(BasicProduct):
description: str = Field(..., min_length=10)
category: str
in_stock: bool
# Two-step extraction with validation
try:
# First get basic fields
basic = client.create(
model="gpt-5.4-mini",
messages=[
{"role": "user", "content": "Product: Mini Pen, Price: $2.50"}
],
response_model=BasicProduct
)
# Then get full details with context from the first step
detailed = client.create(
model="gpt-5.4-mini",
messages=[
{"role": "user", "content": f"Provide more details about {basic.name} which costs ${basic.price}"}
],
response_model=DetailedProduct
)
except Exception as e:
# Handle validation failures
print(f"Validation failed: {e}")
```
## Related Resources
- [Retrying](../../concepts/retrying.md) - Core retry concepts
- [Validation](../../concepts/validation.md) - Main validation documentation
- [Custom Validators](../../concepts/reask_validation.md) - Creating custom validation logic
- [Fallback Strategies](../../concepts/error_handling.md) - Handling persistent validation failures
- [Self Critique](../../examples/self_critique.md) - Example of model self-correction
## Next Steps
- Learn about [Field-level Validation](field_level_validation.md)
- Implement [Custom Validators](custom_validators.md)