# OpenAI Agents SDK

> Record agent invocations, model messages, tool calls and usage from your existing application.

The OpenTelemetry instrumentors for the Agents SDK and OpenAI client record your existing agent loop. The Agents instrumentor captures invocations and tools; the client instrumentor captures model requests and token usage. Enable message capture to inspect prompts, responses and tool payloads in Radiant.

## Configure export

Use your existing Python application and the endpoint and ingestion key from [Set up your project](/docs/platform/set-up-your-project.md). Install the OpenTelemetry exporter and both instrumentors alongside the Agents SDK:

**Terminal**

```sh
python -m pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http \
  opentelemetry-instrumentation-genai-openai-agents==1.3b0 \
  opentelemetry-instrumentation-genai-openai==1.3b0
```

These examples use the upstream instrumentors at version `1.3b0`. Keep the Agents SDK and model configuration already used by your application.

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

Initialize the provider and instrumentors at application startup, before creating agents or making model requests. If the application already has an OpenTelemetry SDK provider, add the exporter to that provider instead of creating another one.

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


from opentelemetry.instrumentation.genai.openai_agents import OpenAIAgentsInstrumentor
from opentelemetry.instrumentation.genai.openai import OpenAIInstrumentor


OpenAIAgentsInstrumentor().instrument()
OpenAIInstrumentor().instrument()
```

Import this module during startup. Your existing `Runner.run(...)`, `Runner.run_sync(...)` and tool definitions can remain unchanged. The instrumentors record their operations and preserve their parent-child relationships; remove any manual spans that duplicate the same agent or tool operations.

The Agents SDK can also export its own traces to OpenAI. To send its trace data only through OpenTelemetry, pass `disable_openai_trace_export=True` to `OpenAIAgentsInstrumentor().instrument(...)`.

## Capture messages and tool payloads

Set this before starting the application when you want model input/output messages and tool arguments/results on the exported spans:

**Application environment**

```sh
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT='SPAN_ONLY'
```

Content capture is off by default. Enabling it can include application data supplied to models and tools. Model identity, timing and token usage are recorded without enabling message content.

Keep the provider alive across requests. Call `provider.shutdown()` in the application’s shutdown lifecycle to flush buffered spans. For streaming runs, consume the stream before shutting down the provider.

## Connect runs into conversations

Pass your application’s conversation identifier through `RunConfig.group_id` at the existing runner call:

**At the existing Runner call**

```python
from agents import RunConfig, Runner


result = await Runner.run(
    agent,
    user_input,
    run_config=RunConfig(group_id=conversation_id),
)
```

Merge `group_id` into an existing `RunConfig` if you already supply one. The instrumentor exports it as `gen_ai.conversation.id`. Reuse the identifier across turns in the same conversation; each invocation remains a separate agent run in Radiant.

## Add application context

For labels shared by the process, use OpenTelemetry resource attributes before startup:

**Application environment**

```sh
export OTEL_RESOURCE_ATTRIBUTES='deployment.environment.name=production,app.release=2026.10.30'
```

For request-specific attributes, put a normal OpenTelemetry span around the existing runner call and add the attributes there. The SDK’s native invocation remains a child of that request span. The [OpenTelemetry guide](/docs/platform/connect-your-agent/opentelemetry.md#add-attributes) explains attribute scope.

## Inspect an invocation

Run an existing request and open the project’s **Logs**. **All agent runs** shows the invocation; opening it reveals its model requests and tools. Select a model operation to inspect captured messages in **Thread**, or select a tool to inspect its arguments and result. **Conversations** brings together runs with the same conversation identifier.

For SDK tracing controls, see the [official Agents SDK observability guide](https://developers.openai.com/api/docs/guides/agents/integrations-observability). The upstream [Agents instrumentor](https://github.com/open-telemetry/opentelemetry-python-genai/tree/main/instrumentation/opentelemetry-instrumentation-genai-openai-agents) documents the OpenTelemetry integration. For export failures, see [tracing troubleshooting](/docs/platform/reference/telemetry.md#troubleshoot-tracing).
