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

# Pydantic AI

> Trace Pydantic AI agents with OpenInference and send spans to Arize AX for LLM observability.

[Pydantic AI](https://ai.pydantic.dev/) is an agent framework from the Pydantic team that emphasises type-safe agents, Pydantic-validated outputs, and tool use. Arize AX captures every Pydantic AI agent run — model calls, tool invocations, and structured-output validation — via the [`openinference-instrumentation-pydantic-ai`](https://github.com/Arize-ai/openinference/tree/main/python/instrumentation/openinference-instrumentation-pydantic-ai) package. Pydantic AI emits OpenTelemetry spans natively when `instrument=True`; the OpenInference span processor reshapes them into the OpenInference format that Arize AX understands.

## Prerequisites

* Python 3.10+
* An Arize AX account ([sign up](https://arize.com/sign-up/))
* An `OPENAI_API_KEY` from the [OpenAI Platform](https://platform.openai.com/api-keys)

## Launch Arize AX

1. Sign in to your [Arize AX account](https://app.arize.com/).
2. From **Space Settings**, copy your **Space ID** and **API Key**. You will set them as `ARIZE_SPACE_ID` and `ARIZE_API_KEY` below.

## Install

```bash theme={null}
pip install arize-otel \
  openinference-instrumentation-pydantic-ai \
  pydantic-ai openai
```

## Configure credentials

```bash theme={null}
export ARIZE_SPACE_ID="<your-space-id>"
export ARIZE_API_KEY="<your-api-key>"
export ARIZE_PROJECT_NAME="pydantic-ai-tracing-example"
export OPENAI_API_KEY="<your-openai-api-key>"
```

## Setup tracing

```python theme={null}
# instrumentation.py
import os

from arize.otel import BatchSpanProcessor, GRPCSpanExporter, register
from openinference.instrumentation.pydantic_ai import OpenInferenceSpanProcessor

space_id = os.environ["ARIZE_SPACE_ID"]
api_key = os.environ["ARIZE_API_KEY"]

tracer_provider = register(
    space_id=space_id,
    api_key=api_key,
    project_name=os.environ["ARIZE_PROJECT_NAME"],
)

# add_span_processor replaces register()'s default OTLP processor, so we
# add it back explicitly. The two-call pattern gives us:
# OpenInferenceSpanProcessor (reshapes spans) →
# GRPCSpanExporter (sends to Arize).
tracer_provider.add_span_processor(OpenInferenceSpanProcessor())
tracer_provider.add_span_processor(
    BatchSpanProcessor(GRPCSpanExporter(space_id=space_id, api_key=api_key))
)
print("Arize AX tracing initialized for Pydantic AI.")
```

## Run Pydantic AI

```python theme={null}
# example.py

# Importing instrumentation first ensures tracing is set up
# before `pydantic_ai` is imported.
from instrumentation import tracer_provider

from pydantic import BaseModel
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel


class CityFact(BaseModel):
    city: str
    fact: str


# OpenAIChatModel reads OPENAI_API_KEY from the environment.
model = OpenAIChatModel("gpt-5")
agent = Agent(model, output_type=CityFact, instrument=True)

result = agent.run_sync("Give me one short fact about Paris.")
print(f"city={result.output.city} fact={result.output.fact}")
```

### Expected output

```text wrap theme={null}
Arize AX tracing initialized for Pydantic AI.
city=Paris fact=The Eiffel Tower was completed in 1889 for the World's Fair.
```

## Verify in Arize AX

1. Open your Arize AX space and select project **`pydantic-ai-tracing-example`**.
2. You should see a new trace within \~30 seconds containing an `agent run` parent span wrapping a nested OpenAI chat-completion LLM span, with the prompt, response, and the validated `CityFact` output attached.
3. If no traces appear, see [Troubleshooting](#troubleshooting).

## Troubleshooting

* **No traces in Arize AX.** Confirm `ARIZE_SPACE_ID` and `ARIZE_API_KEY` are set in the same shell that runs `example.py`. Enable OpenTelemetry debug logs with `export OTEL_LOG_LEVEL=debug` and re-run.
* **Agent ran but no spans appear.** Pydantic AI only emits OTel spans when the agent is constructed with `instrument=True`. Confirm that flag is set on every `Agent(...)` you want traced.
* **`401` from OpenAI.** Verify `OPENAI_API_KEY` is set and has access to `gpt-5`. Swap for a model your key can call.
* **Output validation errors.** When the model returns content that doesn't satisfy the `output_type` Pydantic model, Pydantic AI raises a validation error and may retry. Both the failed and successful attempts surface as separate spans.

## Resources

<CardGroup>
  <Card icon="book-open" href="https://ai.pydantic.dev/" title="Pydantic AI Documentation" horizontal />

  <Card icon="terminal" href="https://github.com/Arize-ai/openinference/tree/main/python/instrumentation/openinference-instrumentation-pydantic-ai" title="OpenInference Pydantic AI Instrumentor" horizontal />

  <Card icon="github" href="https://github.com/pydantic/pydantic-ai" title="Pydantic AI GitHub" horizontal />
</CardGroup>
