> ## 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.

# Pydantic AI

> Trace Pydantic AI agents in Braintrust to debug prompts, evaluate models, and monitor production usage

If you are a coding agent, prefer the Braintrust [`bt` CLI](/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.

[Pydantic AI](https://ai.pydantic.dev) is a Python agent framework built on Pydantic. Braintrust traces Pydantic AI agents, including agent runs, the underlying model calls, and tool calls.

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

  Install the Braintrust SDK and Pydantic AI:

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

  <Note>
    Tracing Pydantic AI 2.0 or later requires the Braintrust Python SDK v0.26.0 or later.
  </Note>

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

  To trace Pydantic AI without modifying each agent call, call `init_logger()` and `auto_instrument()` once at startup. `auto_instrument()` patches Pydantic AI's agent and model APIs along with every other supported library.

  <CodeGroup>
    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import braintrust
    from pydantic_ai import Agent

    braintrust.init_logger(project="my-pydantic-project")  # Replace with your project name
    braintrust.auto_instrument()

    # Use agents as normal - they're automatically traced
    agent = Agent("openai:gpt-5-mini", system_prompt="You are a helpful assistant.")
    result = await agent.run("What is the capital of France?")
    ```
  </CodeGroup>

  <Accordion title="Instrument only Pydantic AI">
    To patch Pydantic AI without enabling Braintrust's other integrations, call `setup_pydantic_ai()` instead. It initializes a logger for you when one isn't already active.

    <CodeGroup>
      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      from braintrust.wrappers.pydantic_ai import setup_pydantic_ai
      from pydantic_ai import Agent

      # Initialize Braintrust tracing for Pydantic AI
      setup_pydantic_ai(project_name="my-pydantic-project")

      # Use agents as normal - they're automatically traced
      agent = Agent("openai:gpt-5-mini", system_prompt="You are a helpful assistant.")
      result = await agent.run("What is the capital of France?")
      ```
    </CodeGroup>
  </Accordion>

  <h3 id="tools-streaming-python">
    Tools and streaming
  </h3>

  Tools and streaming responses are traced without extra configuration:

  <CodeGroup>
    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import braintrust
    from pydantic_ai import Agent, ModelSettings

    braintrust.init_logger(project="my-pydantic-project")  # Replace with your project name
    braintrust.auto_instrument()

    agent = Agent(
        "openai:gpt-5-mini",
        model_settings=ModelSettings(max_tokens=500),
    )

    @agent.tool_plain
    def get_weather(city: str) -> str:
        """Get the current weather for a city."""
        return f"22°C and sunny in {city}"

    # Streaming is fully traced, including time-to-first-token
    async with agent.run_stream("What's the weather in Paris?") as result:
        async for text in result.stream_text(delta=True):
            print(text, end="", flush=True)
    ```
  </CodeGroup>

  <h3 id="existing-spans-python">
    Nest under existing spans
  </h3>

  If you already have a Braintrust span context (e.g., from `@traced` or `start_span`), Pydantic AI traces nest under it:

  <CodeGroup>
    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import braintrust
    from pydantic_ai import Agent

    braintrust.init_logger(project="my-pydantic-project")  # Replace with your project name
    braintrust.auto_instrument()

    agent = Agent("openai:gpt-5-mini")

    @braintrust.traced
    async def my_workflow(question: str):
        # Agent traces appear as children of this span
        result = await agent.run(question)
        return result.output
    ```
  </CodeGroup>

  <h2 id="opentelemetry-python">
    OpenTelemetry
  </h2>

  To trace Pydantic AI through an existing OpenTelemetry pipeline, attach a `BraintrustSpanProcessor` and enable Pydantic AI's built-in instrumentation.

  <Steps>
    <Step title="Install packages">
      Install the Braintrust SDK with the OpenTelemetry extra, alongside Pydantic AI:

      ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      pip install "braintrust[otel]" pydantic-ai
      ```
    </Step>

    <Step title="Configure tracing">
      Register the `BraintrustSpanProcessor` with your tracer provider, then call `Agent.instrument_all()` to emit Pydantic AI's instrumentation to Braintrust:

      <CodeGroup>
        ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        from braintrust.otel import BraintrustSpanProcessor
        from opentelemetry import trace
        from opentelemetry.sdk.trace import TracerProvider
        from pydantic_ai import Agent

        provider = TracerProvider()
        trace.set_tracer_provider(provider)
        provider.add_span_processor(BraintrustSpanProcessor())

        Agent.instrument_all()
        ```
      </CodeGroup>
    </Step>
  </Steps>

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

  Braintrust captures:

  * **Agent run spans** (`agent_run`, `agent_run_sync`, `agent_run_stream`, `agent_run_stream_sync`, `agent_to_cli_sync`), with the run input, agent metadata, output, and timing.
  * **Direct model-request spans** (`model_request`, `model_request_sync`), for `pydantic_ai.direct` API calls.
  * **Model call spans** (`chat <model>`), for the underlying LLM calls made during a run.
  * **Tool call spans**, for tools invoked during an agent run.

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

  * [Pydantic AI documentation](https://ai.pydantic.dev)
  * [OpenTelemetry integration](/integrations/sdk-integrations/opentelemetry)
  * [Trace LLM calls](/instrument/trace-llm-calls)
</View>
