# Pydantic AI

> Export native agent, model and tool spans from an existing Pydantic AI application.

Pydantic AI’s native instrumentation records agent invocations, model requests and tool calls. Configure its OpenTelemetry provider to export to Radiant, then enable instrumentation for your existing agents. This setup does not require a Logfire account.

## Configure the tracer provider

Use Python 3.11+ and the endpoint and ingestion key from [Set up your project](/docs/platform/set-up-your-project.md). Keep the model provider and credentials already configured by your application.

**Terminal**

```sh
python -m pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
```

**Application environment**

```sh
export RADIANT_TRACES_ENDPOINT='https://YOUR_INGESTION_HOST/v1/traces'
export RADIANT_INGESTION_KEY='YOUR_INGESTION_KEY'
export OTEL_SERVICE_NAME='YOUR_APPLICATION_NAME'
```

Create the provider before enabling instrumentation. If one already exists, add the exporter to it rather than registering another provider.

**tracing.py**

```python
import os
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor


provider = TracerProvider(
    resource=Resource.create({"service.name": os.environ["OTEL_SERVICE_NAME"]})
)
provider.add_span_processor(
    BatchSpanProcessor(
        OTLPSpanExporter(
            endpoint=os.environ["RADIANT_TRACES_ENDPOINT"],
            headers={"Authorization": "Bearer " + os.environ["RADIANT_INGESTION_KEY"]},
        )
    )
)
trace.set_tracer_provider(provider)
```

## Enable native instrumentation

At startup, before the existing agents run:

**Application startup**

```python
from pydantic_ai import Agent
from pydantic_ai.models.instrumented import InstrumentationSettings
from tracing import provider


Agent.instrument_all(
    InstrumentationSettings(
        tracer_provider=provider,
        include_content=True,
    )
)
```

Keep your existing agent definitions and `agent.run(...)` or `agent.run_sync(...)` calls. Native instrumentation records agent invocations, model requests and executed tools.

`include_content=True` records message content and tool arguments and results. Set it to `False` when those payloads should be omitted. That control does not remove values recorded by your own custom spans or separate HTTP instrumentation. Set the policy before sending requests containing customer data.

## Inspect a recorded request

Run an existing request and find its service in the project’s **Logs**. Open the invocation to inspect its model and tool operations. With content capture enabled, recorded model messages and tool payloads are available on the corresponding operations; usage appears when the model provider reports it.

Call `provider.shutdown()` in the application’s shutdown lifecycle to export buffered spans. For a short-lived script, call it in an outer `finally` block after the agent finishes.

See [Pydantic AI’s OpenTelemetry configuration](https://pydantic.dev/docs/ai/integrations/logfire/) for instrumentation and capture settings. [Tracing troubleshooting](/docs/platform/reference/telemetry.md#troubleshoot-tracing) covers export and agent-detection problems.

## Optional: Add conversation context

Pass your application’s conversation identifier as `conversation_id` on the existing agent call. Here, `session_id` is the identifier your application already uses:

**At the existing agent call**

```python
result = await agent.run(user_input, conversation_id=session_id)
```

Native instrumentation records it as `gen_ai.conversation.id` on agent, model and tool spans. Open [Conversations in Logs](/docs/platform/logs/search-and-filters.md#conversations) to inspect related runs together. Pydantic AI’s additional run `metadata` is recorded as JSON in the `metadata` attribute, rather than as separate attribute keys. See [Pydantic AI’s conversation correlation](https://pydantic.dev/docs/ai/core-concepts/message-history/#correlating-runs-with-run_id-and-conversation_id).
