Instructor: Structured LLM Outputs for Python Developers

Aug 2, 2025

Introduction

Developers building production AI applications often struggle with the unpredictability of Large Language Model (LLM) outputs. Even when requesting JSON, models frequently return malformed syntax, missing fields, or incorrect data types, forcing developers to write endless boilerplate for parsing and validation. Instructor is a Python library that solves this by providing a type-safe, validated way to extract structured data from any LLM, boasting over 13.5k GitHub stars and 3 million monthly downloads. It replaces the need for manual regex parsing or fragile JSON wrappers by leveraging Pydantic for schema definition and automatic retries.

What Is Instructor?

Instructor is a Python library that enables the extraction of structured, validated data from Large Language Models (LLMs) for developers. Built on top of Pydantic, it allows users to define the desired output schema as a Python class, which Instructor then uses to constrain the LLM’s response and validate the resulting data. It is an open-source project licensed under the MIT License, primarily maintained by Jason Liu and the Instructor community.

The library acts as a thin wrapper around LLM clients (like OpenAI, Anthropic, and Google), patching the client to add a response_model parameter to the chat completion calls. This ensures that the output is not just a string, but a fully typed Pydantic object that can be used immediately in a codebase without further parsing.

Why Instructor Matters

Getting structured data from LLMs is notoriously difficult because models are probabilistic, not deterministic. A model might return a valid JSON object one time and a conversational preamble like “Here is the JSON you requested:” the next, which crashes standard JSON parsers. Instructor removes this friction by abstracting the prompting and parsing logic into a single, declarative schema.

The library’s significance is highlighted by its massive adoption—over 3 million monthly downloads—and its multi-language support (including TypeScript, Go, Ruby, and Rust). By providing a consistent interface across 15+ providers, it prevents vendor lock-in, allowing developers to switch from OpenAI to Anthropic or a local model via Ollama by changing a single line of code.

For engineering teams, this means faster development cycles and higher reliability. Instead of writing custom validation logic for every prompt, developers can rely on Pydantic’s industry-standard validation, ensuring that data pipelines remain stable even as models are updated or swapped.

Key Features

  • Type-Safe Structured Outputs: Uses Pydantic models to define exactly what data is needed, ensuring the LLM returns a validated object rather than a raw string.
  • Automatic Retries: Built-in logic that automatically re-prompts the LLM with the validation error message if the first response fails to match the schema.
  • Multi-Provider Support: Seamlessly integrates with 15+ providers including OpenAI, Anthropic, Google Gemini, Mistral, Cohere, and DeepSeek.
  • Local Model Integration: Full support for running open-source models locally via Ollama, llama-cpp-python, or vLLM for privacy and cost efficiency.
  • Streaming Support: Enables real-time processing of partial responses and lists, allowing users to see data being populated in the UI as it is generated.
  • Nested Schema Support: Allows the definition of complex, nested Pydantic models (models within models) for sophisticated data extraction tasks.
  • IDE Autocompletion: Because it returns Pydantic objects, developers get full type inference and autocompletion in editors like VS Code and PyCharm.
  • Transparent Patching: Patches existing LLM clients without changing their core API, maintaining a familiar developer experience.

How Instructor Compares

Feature Instructor PydanticAI Guardrails AI
Primary Focus Structured Extraction Agent Framework Output Validation
Setup Complexity Very Low Medium High
Provider Agnostic Yes Yes Yes
Automatic Retries Yes Yes Yes
Learning Curve Minimal Moderate Steep

Instructor is designed for developers who need fast, schema-first extraction without the overhead of a full agent framework. While PydanticAI provides a more comprehensive runtime for building complex agents with tools and observability, Instructor remains the superior choice for simple, reliable data extraction. The primary tradeoff is that Instructor is a lightweight wrapper, whereas PydanticAI is a full-fledged framework.

Compared to Guardrails AI, Instructor is significantly easier to set up and maintain. Guardrails often requires a separate .RAIL file or complex XML-like definitions, whereas Instructor uses standard Python classes. This makes Instructor more intuitive for Python developers who are already familiar with Pydantic, reducing the time from prototype to production.

Getting Started: Installation

Instructor can be installed via pip, uv, or poetry. It is compatible with Python 3.9+.

Using pip

pip install instructor

Using uv

uv add instructor

Using poetry

poetry add instructor

Prerequisites: You will need an API key from your chosen LLM provider (e.g., OpenAI, Anthropic, or Google). Set these as environment variables for the easiest integration:

export OPENAI_API_KEY='your-api-key-here'

How to Use Instructor

The core workflow of Instructor involves three simple steps: defining a schema, patching a client, and making a request. First, you define a Pydantic model that represents the data you want to extract. This model acts as the “form” the LLM must fill out.

Next, you use one of Instructor’s from_provider methods to wrap your existing LLM client. This patches the client, adding the response_model argument to the create method. Once the client is patched, you pass your Pydantic model into the response_model parameter during the API call.

Instructor handles the underlying prompting, JSON parsing, and validation. If the LLM returns a response that doesn’t match the schema, Instructor automatically retries the request, sending the validation error back to the LLM to help it correct its own mistake.

Code Examples

Below are examples of how to use Instructor for basic and complex data extraction.

Basic Extraction

This example shows how to extract a person’s name and age from a string of text.

import instructor
from pydantic import BaseModel
from openai import OpenAI

# 1. Define the structure you want
class UserInfo(BaseModel):
    name: str
    age: int

# 2. Patch the OpenAI client
client = instructor.from_openai(OpenAI())

# 3. Extract structured data
user_info = client.chat.completions.create(
    model="gpt-4o-mini",
    response_model=UserInfo,
    messages=[
        {"role": "user", "content": "Extract: John Doe is 30 years old."}
    ],
)

print(user_info.name) # Output: John Doe
print(user_info.age)  # Output: 30

Complex Nested Extraction

This example demonstrates how to extract a list of nested objects, such as a recipe’s ingredients and instructions.

import instructor
from pydantic import BaseModel
from typing import List
from openai import OpenAI

class Ingredient(BaseModel):
    name: str
    amount: str

class Recipe(BaseModel):
    ingredients: List[Ingredient]
    instructions: str

client = instructor.from_openai(OpenAI())

recipe = client.chat.completions.create(
    model="gpt-4o-mini",
    response_model=Recipe,
    messages=[
        {"role": "user", "content": "Write an apple pie recipe"}
    ],
)

print(recipe.ingredients[0].name) # Output: Apple
print(recipe.instructions)

Real-World Use Cases

Instructor is particularly effective in scenarios where LLM outputs must be integrated into a database or an external API.

  • Form Data Extraction: A legal professional can use Instructor to extract specific clauses, dates, and parties from a large set of unstructured PDF contracts, converting them into a structured CSV or database.
  • Customer Support Classification: A support engineer can automate the ticket classification system by extracting the sentiment, priority, and category of an incoming ticket, ensuring it is routed to the appropriate team.
  • Content Generation for APIs: A marketing manager can use Instructor to generate structured product descriptions that match a specific JSON schema required by an e-commerce platform’s API, ensuring zero formatting errors.
  • Local Data Processing: A security researcher can process confidential documents using a local model via Ollama, extracting key entities without the data ever leaving their own infrastructure.

Contributing to Instructor

Instructor is an open-source project that welcomes contributions from the community. Developers can contribute by reporting bugs via GitHub Issues, submitting pull requests for new provider support, or improving the documentation. The project follows standard GitHub flow for contributions.

For those looking to get started, the maintainers often mark issues as good-first-issue to help new contributors find accessible entry points. The project also encourages the creation of “cookbooks” or guest blog posts to show how Instructor is used in real-world applications.

Community and Support

Instructor has a vibrant community of developers. Official support and discussions can be found on the GitHub Discussions tab and the official Discord server. Documentation is available at python.useinstructor.com.

The project is active, with frequent updates and the latest release (v1.15.4) being issued recently. With over 100 contributors, the project is well-maintained and highly stable for production use.

Conclusion

Instructor is the definitive tool for any Python developer who needs reliable, structured data from LLMs. By combining the power of Pydantic with a transparent patching mechanism, it eliminates the a vast majority of the boilerplate associated with LLM data extraction. It is the right choice when you need a lightweight, provider-agnostic library that ensures your AI outputs are lapped into typed objects.

While it is not a full agent framework like PydanticAI, this simplicity is its greatest strength. For developers who want to maintain full control over their prompts and logic while ensuring their data is valid, Instructor is an essential addition to the AI stack.

Star the repo, try the quickstart, and join the community to start building more reliable AI applications.

What is Instructor and what problem does it solve?

Instructor is a Python library that extracts structured, validated data from LLMs using Pydantic models. It solves the problem of unpredictable LLM outputs (like malformed JSON or conversational fluff) by constraining the model’s response to a specific schema and automatically retrying failed requests.

How do I install Instructor?

You can install Instructor using pip by running pip install instructor. You can also use other package managers like uv or poetry, and you can install provider-specific extras (e.g., pip install "instructor[anthropic]") to add support for other LLM providers.

How does Instructor compare to PydanticAI?

Instructor is a lightweight library focused specifically on structured data extraction. PydanticAI is a full agent framework that includes tools for agentic workflows, observability, and production dashboards. Use Instructor for fast, schema-first extraction and PydanticAI for complex AI agents.

Can I use Instructor for local LLMs?

Yes, Instructor supports local models via providers like Ollama, llama-cpp-python, and vLLM. This allows you to extract structured data without sending your data to a proprietary API, making it ideal for privacy-sensitive applications.

Does Instructor support nested Pydantic models?

Yes, Instructor supports complex nested schemas. You can define Pydantic models within other Pydantic models, allowing you to extract sophisticated, hierarchical data structures from natural language.

What license does Instructor use?

Instructor is licensed under the MIT License, which allows for free use, modification, and distribution in commercial and open-source projects.

How does the automatic retry mechanism work?

When a response fails Pydantic validation, Instructor catches the error and sends it back to the LLM in a new prompt. The LLM is then asked to correct the same request based on the validation error, which significantly increases the success rate of structured extraction.

[/et_pb_column] [/et_pb_row]