instructor README

The project's README from github.com/567-labs/instructor. As one markdown file: README.md.

Instructor: Structured Outputs for LLMs

Get reliable JSON from any LLM. Built on Pydantic for validation, type safety, and IDE support.

import instructor
from pydantic import BaseModel


# Define what you want
class User(BaseModel):
    name: str
    age: int


# Extract it from natural language
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)

That's it. No JSON parsing, no error handling, no retries. Just define a model and get structured data.

PyPI Downloads GitHub Stars Discord Twitter

Use Instructor for fast extraction, reach for PydanticAI when you need agents. Instructor keeps schema-first flows simple and cheap. If your app needs richer agent runs, built-in observability, or shareable traces, try PydanticAI. PydanticAI is the official agent runtime from the Pydantic team, adding typed tools, replayable datasets, evals, and production dashboards while using the same Pydantic models. Dive into the PydanticAI docs to see how it extends Instructor-style workflows.

Why Instructor?

Getting structured data from LLMs is hard. You need to:

  1. Write complex JSON schemas
  2. Handle validation errors
  3. Retry failed extractions
  4. Parse unstructured responses
  5. Deal with different provider APIs

Instructor handles all of this with one simple interface:

Without Instructor With Instructor
response = openai.chat.completions.create(
    model="gpt-5.4-mini",
    messages=[{"role": "user", "content": "..."}],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "extract_user",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "age": {"type": "integer"},
                    },
                },
            },
        }
    ],
)

# Parse response
tool_call = response.choices[0].message.tool_calls[0]
user_data = json.loads(tool_call.function.arguments)

# Validate manually
if "name" not in user_data:
    # Handle error...
    pass
client = instructor.from_provider("openai/gpt-5.4-mini")

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

# That's it! user is validated and typed

Install in seconds

pip install instructor

Or with your package manager:

uv add instructor
poetry add instructor

Works with every major provider

Use the same code with any LLM provider:

# OpenAI
client = instructor.from_provider("openai/gpt-4o")

# Anthropic
client = instructor.from_provider("anthropic/claude-3-5-sonnet")

# Google
client = instructor.from_provider("google/gemini-pro")

# Ollama (local)
client = instructor.from_provider("ollama/llama3.2")

# With API keys directly (no environment variables needed)
client = instructor.from_provider("openai/gpt-4o", api_key="sk-...")
client = instructor.from_provider("anthropic/claude-3-5-sonnet", api_key="sk-ant-...")
client = instructor.from_provider("groq/llama-3.1-8b-instant", api_key="gsk_...")

# All use the same API!
user = client.chat.completions.create(
    response_model=User,
    messages=[{"role": "user", "content": "..."}],
)

Production-ready features

Automatic retries

Failed validations are automatically retried with the error message:

from pydantic import BaseModel, field_validator


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

    @field_validator('age')
    def validate_age(cls, v):
        if v < 0:
            raise ValueError('Age must be positive')
        return v


# Instructor automatically retries when validation fails
user = client.chat.completions.create(
    response_model=User,
    messages=[{"role": "user", "content": "..."}],
    max_retries=3,
)

Streaming support

Stream partial objects as they're generated:

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)
    # User(name=None, age=None)
    # User(name="John", age=None)
    # User(name="John", age=25)

Nested objects

Extract complex, nested data structures:

from typing import List


class Address(BaseModel):
    street: str
    city: str
    country: str


class User(BaseModel):
    name: str
    age: int
    addresses: List[Address]


# Instructor handles nested objects automatically
user = client.chat.completions.create(
    response_model=User,
    messages=[{"role": "user", "content": "..."}],
)

Used in production by

Trusted by over 100,000 developers and companies building AI applications:

Companies using Instructor include teams at OpenAI, Google, Microsoft, AWS, and many YC startups.

Get started

Basic extraction

Extract structured data from any text:

from pydantic import BaseModel
import instructor

client = instructor.from_provider("openai/gpt-4o-mini")


class Product(BaseModel):
    name: str
    price: float
    in_stock: bool


product = client.chat.completions.create(
    response_model=Product,
    messages=[{"role": "user", "content": "iPhone 15 Pro, $999, available now"}],
)

print(product)
# Product(name='iPhone 15 Pro', price=999.0, in_stock=True)

Multiple languages

Instructor's simple API is available in many languages:

Learn more

Why use Instructor over alternatives?

vs Raw JSON mode: Instructor provides automatic validation, retries, streaming, and nested object support. No manual schema writing.

vs LangChain/LlamaIndex: Instructor is focused on one thing - structured extraction. It's lighter, faster, and easier to debug.

vs Custom solutions: Battle-tested by thousands of developers. Handles edge cases you haven't thought of yet.

Contributing

We welcome contributions! Check out our good first issues to get started.

License

MIT License - see LICENSE for details.


Built by the Instructor community. Special thanks to Jason Liu and all contributors.

instructor (567-labs/instructor)

Searching Database…

这是什么?Instructor 是一个 Python 库,它通过定义 Pydantic 模型,而不是手写 JSON Schema 和解析逻辑,让 LLM 稳定输出结构化的 JSON。
它是一个库,还是完整的智能体框架?它是一个轻量级库,只专注于结构化信息提取,并不是智能体框架。作者明确指出,如果你需要智能体运行时、工具和可观测性等功能,可以去看 PydanticAI。
怎么把它加到项目里?用 pip 安装(或使用你习惯的包管理器),然后定义一个 Pydantic 模型,再调用经 Instructor 包装的 LLM 客户端,就能拿到经过校验的对象。
它支持哪些 LLM 服务商?它可以用同一套代码对接所有主流 LLM 服务商,因为它包装的是各家的客户端,并在其上叠加 Pydantic 校验。
如果 LLM 返回的内容和我的 Schema 对不上,会怎样?Instructor 会自动重试提取,并把校验错误信息反馈给模型,让它自行修正。
这只适用于 Python 项目吗?核心库是 Python 的,但同样的 Instructor 风格 API 也已在 TypeScript、Ruby、Go、Elixir 和 Rust 中实现。
它能在 LLM 生成内容的同时流式返回部分结果吗?可以,Instructor 支持在生成过程中流式返回部分对象,而不必等待完整响应。
它能处理嵌套或复杂的数据结构吗?可以,它支持提取复杂的嵌套对象结构,而不只是扁平字段。
它和 LangChain、LlamaIndex 有什么不同?Instructor 只专注于一件事,即结构化信息提取,因此比 LangChain、LlamaIndex 这类完整的编排框架更轻量、更快,也更容易调试。
它在生产环境中的使用范围有多广?项目方称,该项目拥有超过 10 万名开发者,每月下载量超过 300 万次,GitHub Star 超过 1 万个,并被 OpenAI、Google、Microsoft、AWS 以及多家 YC 初创公司的团队使用。
Creator
567-labs
Size
77.4 MB
Stars
14K
Age
3y
Commits · 90 Days