> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-5e9cc07a-preview-voicet-1782781101-fbe4599.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Trace OpenAI Realtime applications

> Trace OpenAI Realtime voice agents in LangSmith using the LangSmith SDK.

Trace your [OpenAI Realtime API](https://platform.openai.com/docs/guides/realtime) voice agents to LangSmith. For high-level conventions, see [Voice tracing fundamentals](/langsmith/trace-voice-fundamentals).

OpenAI Realtime is a speech-to-speech model that streams typed events over a WebSocket. Either way you build it, the integration captures each conversation as a single LangSmith trace, with a span for every meaningful event (transcripts, model responses, and tool calls) grouped by turn. You enable it with one call and do not create any spans yourself. The flood of audio chunks is played but not traced.

<Note>
  The OpenAI Realtime integration is in development, so its API may change.
</Note>

## Choose an approach

There are two ways to build an OpenAI Realtime agent, and each has its own integration:

| Approach              | Use when                                                                                                              | Trace with              |
| --------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| **Raw connection**    | You drive the WebSocket loop and run tools yourself, and want full control with minimal dependencies (`openai` only). | `wrap_realtime`         |
| **OpenAI Agents SDK** | You want the Agents SDK to own the turn and tool-call loop, with support for handoffs and multi-agent setups.         | `wrap_realtime_session` |

Both produce the same kind of trace. Pick the one that matches how you built your agent.

## Install

The `langsmith[openai-realtime]` extra provides both wrappers:

<CodeGroup>
  ```bash pip theme={null}
  pip install "langsmith[openai-realtime]"
  ```

  ```bash uv theme={null}
  uv add "langsmith[openai-realtime]"
  ```
</CodeGroup>

Voice apps also need an audio library such as `sounddevice` for microphone and speaker I/O.

## Set environment variables

```bash .env theme={null}
LANGSMITH_API_KEY=<your-langsmith-api-key>
LANGSMITH_TRACING=true
LANGSMITH_PROJECT=openai-realtime-voice
OPENAI_API_KEY=<your-openai-api-key>
```

## Raw connection

Use this when you open the WebSocket yourself with `client.realtime.connect()` and drive the event loop.

### Set up tracing

`wrap_realtime` returns a transparent proxy of your connection. Your existing `async for event in connection` loop, `session.update`, and tool handling stay the same:

```python theme={null}
from langsmith.integrations.openai_realtime import wrap_realtime
from openai import AsyncOpenAI

client = AsyncOpenAI()

async with client.realtime.connect(model="gpt-realtime") as raw, wrap_realtime(
    raw,
    thread_id=thread_id,
    project_name="openai-realtime-voice",
) as connection:
    await connection.session.update(session={...})  # your existing config

    async for event in connection:
        ...  # your existing handling: play audio, run tools, update UI
```

A stable `thread_id` you generate per conversation (for example, a UUID) groups the trace into a LangSmith [thread](/langsmith/threads). Any [`@traceable`](/langsmith/annotate-code) tools you run while handling an event nest under that event automatically.

<Note>
  Enable `input_audio_transcription` (and the agent transcript) in your `session.update`, or the transcription events that make the trace readable never arrive.
</Note>

### Record the conversation audio

Feed the proxy your microphone and playback audio, and it attaches a single stereo recording (user left, agent right) to the trace. Pass `is_agent_speaking` so barge-ins are flagged:

```python theme={null}
async with client.realtime.connect(model="gpt-realtime") as raw, wrap_realtime(
    raw,
    thread_id=thread_id,
    is_agent_speaking=lambda: speaker.buffered_bytes() > 0,
) as connection:
    async for event in connection:
        if event.type == "input_audio_buffer.append":
            connection.record_user_audio(mic_chunk)      # user mic PCM16
        elif event.type == "response.output_audio.delta":
            connection.record_agent_audio(played_chunk)  # agent PCM16 as played
```

## OpenAI Agents SDK

Use this when you build the agent with the [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/realtime/guide/) (`RealtimeAgent` / `RealtimeRunner`), which owns the turn and tool-call loop.

<Note>
  The Agents SDK's built-in realtime tracing uploads to OpenAI's own dashboard. Call `agents.set_tracing_disabled(True)` to avoid a second, separate upload path.
</Note>

### Set up tracing

`wrap_realtime_session` wraps the `RealtimeSession` and enters it for you. Iterate it as you would the original; the SDK runs tools and manages turns:

```python theme={null}
from agents import set_tracing_disabled
from agents.realtime import RealtimeAgent, RealtimeRunner
from langsmith.integrations.openai_realtime import wrap_realtime_session

set_tracing_disabled(True)

runner = RealtimeRunner(
    starting_agent=RealtimeAgent(name="assistant", instructions="...", tools=[...]),
)
session = await runner.run()

async with wrap_realtime_session(
    session,
    thread_id=thread_id,
    project_name="openai-realtime-voice",
) as conn:
    async for event in conn:
        ...  # your handling: play audio, update UI
```

The conversation transcript is reconstructed from the session's `history` snapshots, so messages appear even though the SDK streams them as partials.

### Record the conversation audio

Feed the proxy your microphone and playback audio:

```python theme={null}
async for event in conn:
    if event.type == "audio":
        conn.record_agent_audio(event.audio.data)  # agent PCM16 as played
    # feed user mic PCM16 as you send it to the session:
    # conn.record_user_audio(mic_chunk)
```

## Next steps

<CardGroup cols={2}>
  <Card title="Voice fundamentals" icon="waveform" href="/langsmith/trace-voice-fundamentals">
    Core conventions for tracing voice agents.
  </Card>

  <Card title="Upload files with traces" icon="paperclip" href="/langsmith/upload-files-with-traces">
    Attach the conversation audio recording to your trace.
  </Card>
</CardGroup>

***

<div className="source-links">
  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>

  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/langsmith/trace-openai-realtime.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>
</div>
