> ## 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="tracing-python">
    Tracing
  </h2>

  To trace Pydantic AI with Braintrust's Python SDK, use auto-instrumentation or attach Braintrust to Pydantic AI's built-in OpenTelemetry instrumentation. Auto-instrumentation is the recommended path for most users.

  <Tabs>
    <Tab title="Auto-instrumentation">
      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.

      <h3 id="setup-python-auto">
        Setup
      </h3>

      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>

      <h3 id="auto-instrumentation-python">
        Trace your application
      </h3>

      Call `init_logger()` and `auto_instrument()` at startup. Pydantic AI agents and direct API calls are then traced automatically:

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

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

      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>

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

      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>

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

      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.

      <h3 id="tracing-resources-python">
        Tracing resources
      </h3>

      * [Pydantic AI documentation](https://ai.pydantic.dev)
      * [Trace LLM calls](/instrument/trace-llm-calls)
    </Tab>

    <Tab title="OpenTelemetry">
      To trace Pydantic AI through an existing OpenTelemetry pipeline, attach a `BraintrustSpanProcessor` and enable Pydantic AI's built-in instrumentation.

      <h3 id="setup-python-otel">
        Setup
      </h3>

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

      <h3 id="opentelemetry-python">
        Configure tracing
      </h3>

      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>

      <h3 id="tracing-resources-python-otel">
        Tracing resources
      </h3>

      * [OpenTelemetry integration](/integrations/sdk-integrations/opentelemetry)
      * [Pydantic AI documentation](https://ai.pydantic.dev)
    </Tab>
  </Tabs>
</View>
