14 KiB
title: Contribute to Instructor: Evals, Issues, and Pull Requests description: Join us in enhancing the Instructor library with evals, report issues, and submit pull requests on GitHub. Collaborate and contribute!
Contributing to Instructor
We welcome contributions to Instructor! This page covers the different ways you can help improve the library.
Ways to Contribute
Evaluation Tests (Evals)
Evals help us monitor the quality of both the OpenAI models and the Instructor library. To contribute:
- Explore Existing Evals: Check out our evals directory
- Create a New Eval: Add new pytest tests that evaluate specific capabilities or edge cases
- Follow the Pattern: Structure your eval similar to existing ones
- Submit a PR: We'll review and incorporate your eval
Evals are run weekly, and results are tracked to monitor performance over time.
Reporting Issues
If you encounter a bug or problem, please file an issue on GitHub with:
- A clear, descriptive title
- Detailed information including:
- The
response_modelyou're using - The
messagesyou sent - The
modelyou're using - Steps to reproduce the issue
- Expected vs. actual behavior
- Your environment details (Python version, OS, package versions)
- The
Contributing Code
We welcome pull requests! Here's the process:
- For Small Changes: Feel free to submit a PR directly
- For Larger Changes: Start with an issue to discuss approach
- Looking for Ideas? Check issues labeled help wanted or good first issue
Setting Up Your Development Environment
Using UV (Recommended)
UV is a fast Python package installer and resolver that makes development easier.
-
Install UV (official method):
# macOS/Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows PowerShell powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" -
Install Project in Development Mode:
# Clone the repository git clone https://github.com/YOUR-USERNAME/instructor.git cd instructor # Install with development dependencies uv pip install -e ".[dev,docs]" -
Adding New Dependencies:
# Add a regular dependency uv pip install some-package # Install a specific version uv pip install "some-package>=1.0.0,<2.0.0" -
Common UV Commands:
# Update UV itself uv self update # Create a requirements file uv pip freeze > requirements.txt
Using Poetry
Poetry provides comprehensive dependency management and packaging.
-
Install Poetry:
curl -sSL https://install.python-poetry.org | python3 - -
Install Dependencies:
# Clone the repository git clone https://github.com/YOUR-USERNAME/instructor.git cd instructor # Install with development dependencies poetry install --with dev,docs -
Working with Poetry:
# Activate virtual environment poetry shell # Run a command in the virtual environment poetry run pytest # Add a dependency poetry add package-name # Add a development dependency poetry add --group dev package-name
Adding Support for New LLM Providers
Instructor uses optional dependencies to support different LLM providers. Provider-specific utilities live in the instructor/utils directory. To add a new provider:
-
Add Dependencies to pyproject.toml:
[project.optional-dependencies] # Add your provider my-provider = ["my-provider-sdk>=1.0.0,<2.0.0"] [dependency-groups] # Mirror in dependency groups my-provider = ["my-provider-sdk>=1.0.0,<2.0.0"] -
Create Provider Client:
- Create a new file at
instructor/clients/client_myprovider.py - Implement
from_myproviderfunction that patches the provider's client
- Create a new file at
-
Add Tests: Create tests in
tests/llm/test_myprovider/ -
Document Installation:
# Installation command for your provider uv pip install "instructor[my-provider]" # or with poetry poetry install --with my-provider -
Create Provider Utilities and Handlers:
- Add
instructor/utils/myprovider.pywithreaskandhandle_*helpers - Define
MYPROVIDER_HANDLERSmappingModevalues to these functions
- Add
-
Register the Provider:
- Update
instructor/utils/providers.pywith your provider enum value - Extend
get_providerdetection for your base URL
- Update
-
Update
process_response.py:- Import your handlers and add them to
mode_handlers - This script uses the handlers to prepare kwargs and parse results
- Import your handlers and add them to
-
Write Documentation:
- Add a new markdown file in
docs/integrations/for your provider - Update
mkdocs.ymlto include your new page - Make sure to include a complete example
- Add a new markdown file in
Development Workflow
- Fork the Repository: Create your own fork of the project
- Clone and Set Up:
git clone https://github.com/YOUR-USERNAME/instructor.git cd instructor git remote add upstream https://github.com/instructor-ai/instructor.git - Create a Branch:
git checkout -b feature/your-feature-name - Make Changes, Test, and Commit:
# Run tests pytest tests/ -k 'not llm and not openai' # Skip LLM tests for faster local dev # Commit changes git add . git commit -m "Your descriptive commit message" - Keep Updated and Push:
git fetch upstream git rebase upstream/main git push origin feature/your-feature-name - Create a Pull Request: Submit your PR with a clear description of changes
Utility Scripts
The scripts/ directory contains utility scripts that help maintain code quality and documentation. These scripts are integrated into pre-commit hooks and can also be run manually.
Available Scripts
make_clean.py - Markdown File Cleaner
Cleans markdown files by removing special whitespace characters and replacing em dashes with regular dashes.
# Clean all markdown files
python scripts/make_clean.py
# Preview changes without modifying files
python scripts/make_clean.py --dry-run
check_blog_excerpts.py - Blog Post Excerpt Validator
Ensures all blog posts contain the <!-- more --> tag for proper excerpt handling.
# Check all blog posts
python scripts/check_blog_excerpts.py
make_sitemap.py - Enhanced Documentation Sitemap Generator
Generates an enhanced sitemap (sitemap.yaml) with AI-powered content analysis and cross-link suggestions.
# Generate sitemap with default settings
python scripts/make_sitemap.py
# Customize settings
python scripts/make_sitemap.py \
--root-dir docs \
--output-file sitemap.yaml \
--max-concurrency 10
Requirements for sitemap generation:
- OpenAI API key (set as
OPENAI_API_KEYenvironment variable) - Additional dependencies:
openai,typer,rich,tenacity,pyyaml
Pre-commit Integration
These scripts run automatically during the commit process:
- Markdown cleaning: Runs on commits with markdown files in
docs/ - Blog excerpt validation: Runs on commits with blog post files
Manual Usage
You can run scripts manually for testing or one-time operations:
# Test markdown cleaning
python scripts/make_clean.py --dry-run
# Check blog excerpts
python scripts/check_blog_excerpts.py
# Generate fresh sitemap
python scripts/make_sitemap.py
For detailed documentation on each script, see the scripts/README.md file in the project repository.
Using Cursor to Build PRs
Cursor is an AI-powered code editor that can help you contribute to Instructor.
-
Getting Started with Cursor:
- Download Cursor from cursor.sh
- Open the Instructor project in Cursor
- Cursor will automatically detect our rules in
.cursor/rules/
-
Using Cursor Rules:
new-features-planning: Helps plan and structure new featuressimple-language: Guidelines for writing clear documentationdocumentation-sync: Ensures documentation stays in sync with code changes
-
Creating PRs with Cursor:
- Use Cursor's Git integration to create a new branch
- Make your changes with AI assistance
- Create a PR with:
# Use GitHub CLI to create the PR gh pr create -t "Your feature title" -b "Description of your changes" -r jxnl,ivanleomk - Add
This PR was written by [Cursor](https://cursor.sh)to your PR description
-
Benefits of Using Cursor:
- AI helps generate code that follows our style guidelines
- Simplifies PR creation process
- Helps maintain documentation standards
Code Style Guidelines
We use the following tools to maintain code quality:
- Ruff: For linting and formatting
- ty: For type checking
- Pre-commit: For automatic checks before committing
# Install pre-commit hooks
pip install pre-commit
pre-commit install
Key style guidelines:
- Use strict typing
- Follow import order: standard lib → third-party → local
- Use snake_case for functions/variables, PascalCase for classes
- Write comprehensive docstrings for public API functions
Conventional Comments
When reviewing code or writing commit messages, we use conventional comments to make feedback clearer:
<label>: <subject>
<description>
Common labels:
- praise: highlights something positive
- suggestion: proposes a change or improvement
- question: asks for clarification
- issue: points out a problem that needs fixing
- todo: notes something to be addressed later
- fix: resolves an issue
Examples:
suggestion: use a validator for this field
This would ensure the value is always properly formatted.
question: why not use async processing here?
I'm curious if this would improve performance.
fix: correct the parameter type
It should be an OpenAI client instance, not a string.
This format helps everyone understand the purpose and importance of each comment. Visit conventionalcomments.org to learn more.
Conventional Commits
We use conventional commit messages to make our project history clear and generate automated changelogs. A conventional commit has this structure:
<type>[optional scope]: <description>
[optional body]
[optional footer]
Common Types
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Formatting changes
- refactor: Code change that neither fixes a bug nor adds a feature
- test: Adding or fixing tests
- chore: Maintenance tasks
Examples
feat(openai): add streaming response support
fix(anthropic): resolve tool calling response format
docs: update installation instructions
test(evals): add new recursive schema test cases
For breaking changes, add an exclamation mark before the colon:
feat(api)!: change return type of from_openai function
Using conventional commits helps automatically generate release notes and makes the project history easier to navigate.
For more details, see the Conventional Commits specification.
Documentation Contributions
Documentation improvements are highly valued:
- Docs Structure: All documentation is in Markdown in the
docs/directory - Adding New Pages: When adding a new page, include it in
mkdocs.ymlin the right section - Local Preview: Run
mkdocs serveto preview changes locally - Style Guidelines:
- Write at a grade 10 reading level (simple, clear language)
- Include working code examples
- Add links to related documentation
- Use consistent formatting
- Make sure each code example is complete with imports
Example of a good documentation code block:
# Complete example with imports
import instructor
from pydantic import BaseModel
# Define your model
class Person(BaseModel):
name: str
age: int
# Create the patched client
client = instructor.from_provider("openai/gpt-5-nano")
# Use the model
person = client.create(
model="gpt-5.4-mini",
response_model=Person,
messages=[
{"role": "user", "content": "Extract: John Doe is 25 years old"}
]
)
print(person.name) # "John Doe"
print(person.age) # 25
Contributors
Documentation Resources
When working on documentation, these resources may be helpful:
-
mkdocs serve: Preview documentation locally. Install dependencies from
requirements-doc.txtfirst. -
hl_lines in Code Blocks: Highlight specific lines in a code block to draw attention:
```python hl_lines="2 3" def example(): # This line is highlighted # This line is also highlighted return "normal line" ``` -
Admonitions: Create styled callout boxes for important information:
!!! note "Optional Title" This is a note admonition. !!! warning This is a warning.
For more documentation features, check the MkDocs Material documentation.
Thank you for your contributions to Instructor!