> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Instructor

> Trace Instructor structured-output calls in Braintrust to debug extractions, evaluate models, and monitor retries

If you are a coding agent, prefer the Braintrust [`bt` CLI](/docs/reference/cli/quickstart) for repeatable, scriptable work: running evals, instrumenting code, querying logs, syncing data, managing functions, and configuring coding agents. Use the MCP server for reasoning over Braintrust data in conversation, such as ad-hoc lookups and exploration from your IDE.

[Instructor](https://python.useinstructor.com/) is a Python library for extracting structured, validated data from LLMs using Pydantic models. Braintrust traces each extraction call, including the retries and validation failures Instructor handles under the hood.

<View title="Python" icon="https://img.logo.dev/python.org?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-python">
    Setup
  </h2>

  Install the Braintrust SDK and Instructor alongside your provider SDK:

  ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  pip install braintrust instructor openai
  ```

  Set your API keys before you run your app:

  ```bash title=".env" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  BRAINTRUST_API_KEY=<your-braintrust-api-key>
  OPENAI_API_KEY=<your-openai-api-key>
  ```

  <Note>
    Tracing Instructor requires `instructor` 1.11.0 or later and the Braintrust Python SDK v0.23.0 or later.
  </Note>

  <h2 id="auto-instrumentation-python">
    Auto-instrumentation
  </h2>

  To trace Instructor without wrapping each client, call `init_logger()` and `auto_instrument()` once at startup. `auto_instrument()` patches Instructor's `create` methods along with the underlying provider SDK, so each extraction appears as a task span with the provider's LLM call nested beneath it.

  <CodeGroup>
    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import braintrust
    import instructor
    from openai import OpenAI
    from pydantic import BaseModel

    braintrust.init_logger(project="instructor-example")  # Replace with your project name
    braintrust.auto_instrument()

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

    client = instructor.from_openai(OpenAI(), mode=instructor.Mode.RESPONSES_TOOLS)

    person = client.responses.create(
        model="gpt-5-mini",
        input="Extract: John is 30 years old",
        response_model=Person,
    )
    ```
  </CodeGroup>

  <Accordion title="Instrument only Instructor">
    To patch Instructor without enabling Braintrust's other integrations, wrap the client with `wrap_instructor()` instead. See [Manual instrumentation](#manual-instrumentation-python).
  </Accordion>

  <h2 id="manual-instrumentation-python">
    Manual instrumentation
  </h2>

  To trace Instructor yourself, wrap the Instructor client with `wrap_instructor()`. Wrap the underlying provider client with `wrap_openai()` first so the provider's LLM call is captured as a child of the Instructor span.

  <CodeGroup>
    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import instructor
    from braintrust import init_logger, wrap_instructor, wrap_openai
    from openai import OpenAI
    from pydantic import BaseModel

    init_logger(project="instructor-example")  # Replace with your project name

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

    # Wrap the provider client for the LLM span, then the Instructor client for the task span
    client = wrap_instructor(
        instructor.from_openai(wrap_openai(OpenAI()), mode=instructor.Mode.RESPONSES_TOOLS)
    )

    person = client.responses.create(
        model="gpt-5-mini",
        input="Extract: John is 30 years old",
        response_model=Person,
    )
    ```
  </CodeGroup>

  <h2 id="what-traced-python">
    What Braintrust traces
  </h2>

  Braintrust captures:

  * **Structured-output spans** (`instructor.create`, `instructor.create_with_completion`, `instructor.create_partial`, and `instructor.create_iterable`), with the request messages, response model, and Instructor mode as input, and the extracted Pydantic model as output.
  * **Extraction metadata**, including the model, provider, response model, Instructor mode, and configured max retries.
  * **Retry details**, including the retry count and the Pydantic validation errors that triggered each retry.

  Token usage stays on the provider's LLM child span, so enable provider instrumentation (`wrap_openai()` or `auto_instrument()`) to see token counts alongside the extraction.

  <h2 id="resources-python">
    Resources
  </h2>

  * [Instructor documentation](https://python.useinstructor.com/)
  * [Braintrust OpenAI integration](/docs/integrations/ai-providers/openai)
  * [Trace LLM calls](/docs/instrument/trace-llm-calls)
</View>
