This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
- Install deps:
uv pip install -e ".[dev,anthropic]"orpoetry install --with dev,anthropic - Run tests:
uv run pytest tests/ - Run specific test:
uv run pytest tests/path_to_test.py::test_name - Skip LLM tests:
uv run pytest tests/ -k 'not llm and not openai' - Type check:
uv run pyright - Lint:
uv run ruff check instructor examples tests - Format:
uv run ruff format instructor examples tests - Generate coverage:
uv run coverage run -m pytest tests/ -k "not docs"thenuv run coverage report - Build documentation:
uv run mkdocs serve(for local preview) or./build_mkdocs.sh(for production)
- Fork the repository and clone your fork
- Install UV:
pip install uv - Create virtual environment:
uv venv - Install dependencies:
uv pip install -e ".[dev]" - Install pre-commit:
uv run pre-commit install - Run tests to verify:
uv run pytest tests/ -k "not openai"
- Typing: Use strict typing with annotations for all functions and variables
- Imports: Standard lib → third-party → local imports
- Formatting: Follow Black's formatting conventions (enforced by Ruff)
- Models: Define structured outputs as Pydantic BaseModel subclasses
- Naming: snake_case for functions/variables, PascalCase for classes
- Error Handling: Use custom exceptions from exceptions.py, validate with Pydantic
- Comments: Docstrings for public functions, inline comments for complex logic
- Format:
type(scope): description - Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
- Examples:
feat(anthropic): add support for Claude 3.5fix(openai): correct response parsing for streamingdocs(README): update installation instructionstest(gemini): add validation tests for JSON mode
- Base Classes:
InstructorandAsyncInstructorin client.py are the foundation - Factory Pattern: Provider-specific factory functions (
from_openai,from_anthropic, etc.) - Unified Access:
from_provider()function in auto_client.py for automatic provider detection - Mode System:
Modeenum categorizes different provider capabilities (tools vs JSON output) - Patching Mechanism: Uses Python's dynamic nature to patch provider clients for structured outputs
- Response Processing: Transforms raw API responses into validated Pydantic models
- DSL Components: Special types like Partial, Iterable, Maybe extend the core functionality
- Supported Providers: OpenAI, Anthropic, Gemini, Cohere, Mistral, Groq, VertexAI, Fireworks, Cerebras, Writer, Databricks, Anyscale, Together, LiteLLM, Bedrock, Perplexity
- Provider Implementation: Each provider has a dedicated client file (e.g.,
client_anthropic.py) with factory functions - Modes: Different providers support specific modes (
Modeenum):ANTHROPIC_TOOLS,GEMINI_JSON, etc. - Common Pattern: Factory functions (e.g.,
from_anthropic) take a native client and return patchedInstructorinstances - Provider Testing: Tests in
tests/llm/directory, define Pydantic models, make API calls, verify structured outputs - Provider Detection:
get_providerfunction analyzes base URL to detect which provider is being used
- process_response.py: Handles parsing and converting LLM outputs to Pydantic models
- patch.py: Contains the core patching logic for modifying provider clients
- function_calls.py: Handles generating function/tool schemas from Pydantic models
- hooks.py: Provides event hooks for intercepting various stages of the LLM request/response cycle
- dsl/: Domain-specific language extensions for specialized model types
- retry.py: Implements retry logic for handling validation failures
- validators.py: Custom validation mechanisms for structured outputs
- Tests are organized by provider under
tests/llm/ - Each provider has its own conftest.py with fixtures
- Standard tests cover: basic extraction, streaming, validation, retries
- Evaluation tests in
tests/llm/test_provider/evals/assess model capabilities - Use parametrized tests when testing similar functionality across variants
- IMPORTANT: No mocking in tests - tests make real API calls
- Every provider needs documentation in
docs/integrations/following standard format - Provider docs should include: installation, basic example, modes supported, special features
- When adding a new provider, update
mkdocs.ymlnavigation and redirects - Example code should include complete imports and environment setup
- Tutorials should progress from simple to complex concepts
- New features should include conceptual explanation in
docs/concepts/ - Writing Style: Grade 10 reading level, all examples must be working code
- Fork and clone the repository
- Create feature branch:
git checkout -b feat/your-feature - Make changes and add tests
- Run tests and linting
- Commit with conventional commit message
- Push to your fork and create PR
- Use stacked PRs for complex features
-
Update Provider Enum in
instructor/utils.py:class Provider(Enum): YOUR_PROVIDER = "your_provider"
-
Add Provider Modes in
instructor/mode.py:class Mode(enum.Enum): YOUR_PROVIDER_TOOLS = "your_provider_tools" YOUR_PROVIDER_JSON = "your_provider_json"
-
Create Client Implementation
instructor/client_your_provider.py:- Use overloads for sync/async variants
- Validate mode compatibility
- Return appropriate Instructor/AsyncInstructor instance
- Handle provider-specific edge cases
-
Add Conditional Import in
instructor/__init__.py:if importlib.util.find_spec("your_provider_sdk") is not None: from .client_your_provider import from_your_provider __all__ += ["from_your_provider"]
-
Update Auto Client in
instructor/auto_client.py:- Add to
supported_providerslist - Implement provider handling in
from_provider() - Update
get_provider()function if URL-detectable
- Add to
-
Create Tests in
tests/llm/test_your_provider/:conftest.pywith client fixtures- Basic extraction tests
- Streaming tests
- Validation/retry tests
- No mocking - use real API calls
-
Add Documentation in
docs/integrations/your_provider.md:- Installation instructions
- Basic usage examples
- Supported modes
- Provider-specific features
-
Update Navigation in
mkdocs.yml:- Add to integrations section
- Include redirects if needed
- Standard evals for each provider test model capabilities
- Create new evals following existing patterns
- Run evals as part of integration test suite
- Performance tracking and comparison
- Keep PRs small and focused
- Include tests for all changes
- Update documentation as needed
- Follow PR template
- Link to relevant issues
- Type Checking Mode: Basic (not strict) for gradual typing adoption
- Python Version: 3.9 for compatibility
- Settings in pyrightconfig.json:
reportMissingImports = "warning"- Missing imports are warningsreportMissingTypeStubs = false- Type stubs optional- Exclusions for certain client files (bedrock, cerebras)
- Run
uv run pyrightbefore committing - zero errors required
- Bounded TypeVars: Use
T = TypeVar("T", bound=Union[BaseModel, ...])for constraints - Version Compatibility: Handle Python 3.9 vs 3.10+ typing differences explicitly
- Union Type Syntax: Use
from __future__ import annotationsto enable Python 3.10+ union syntax (|) in Python 3.9 - Simple Type Detection: Special handling for
list[Union[int, str]]patterns - Runtime Type Handling: Graceful fallbacks for compatibility
- Heavy use of
BaseModelfor structured outputs TypeAdapterused internally for JSON schema generation- Field validators and custom types
- Models serve dual purpose: validation and documentation
# Install documentation dependencies
pip install -r requirements-doc.txt# Serve documentation locally with hot reload
uv run mkdocs serve
# Build documentation for production
./build_mkdocs.sh- Material Theme: Modern UI with extensive customization
- Plugins:
mkdocstrings- API documentation from docstringsmkdocs-jupyter- Notebook integrationmkdocs-redirects- URL management- Custom hooks for code processing
- Custom Processing:
hide_lines.pyremoves code marked with# <%hide%> - Redirect Management: Comprehensive redirect maps for moved content
- Follow templates in
docs/templates/for consistency - Grade 10 reading level for accessibility
- All code examples must be runnable
- Include complete imports and environment setup
- Progressive complexity: simple → advanced
instructor/- Core library code- Base classes (
client.py):InstructorandAsyncInstructor - Provider clients (
client_*.py): Factory functions for each provider - DSL components (
dsl/): Partial, Iterable, Maybe, Citation extensions - Core logic:
patch.py,process_response.py,function_calls.py - CLI tools (
cli/): Batch processing, file management, usage tracking
- Base classes (
tests/- Test suite organized by provider- Provider-specific tests in
tests/llm/test_<provider>/ - Evaluation tests for model capabilities
- No mocking - all tests use real API calls
- Provider-specific tests in
docs/- MkDocs documentationconcepts/- Core concepts and featuresintegrations/- Provider-specific guidesexamples/- Practical examples and cookbookslearning/- Progressive tutorial pathblog/posts/- Technical articles and announcementstemplates/- Templates for new docs (provider, concept, cookbook)
examples/- Runnable code examples- Feature demos: caching, streaming, validation, parallel processing
- Use cases: classification, extraction, knowledge graphs
- Provider examples: anthropic, openai, groq, mistral
- Each example has
run.pyas the main entry point
typings/- Type stubs for untyped dependencies
- Getting Started Path: Installation → First Extraction → Response Models → Structured Outputs
- Learning Patterns: Simple Objects → Lists → Nested Structures → Validation → Streaming
- Example Organization: Self-contained directories with runnable code demonstrating specific features
- Blog Posts: Technical deep-dives with code examples in
docs/blog/posts/
When creating examples:
- Use
run.pyas the main file name - Include clear imports: stdlib → third-party → instructor
- Define Pydantic models with descriptive fields
- Show expected output in comments
- Handle errors appropriately
- Make examples self-contained and runnable
- Minimal core:
openai,pydantic,docstring-parser,typer,rich - Python requirement:
<4.0,>=3.9 - Pydantic version:
<3.0.0,>=2.8.0(constrained for stability)
Provider-specific packages as extras:
# Install with specific provider
pip install "instructor[anthropic]"
pip install "instructor[google-generativeai]"
pip install "instructor[groq]"# Install all development dependencies
uv pip install -e ".[dev]"Includes:
pyright<2.0.0- Type checkingpytestandpytest-asyncio- Testingruff- Linting and formattingcoverage- Test coveragemkdocsand plugins - Documentation
- Upper bounds on all dependencies for stability
- Provider SDK versions pinned to tested versions
- Test dependencies include evaluation frameworks
- Update
pyproject.tomlfor new dependencies - Test with multiple Python versions (3.9-3.12)
- Run full test suite after dependency updates
- Document any provider-specific version requirements
The library enables structured LLM outputs using Pydantic models across multiple providers with type safety.