Instructor

Get validated, typed JSON from any LLM using plain Pydantic models, with automatic retries.

Stars
★ 14k
Last updated
1d ago
License
MIT
Primary language
Python

At a glance

How it runs
Library / SDK
Works with
Universal · cross-platformOpenAI API · Claude API
Cost
Free software; you pay for model usage
Setup effort
Low · running in minutes
You'll need
Pythonpip/uv/poetryPydanticLLM provider API key or local model runtimeShell / CLINetwork access
Typical use
A Python backend engineer extracting names, ages and addresses from support tickets or emails into a database.
Not a fit if
  • Teams expecting a full agent runtime with tools and observability built in
  • Non-Python stacks that cannot adopt Pydantic-based models

What does this agent do, and when should you use it?

Instructor is a Python library that turns free-form LLM responses into Pydantic-validated structured objects. Developers define a BaseModel, create a patched client with instructor.from_provider (covering OpenAI, Anthropic, Google, Ollama and more), and call client.chat.completions.create(response_model=User, messages=[...]) to get a typed instance back. Validation failures are retried automatically with the error message via max_retries, Partial[Model] with stream=True yields progressively filled objects, and nested models are handled recursively. It is MIT-licensed and installed through pip, uv or poetry as a dependency inside your own Python application, not as a standalone server or hosted endpoint.

Instructor reads a caller-defined Pydantic BaseModel and uses it to constrain LLM output. A client is created with instructor.from_provider("openai/gpt-4o-mini"), then client.chat.completions.create(response_model=User, messages=[...]) generates or injects the corresponding schema or function-calling parameters, sends the request, parses the response and constructs the Pydantic instance. When field validators or types fail, it re-requests the model with the error message up to max_retries times. Passing response_model=Partial[User] with stream=True yields objects whose fields fill in incrementally. Nested models such as List[Address] are handled recursively without hand-written JSON Schema.

  1. A Python backend engineer extracting names, ages and addresses from support tickets or emails into a database.
  2. A data team turning unstructured documents into structured records such as product name, price and stock status.
  3. An application developer who wants one extraction code path while switching between OpenAI, Anthropic and Ollama.
  4. A product team streaming partially generated structured objects to a frontend for progressive display.
  5. A quality engineer enforcing Pydantic field rules, such as positive ages, on model output.
  6. A privacy-sensitive project running local models through Ollama so data stays on the internal network.

How do you install or deploy this agent?

You need a Python environment and credentials for the model provider you call. Install with a package manager:

pip install instructor

Or with uv / poetry:

uv add instructor
poetry add instructor

After installation, provide an API key for the chosen provider (for example OPENAI_API_KEY) or run a local model service such as Ollama.

How do you use this agent?

Define a Pydantic model, point from_provider at a provider/model, and pass response_model:

import instructor
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

client = instructor.from_provider("openai/gpt-4o-mini")
user = client.chat.completions.create(
    response_model=User,
    messages=[{"role": "user", "content": "John is 25 years old"}],
)
print(user)  # User(name='John', age=25)

You can pass an API key directly or switch providers:

client = instructor.from_provider("anthropic/claude-3-5-sonnet", api_key="sk-ant-...")
client = instructor.from_provider("ollama/llama3.2")

Enable automatic retries and streaming:

user = client.chat.completions.create(
    response_model=User,
    messages=[{"role": "user", "content": "..."}],
    max_retries=3,
)

from instructor import Partial
for partial_user in client.chat.completions.create(
    response_model=Partial[User],
    messages=[{"role": "user", "content": "..."}],
    stream=True,
):
    print(partial_user)

What are this agent's strengths and limitations?

Pros
  • Pydantic-first design gives type hints, IDE completion and field-level validation for free.
  • Failed validations are retried automatically with the error message, removing hand-written parsing and error handling.
  • The from_provider interface covers OpenAI, Anthropic, Google, Ollama and Groq with the same call shape, making provider switches cheap.
  • Partial[Model] with stream=True yields progressively filled objects for real-time display.
  • Nested models are handled recursively, so complex JSON Schema is not written by hand.
  • MIT-licensed and installable via pip, uv or poetry directly into existing Python projects.
Limitations
  • It is a Python library first; ports for TypeScript, Ruby, Go, Rust and Elixir are separate implementations whose parity must be checked.
  • Real usage depends on an external LLM provider, so you need network access, an API key and per-token spend.
  • The README documents no built-in observability, tool orchestration or eval tooling; richer agent workflows need PydanticAI or custom code.
  • Provider SDK and model-name changes remain the adopter's responsibility to track and adapt.

How does this agent compare with similar options?

The README explicitly contrasts Instructor with three alternatives: raw JSON mode, which lacks automatic validation, retries, streaming and nested-object support; LangChain/LlamaIndex, which Instructor positions as broader and heavier than its focused extraction role; and custom in-house solutions, where it cites battle-testing across many developers and edge cases. It also recommends PydanticAI when you need richer agent runs, built-in observability or shareable traces.

Key facts side by side with the most closely related agents.

Agent Source review Form / cost Stars Updated Language Full support on
Instructor This agent 55 · Major gaps Library / SDKFree + model costs ★ 14k 1d ago Python OpenAI API · Claude API
Adaline Gateway 69 · Some gaps Library / SDKFree + model costs ★ 607 2mo ago TypeScript OpenAI API · Claude API
Pydantic AI 65 · Some gaps Library / SDKFree + model costs ★ 21k today Python OpenAI API · Claude API
Mirascope 55 · Major gaps Library / SDKFree + model costs ★ 1.5k today Python Claude API

How does FollowAgents rate this agent?

FollowAgents source review · FARS-2.1
Major gaps
55/ 100 5-point scale 2.8 / 5
Trust 13/29
Reliability 9/14
Adaptability 10/18
Convention 10/18
Effectiveness 10/13
Verifiability 3/8
Why each dimension lost points
Trust13 / 29 · 2.2/5

Trust: data-flow transparency is moderate — usage.md documents cumulative token accounting, cache hits, and provider billing differences, and cli/usage.md warns about legacy estimates; dependencies are bounded in pyproject.toml. But least_privilege scores 1: the library patches clients and auto-retries by default, README passes api_key in plaintext without key-management guidance. user_confirmation scores 1: auto-retry and cache hits have no explicit confirmation. sensitive_data_handling scores 1: no PII/log redaction guidance. external_effects scores 1: real provider calls incur cost with no cost guardrails. rollback scores 1: no rollback/undo mechanism described. source_attribution scores 2: LICENSE and author/contributor links are clear.

Reliability9 / 14 · 3.2/5

Reliability: self_consistency scores 2 — docs and code structure broadly align, but README and getting-started mix client.create and client.chat.completions.create styles, a minor inconsistency. dependency_availability scores 2 — bounded versions in pyproject.toml and a locked requirements.txt, but no stated vulnerability mitigation. failure_messages scores 2 — docs show IncompleteOutputException and validation-retry feedback, adequate for ordinary use.

Adaptability10 / 18 · 2.8/5

Adaptability: audience_and_scenarios scores 2 — covers multiple providers, multi-language implementations, FastAPI/async. capability_boundaries scores 2 — README explicitly recommends PydanticAI for richer agent runs, a clear boundary. trigger_precision scores 1 — as a library rather than an agent, triggering depends on the caller and docs do not systematically explain when to use which mode. environment_fit scores 2 — declares Python 3.9+ and per-provider extras.

Convention10 / 18 · 2.8/5

Convention: information_architecture scores 2 — clear docs tree. install_notes scores 2 — install and extras well documented. naming_stability scores 1 — README and getting-started mix from_provider with legacy patch/from_openai, and repo URLs differ between 567-labs and jxnl. examples_and_faq scores 2 — rich FAQ and examples. known_limitations scores 2 — usage.md and cli/usage.md explicitly list billing and accumulation limits. license scores 3 — full MIT text. versioning_changelog scores 1 — version in pyproject but no CHANGELOG. maintenance_responsibility scores 1 — maintainer emails listed but publisher identity unverified and update path unclear.

Effectiveness10 / 13 · 3.8/5

Effectiveness: output_usability scores 3 — returns typed Pydantic objects directly. marginal_value scores 2 — clear gain over manual JSON parsing, but competitive space. cost_benefit scores 2 — docs mention token optimization and caching, but auto-retry can amplify cost with no guardrails.

Verifiability3 / 8 · 1.9/5

Verifiability: claim_traceability scores 1 — README claims 3M+ monthly downloads, 10K+ stars, 1000+ contributors, and usage by OpenAI/Google etc., none backed by in-repo evidence. cross_source_corroboration scores 1 — tests exist but were not executed in this static review, so no cross-confirmation. fact_inference_separation scores 1 — marketing claims and factual statements are mixed without clear separation.

Risks and how to mitigate them
  • README claims about downloads, stars, contributor counts, and big-company usage lack in-repo evidence and are marketing statements, not reliability signals.
  • The library auto-retries and patches clients by default, which can amplify API cost; README examples pass api_key in plaintext, so key management and least privilege are the caller's responsibility.
  • Repository URLs differ between 567-labs and jxnl, publisher identity is unverified, and the update/maintenance path is unclear.
  • Docs mix from_provider with legacy patch/from_openai styles; watch naming stability when migrating.
  • This is a static review; no tests were executed, so test quality and determinism are unverified.
Evidence confidence: Low Reviewed Oct 21, 2026 Reviewed revision 6cd771c5254a
See the full review method →

FAQ

Does Instructor cost anything?
Instructor itself is MIT-licensed open source and free to install; cloud model calls to OpenAI, Anthropic and similar providers require your own API key and are billed per usage, while local runtimes such as Ollama avoid that cost.
Which model providers are supported?
The README shows from_provider examples for OpenAI, Anthropic, Google, Ollama and Groq, and supports passing an api_key argument directly instead of relying on environment variables.
What happens when the model output fails Pydantic validation?
Instructor sends the validation error back to the model and re-requests, repeating up to the max_retries value shown in the example (3).
Can it build full agents with tools and tracing?
No. The README positions Instructor as a simple, cheap extraction layer and points to PydanticAI when you need a fuller agent runtime, built-in observability or shareable traces.
How do I get structured objects while streaming?
Set response_model to Partial[User] and pass stream=True; you then iterate over partially filled instances, for example from User(name=None, age=None) to User(name='John', age=25).
View on GitHub ↗ Install ↓

Compare agents like this one

The same FARS review applied across the shortlist this agent qualifies for.

Related agents