> ## 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, and for capabilities the CLI doesn't cover, such as monitor views, alerts, and authoring evaluators, preprocessors, and facets.

[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>
