CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-instructor

Structured outputs for LLMs with type safety, validation, and automatic retries

Pending
Overview
Eval results
Files

modes-and-configuration.mddocs/

Modes and Configuration

The instructor package provides a comprehensive mode system for configuring how structured extraction works across different LLM providers. Each mode optimizes for specific provider capabilities and use cases.

Mode Enumeration

The Mode enum defines extraction strategies for different providers and scenarios.

from instructor import Mode

class Mode(Enum):
    """
    LLM interaction modes for structured extraction.
    
    Defines how the instructor client should interact with different
    LLM providers to achieve structured output extraction.
    """
    
    # OpenAI Modes
    TOOLS = "tools"
    TOOLS_STRICT = "tools_strict"
    JSON = "json"
    JSON_O1 = "json_o1"
    JSON_SCHEMA = "json_schema"
    MD_JSON = "markdown_json"
    PARALLEL_TOOLS = "parallel_tools"
    FUNCTIONS = "functions"  # Deprecated
    
    # Response API Modes
    RESPONSES_TOOLS = "responses_tools"
    RESPONSES_TOOLS_WITH_INBUILT_TOOLS = "responses_tools_with_inbuilt_tools"
    
    # XAI Modes
    XAI_JSON = "xai_json"
    XAI_TOOLS = "xai_tools"
    
    # Anthropic Modes
    ANTHROPIC_TOOLS = "anthropic_tools"
    ANTHROPIC_JSON = "anthropic_json"
    ANTHROPIC_REASONING_TOOLS = "anthropic_reasoning_tools"
    ANTHROPIC_PARALLEL_TOOLS = "anthropic_parallel_tools"
    
    # Provider-Specific Modes
    MISTRAL_TOOLS = "mistral_tools"
    VERTEXAI_TOOLS = "vertexai_tools" 
    GEMINI_TOOLS = "gemini_tools"
    COHERE_TOOLS = "cohere_tools"
    GROQ_TOOLS = "groq_tools"
    FIREWORKS_TOOLS = "fireworks_tools"
    CEREBRAS_TOOLS = "cerebras_tools"
    WRITER_TOOLS = "writer_tools"
    BEDROCK_TOOLS = "bedrock_tools"
    
    @classmethod
    def tool_modes(cls) -> List['Mode']:
        """
        Get all tool-based modes.
        
        Returns:
            List of modes that use function/tool calling
        """
        
    @classmethod
    def json_modes(cls) -> List['Mode']:
        """
        Get all JSON-based modes.
        
        Returns:
            List of modes that use JSON schema extraction
        """
        
    @classmethod
    def warn_mode_functions_deprecation(cls) -> None:
        """Warn about deprecated FUNCTIONS mode."""

OpenAI Modes

TOOLS Mode (Recommended)

Default and recommended mode for OpenAI models with function calling support.

import instructor
from openai import OpenAI

# Standard tools mode
client = instructor.from_openai(
    OpenAI(), 
    mode=instructor.Mode.TOOLS
)

# Usage
result = client.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Extract user: John, 25, engineer"}],
    response_model=UserProfile
)

Characteristics:

  • Uses OpenAI's function calling API
  • Supports streaming and partial results
  • Best reliability and type safety
  • Compatible with GPT-4, GPT-3.5-turbo, and newer models

TOOLS_STRICT Mode

Strict mode with enhanced schema validation and enforcement.

# Strict tools mode for maximum reliability
client = instructor.from_openai(
    OpenAI(),
    mode=instructor.Mode.TOOLS_STRICT
)

# Enhanced validation and schema enforcement
result = client.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Extract data..."}],
    response_model=StrictModel,
    strict=True  # Enforces strict schema adherence
)

Characteristics:

  • Strict schema validation
  • Enhanced error handling
  • Reduced hallucination in function calls
  • Optimal for production environments

JSON Mode

Direct JSON schema extraction without function calling.

# JSON mode for models without function calling
client = instructor.from_openai(
    OpenAI(),
    mode=instructor.Mode.JSON
)

# Forces JSON response format
result = client.create(
    model="gpt-3.5-turbo-1106",
    messages=[{"role": "user", "content": "Return JSON: user data..."}],
    response_model=UserProfile,
    response_format={"type": "json_object"}
)

Characteristics:

  • Works with models lacking function calling
  • Relies on JSON schema in prompt
  • Less reliable than tools mode
  • Useful for cost optimization

JSON_O1 Mode

Specialized JSON mode optimized for OpenAI O1 models.

# Optimized for O1 models
client = instructor.from_openai(
    OpenAI(),
    mode=instructor.Mode.JSON_O1
)

result = client.create(
    model="o1-preview",
    messages=[{"role": "user", "content": "Analyze and extract..."}],
    response_model=AnalysisResult
)

Characteristics:

  • Optimized for O1 model capabilities
  • Enhanced reasoning integration
  • Specialized prompt formatting
  • Better performance on complex extractions

PARALLEL_TOOLS Mode

Parallel function calling for multiple simultaneous extractions.

# Parallel extraction mode
client = instructor.from_openai(
    OpenAI(),
    mode=instructor.Mode.PARALLEL_TOOLS
)

# Can extract multiple entities in one call
results = client.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Extract all users and products..."}],
    response_model=List[Union[UserProfile, ProductInfo]]
)

Characteristics:

  • Extracts multiple entities simultaneously
  • Improved efficiency for batch operations
  • Requires compatible models
  • Complex result handling

Anthropic Modes

ANTHROPIC_TOOLS Mode

Primary mode for Anthropic models using their tool calling system.

import instructor
from anthropic import Anthropic

# Standard Anthropic tools
client = instructor.from_anthropic(
    Anthropic(),
    mode=instructor.Mode.ANTHROPIC_TOOLS
)

result = client.create(
    model="claude-3-sonnet-20240229",
    messages=[{"role": "user", "content": "Extract information..."}],
    response_model=DataModel
)

Characteristics:

  • Native Anthropic tool integration
  • High reliability and accuracy
  • Supports complex nested structures
  • Optimized for Claude 3+ models

ANTHROPIC_JSON Mode

JSON-based extraction for Anthropic models.

# JSON mode for Anthropic
client = instructor.from_anthropic(
    Anthropic(),
    mode=instructor.Mode.ANTHROPIC_JSON
)

result = client.create(
    model="claude-3-haiku-20240307",
    messages=[{"role": "user", "content": "Return structured data..."}],
    response_model=SimpleModel
)

Characteristics:

  • JSON schema-based extraction
  • Works with all Claude models
  • Cost-effective option
  • Slightly less reliable than tools mode

ANTHROPIC_REASONING_TOOLS Mode

Enhanced mode with reasoning capabilities (beta feature).

# Reasoning tools mode (beta)
client = instructor.from_anthropic(
    Anthropic(),
    mode=instructor.Mode.ANTHROPIC_REASONING_TOOLS,
    beta=True
)

result = client.create(
    model="claude-3-opus-20240229",
    messages=[{"role": "user", "content": "Analyze and extract insights..."}],
    response_model=ReasoningResult,
    reasoning=True
)

Characteristics:

  • Includes reasoning traces
  • Enhanced analytical capabilities
  • Beta feature requiring opt-in
  • Higher token usage

ANTHROPIC_PARALLEL_TOOLS Mode

Parallel tool calling for Anthropic models.

# Parallel tools for Anthropic
client = instructor.from_anthropic(
    Anthropic(),
    mode=instructor.Mode.ANTHROPIC_PARALLEL_TOOLS
)

results = client.create(
    model="claude-3-sonnet-20240229", 
    messages=[{"role": "user", "content": "Extract multiple entities..."}],
    response_model=List[EntityType]
)

Provider-Specific Modes

MISTRAL_TOOLS Mode

Optimized for Mistral AI models with tool calling.

import instructor
from mistralai.client import MistralClient

client = instructor.from_mistral(
    MistralClient(),
    mode=instructor.Mode.MISTRAL_TOOLS
)

result = client.create(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Extract data..."}],
    response_model=DataModel
)

VERTEXAI_TOOLS Mode

Google Vertex AI integration with function calling.

import instructor
from vertexai.preview.generative_models import GenerativeModel

client = instructor.from_vertexai(
    GenerativeModel("gemini-pro"),
    mode=instructor.Mode.VERTEXAI_TOOLS
)

GEMINI_TOOLS Mode

Google Gemini models with function calling support.

import instructor
import google.generativeai as genai

client = instructor.from_genai(
    genai.GenerativeModel("gemini-pro"),
    mode=instructor.Mode.GEMINI_TOOLS
)

Mode Selection Guidelines

By Provider and Model

def select_optimal_mode(provider: str, model: str) -> instructor.Mode:
    """
    Select optimal mode based on provider and model capabilities.
    
    Args:
        provider: LLM provider name
        model: Specific model identifier
        
    Returns:
        Recommended mode for the provider/model combination
    """
    
    if provider == "openai":
        if model.startswith("gpt-4"):
            return instructor.Mode.TOOLS_STRICT
        elif model.startswith("gpt-3.5-turbo"):
            return instructor.Mode.TOOLS
        elif model.startswith("o1"):
            return instructor.Mode.JSON_O1
        else:
            return instructor.Mode.JSON
            
    elif provider == "anthropic":
        if "opus" in model or "sonnet" in model:
            return instructor.Mode.ANTHROPIC_TOOLS
        else:
            return instructor.Mode.ANTHROPIC_JSON
            
    elif provider == "mistral":
        return instructor.Mode.MISTRAL_TOOLS
        
    elif provider == "google":
        if "gemini" in model:
            return instructor.Mode.GEMINI_TOOLS
        else:
            return instructor.Mode.VERTEXAI_TOOLS
    
    # Default fallback
    return instructor.Mode.JSON

# Usage
optimal_mode = select_optimal_mode("openai", "gpt-4-turbo")
client = instructor.from_openai(OpenAI(), mode=optimal_mode)

By Use Case

# Production reliability - use strict modes
production_client = instructor.from_openai(
    OpenAI(),
    mode=instructor.Mode.TOOLS_STRICT
)

# Cost optimization - use JSON modes
cost_optimized_client = instructor.from_openai(
    OpenAI(),
    mode=instructor.Mode.JSON
)

# High throughput - use parallel modes
parallel_client = instructor.from_openai(
    OpenAI(), 
    mode=instructor.Mode.PARALLEL_TOOLS
)

# Complex reasoning - use reasoning modes
reasoning_client = instructor.from_anthropic(
    Anthropic(),
    mode=instructor.Mode.ANTHROPIC_REASONING_TOOLS,
    beta=True
)

Configuration Options

Client Configuration

# Comprehensive client configuration
client = instructor.from_openai(
    OpenAI(
        api_key="your-key",
        base_url="https://custom-endpoint.com",
        timeout=30.0,
        max_retries=3
    ),
    mode=instructor.Mode.TOOLS_STRICT,
    
    # Instructor-specific configuration
    hooks=my_hooks,
    max_validation_retries=2,
    strict_mode=True,
    enable_caching=True
)

Mode-Specific Configuration

# Tools mode with custom settings
tools_config = {
    "strict": True,
    "parallel_tool_calls": False,
    "tool_choice": "auto"
}

client = instructor.from_openai(
    OpenAI(),
    mode=instructor.Mode.TOOLS_STRICT,
    **tools_config
)

# JSON mode with custom settings
json_config = {
    "response_format": {"type": "json_object"},
    "temperature": 0.1,
    "max_tokens": 1000
}

client = instructor.from_openai(
    OpenAI(),
    mode=instructor.Mode.JSON,
    **json_config
)

Dynamic Mode Switching

class AdaptiveClient:
    """Client that adapts mode based on context."""
    
    def __init__(self, base_client):
        self.base_client = base_client
        self.openai_client = instructor.from_openai(base_client)
        
    def create_adaptive(
        self,
        model: str,
        messages: List[Dict],
        response_model: Type[BaseModel],
        prefer_reliability: bool = True,
        **kwargs
    ):
        """Create with adaptive mode selection."""
        
        # Select mode based on context
        if prefer_reliability:
            if "gpt-4" in model:
                mode = instructor.Mode.TOOLS_STRICT
            else:
                mode = instructor.Mode.TOOLS
        else:
            mode = instructor.Mode.JSON
            
        # Recreate client with selected mode
        adaptive_client = instructor.from_openai(
            self.base_client,
            mode=mode
        )
        
        return adaptive_client.create(
            model=model,
            messages=messages,
            response_model=response_model,
            **kwargs
        )

# Usage
adaptive = AdaptiveClient(OpenAI())

# High reliability extraction
result = adaptive.create_adaptive(
    model="gpt-4",
    messages=[{"role": "user", "content": "Critical data..."}],
    response_model=CriticalModel,
    prefer_reliability=True
)

# Cost-optimized extraction
result = adaptive.create_adaptive(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "Simple data..."}],
    response_model=SimpleModel,
    prefer_reliability=False
)

Performance and Reliability

Mode Comparison

ModeReliabilitySpeedCostStreamingParallel
TOOLSHighFastMediumYesNo
TOOLS_STRICTHighestFastMediumYesNo
JSONMediumFastestLowLimitedNo
JSON_O1HighMediumHighNoNo
PARALLEL_TOOLSHighMediumMediumYesYes
ANTHROPIC_TOOLSHighFastMediumYesNo
ANTHROPIC_REASONING_TOOLSHighestSlowHighLimitedNo

Error Handling by Mode

def robust_extraction(
    client,
    model: str,
    messages: List[Dict],
    response_model: Type[BaseModel],
    fallback_modes: List[instructor.Mode] = None
):
    """Extraction with mode fallback on errors."""
    
    if fallback_modes is None:
        fallback_modes = [
            instructor.Mode.TOOLS_STRICT,
            instructor.Mode.TOOLS,
            instructor.Mode.JSON
        ]
    
    last_error = None
    
    for mode in fallback_modes:
        try:
            # Recreate client with current mode
            mode_client = instructor.from_openai(
                client.client,  # Access underlying OpenAI client
                mode=mode
            )
            
            result = mode_client.create(
                model=model,
                messages=messages,
                response_model=response_model
            )
            
            return result, mode
            
        except Exception as e:
            last_error = e
            print(f"Mode {mode} failed: {e}")
            continue
    
    raise RuntimeError(f"All modes failed. Last error: {last_error}")

# Usage with fallback
try:
    result, used_mode = robust_extraction(
        client,
        model="gpt-4",
        messages=[{"role": "user", "content": "Extract..."}],
        response_model=MyModel
    )
    print(f"Success with mode: {used_mode}")
except RuntimeError as e:
    print(f"All extraction attempts failed: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-instructor

docs

batch-processing.md

client-usage.md

dsl-components.md

index.md

modes-and-configuration.md

providers.md

schema-generation.md

validation.md

tile.json