> ## 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](/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.

[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](/docs/integrations/sdk-integrations/opentelemetry)
  * [Trace LLM calls](/docs/instrument/trace-llm-calls)
</View>
