instructor


Nameinstructor JSON
Version 1.10.0 PyPI version JSON
download
home_pageNone
Summarystructured outputs for llm
upload_time2025-07-18 15:28:52
maintainerNone
docs_urlNone
authorNone
requires_python<4.0,>=3.9
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            # Instructor: Structured Outputs for LLMs

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

```python
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](https://img.shields.io/pypi/v/instructor?style=flat-square)](https://pypi.org/project/instructor/)
[![Downloads](https://img.shields.io/pypi/dm/instructor?style=flat-square)](https://pypi.org/project/instructor/)
[![GitHub Stars](https://img.shields.io/github/stars/instructor-ai/instructor?style=flat-square)](https://github.com/instructor-ai/instructor)
[![Discord](https://img.shields.io/discord/1192334452110659664?style=flat-square)](https://discord.gg/bD9YE9JArw)
[![Twitter](https://img.shields.io/twitter/follow/jxnlco?style=flat-square)](https://twitter.com/jxnlco)

## 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:**

<table>
<tr>
<td><b>Without Instructor</b></td>
<td><b>With Instructor</b></td>
</tr>
<tr>
<td>

```python
response = openai.chat.completions.create(
    model="gpt-4",
    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
```

</td>
<td>

```python
client = instructor.from_provider("openai/gpt-4")

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

# That's it! user is validated and typed
```

</td>
</tr>
</table>

## Install in seconds

```bash
pip install instructor
```

Or with your package manager:
```bash
uv add instructor
poetry add instructor
```

## Works with every major provider

Use the same code with any LLM provider:

```python
# 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:

```python
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:

```python
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:

```python
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:

- **3M+ monthly downloads**
- **10K+ GitHub stars**  
- **1000+ community contributors**

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

## Get started

### Basic extraction

Extract structured data from any text:

```python
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:

- [Python](https://python.useinstructor.com) - The original
- [TypeScript](https://js.useinstructor.com) - Full TypeScript support
- [Ruby](https://ruby.useinstructor.com) - Ruby implementation  
- [Go](https://go.useinstructor.com) - Go implementation
- [Elixir](https://hex.pm/packages/instructor) - Elixir implementation
- [Rust](https://rust.useinstructor.com) - Rust implementation

### Learn more

- [Documentation](https://python.useinstructor.com) - Comprehensive guides
- [Examples](https://python.useinstructor.com/examples/) - Copy-paste recipes  
- [Blog](https://python.useinstructor.com/blog/) - Tutorials and best practices
- [Discord](https://discord.gg/bD9YE9JArw) - Get help from the community

## 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](https://github.com/instructor-ai/instructor/labels/good%20first%20issue) to get started.

## License

MIT License - see [LICENSE](https://github.com/instructor-ai/instructor/blob/main/LICENSE) for details.

---

<p align="center">
Built by the Instructor community. Special thanks to <a href="https://twitter.com/jxnlco">Jason Liu</a> and all <a href="https://github.com/instructor-ai/instructor/graphs/contributors">contributors</a>.
</p>
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "instructor",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": null,
    "author_email": "Jason Liu <jason@jxnl.co>, Ivan Leo <ivan@jxnl.co>",
    "download_url": "https://files.pythonhosted.org/packages/a5/67/63c4b4d2cc3c7b4238920ad3388a6f5d67265ab7c09ee34012d6b591130e/instructor-1.10.0.tar.gz",
    "platform": null,
    "description": "# Instructor: Structured Outputs for LLMs\n\nGet reliable JSON from any LLM. Built on Pydantic for validation, type safety, and IDE support.\n\n```python\nimport instructor\nfrom pydantic import BaseModel\n\n\n# Define what you want\nclass User(BaseModel):\n    name: str\n    age: int\n\n\n# Extract it from natural language\nclient = instructor.from_provider(\"openai/gpt-4o-mini\")\nuser = client.chat.completions.create(\n    response_model=User,\n    messages=[{\"role\": \"user\", \"content\": \"John is 25 years old\"}],\n)\n\nprint(user)  # User(name='John', age=25)\n```\n\n**That's it.** No JSON parsing, no error handling, no retries. Just define a model and get structured data.\n\n[![PyPI](https://img.shields.io/pypi/v/instructor?style=flat-square)](https://pypi.org/project/instructor/)\n[![Downloads](https://img.shields.io/pypi/dm/instructor?style=flat-square)](https://pypi.org/project/instructor/)\n[![GitHub Stars](https://img.shields.io/github/stars/instructor-ai/instructor?style=flat-square)](https://github.com/instructor-ai/instructor)\n[![Discord](https://img.shields.io/discord/1192334452110659664?style=flat-square)](https://discord.gg/bD9YE9JArw)\n[![Twitter](https://img.shields.io/twitter/follow/jxnlco?style=flat-square)](https://twitter.com/jxnlco)\n\n## Why Instructor?\n\nGetting structured data from LLMs is hard. You need to:\n\n1. Write complex JSON schemas\n2. Handle validation errors  \n3. Retry failed extractions\n4. Parse unstructured responses\n5. Deal with different provider APIs\n\n**Instructor handles all of this with one simple interface:**\n\n<table>\n<tr>\n<td><b>Without Instructor</b></td>\n<td><b>With Instructor</b></td>\n</tr>\n<tr>\n<td>\n\n```python\nresponse = openai.chat.completions.create(\n    model=\"gpt-4\",\n    messages=[{\"role\": \"user\", \"content\": \"...\"}],\n    tools=[\n        {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"extract_user\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"name\": {\"type\": \"string\"},\n                        \"age\": {\"type\": \"integer\"},\n                    },\n                },\n            },\n        }\n    ],\n)\n\n# Parse response\ntool_call = response.choices[0].message.tool_calls[0]\nuser_data = json.loads(tool_call.function.arguments)\n\n# Validate manually\nif \"name\" not in user_data:\n    # Handle error...\n    pass\n```\n\n</td>\n<td>\n\n```python\nclient = instructor.from_provider(\"openai/gpt-4\")\n\nuser = client.chat.completions.create(\n    response_model=User,\n    messages=[{\"role\": \"user\", \"content\": \"...\"}],\n)\n\n# That's it! user is validated and typed\n```\n\n</td>\n</tr>\n</table>\n\n## Install in seconds\n\n```bash\npip install instructor\n```\n\nOr with your package manager:\n```bash\nuv add instructor\npoetry add instructor\n```\n\n## Works with every major provider\n\nUse the same code with any LLM provider:\n\n```python\n# OpenAI\nclient = instructor.from_provider(\"openai/gpt-4o\")\n\n# Anthropic\nclient = instructor.from_provider(\"anthropic/claude-3-5-sonnet\")\n\n# Google\nclient = instructor.from_provider(\"google/gemini-pro\")\n\n# Ollama (local)\nclient = instructor.from_provider(\"ollama/llama3.2\")\n\n# With API keys directly (no environment variables needed)\nclient = instructor.from_provider(\"openai/gpt-4o\", api_key=\"sk-...\")\nclient = instructor.from_provider(\"anthropic/claude-3-5-sonnet\", api_key=\"sk-ant-...\")\nclient = instructor.from_provider(\"groq/llama-3.1-8b-instant\", api_key=\"gsk_...\")\n\n# All use the same API!\nuser = client.chat.completions.create(\n    response_model=User,\n    messages=[{\"role\": \"user\", \"content\": \"...\"}],\n)\n```\n\n## Production-ready features\n\n### Automatic retries\n\nFailed validations are automatically retried with the error message:\n\n```python\nfrom pydantic import BaseModel, field_validator\n\n\nclass User(BaseModel):\n    name: str\n    age: int\n\n    @field_validator('age')\n    def validate_age(cls, v):\n        if v < 0:\n            raise ValueError('Age must be positive')\n        return v\n\n\n# Instructor automatically retries when validation fails\nuser = client.chat.completions.create(\n    response_model=User,\n    messages=[{\"role\": \"user\", \"content\": \"...\"}],\n    max_retries=3,\n)\n```\n\n### Streaming support\n\nStream partial objects as they're generated:\n\n```python\nfrom instructor import Partial\n\nfor partial_user in client.chat.completions.create(\n    response_model=Partial[User],\n    messages=[{\"role\": \"user\", \"content\": \"...\"}],\n    stream=True,\n):\n    print(partial_user)\n    # User(name=None, age=None)\n    # User(name=\"John\", age=None)\n    # User(name=\"John\", age=25)\n```\n\n### Nested objects\n\nExtract complex, nested data structures:\n\n```python\nfrom typing import List\n\n\nclass Address(BaseModel):\n    street: str\n    city: str\n    country: str\n\n\nclass User(BaseModel):\n    name: str\n    age: int\n    addresses: List[Address]\n\n\n# Instructor handles nested objects automatically\nuser = client.chat.completions.create(\n    response_model=User,\n    messages=[{\"role\": \"user\", \"content\": \"...\"}],\n)\n```\n\n## Used in production by\n\nTrusted by over 100,000 developers and companies building AI applications:\n\n- **3M+ monthly downloads**\n- **10K+ GitHub stars**  \n- **1000+ community contributors**\n\nCompanies using Instructor include teams at OpenAI, Google, Microsoft, AWS, and many YC startups.\n\n## Get started\n\n### Basic extraction\n\nExtract structured data from any text:\n\n```python\nfrom pydantic import BaseModel\nimport instructor\n\nclient = instructor.from_provider(\"openai/gpt-4o-mini\")\n\n\nclass Product(BaseModel):\n    name: str\n    price: float\n    in_stock: bool\n\n\nproduct = client.chat.completions.create(\n    response_model=Product,\n    messages=[{\"role\": \"user\", \"content\": \"iPhone 15 Pro, $999, available now\"}],\n)\n\nprint(product)\n# Product(name='iPhone 15 Pro', price=999.0, in_stock=True)\n```\n\n### Multiple languages\n\nInstructor's simple API is available in many languages:\n\n- [Python](https://python.useinstructor.com) - The original\n- [TypeScript](https://js.useinstructor.com) - Full TypeScript support\n- [Ruby](https://ruby.useinstructor.com) - Ruby implementation  \n- [Go](https://go.useinstructor.com) - Go implementation\n- [Elixir](https://hex.pm/packages/instructor) - Elixir implementation\n- [Rust](https://rust.useinstructor.com) - Rust implementation\n\n### Learn more\n\n- [Documentation](https://python.useinstructor.com) - Comprehensive guides\n- [Examples](https://python.useinstructor.com/examples/) - Copy-paste recipes  \n- [Blog](https://python.useinstructor.com/blog/) - Tutorials and best practices\n- [Discord](https://discord.gg/bD9YE9JArw) - Get help from the community\n\n## Why use Instructor over alternatives?\n\n**vs Raw JSON mode**: Instructor provides automatic validation, retries, streaming, and nested object support. No manual schema writing.\n\n**vs LangChain/LlamaIndex**: Instructor is focused on one thing - structured extraction. It's lighter, faster, and easier to debug.\n\n**vs Custom solutions**: Battle-tested by thousands of developers. Handles edge cases you haven't thought of yet.\n\n## Contributing\n\nWe welcome contributions! Check out our [good first issues](https://github.com/instructor-ai/instructor/labels/good%20first%20issue) to get started.\n\n## License\n\nMIT License - see [LICENSE](https://github.com/instructor-ai/instructor/blob/main/LICENSE) for details.\n\n---\n\n<p align=\"center\">\nBuilt by the Instructor community. Special thanks to <a href=\"https://twitter.com/jxnlco\">Jason Liu</a> and all <a href=\"https://github.com/instructor-ai/instructor/graphs/contributors\">contributors</a>.\n</p>",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "structured outputs for llm",
    "version": "1.10.0",
    "project_urls": {
        "repository": "https://github.com/instructor-ai/instructor"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2cfbffc1ade9779795a8dc8e2379b1bfb522161ee7df8df12722f50d348fb4ea",
                "md5": "89f20daec5a8c591a61c8a985e91e63a",
                "sha256": "9c789f0fce915d5498059afb5314530c8a5b22b0283302679148ddae98f732b0"
            },
            "downloads": -1,
            "filename": "instructor-1.10.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "89f20daec5a8c591a61c8a985e91e63a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.9",
            "size": 119455,
            "upload_time": "2025-07-18T15:28:48",
            "upload_time_iso_8601": "2025-07-18T15:28:48.785784Z",
            "url": "https://files.pythonhosted.org/packages/2c/fb/ffc1ade9779795a8dc8e2379b1bfb522161ee7df8df12722f50d348fb4ea/instructor-1.10.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a56763c4b4d2cc3c7b4238920ad3388a6f5d67265ab7c09ee34012d6b591130e",
                "md5": "367aa6ca185793ebdbdb8f4a50d9d949",
                "sha256": "887d33e058b913290dbf526b0096b1bb8d7ea1a07d75afecbf716161f959697b"
            },
            "downloads": -1,
            "filename": "instructor-1.10.0.tar.gz",
            "has_sig": false,
            "md5_digest": "367aa6ca185793ebdbdb8f4a50d9d949",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.9",
            "size": 69388981,
            "upload_time": "2025-07-18T15:28:52",
            "upload_time_iso_8601": "2025-07-18T15:28:52.386517Z",
            "url": "https://files.pythonhosted.org/packages/a5/67/63c4b4d2cc3c7b4238920ad3388a6f5d67265ab7c09ee34012d6b591130e/instructor-1.10.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-18 15:28:52",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "instructor-ai",
    "github_project": "instructor",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "lcname": "instructor"
}
        
Elapsed time: 1.12906s