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

# Trace Pipecat applications

<Note>
  This integration is in beta, so its API may change.
</Note>

Trace your [Pipecat](https://pipecat.ai/) voice agents to LangSmith with the LangSmith Pipecat integration. For high-level conventions, see [Voice tracing fundamentals](/langsmith/trace-voice-fundamentals).

<Note>
  The Pipecat integration requires `langsmith[pipecat]>=0.9.7`.
</Note>

The integration hooks into the spans Pipecat already emits and maps them onto LangSmith's tracing format, so each conversation becomes a single LangSmith trace, with a span per pipeline stage (STT, LLM, TTS). This covers both the STT/LLM/TTS cascade and speech-to-speech (realtime) models. Realtime models (for example, `OpenAIRealtimeLLMService`) need one extra call to capture the user's transcript. See [When using Pipecat with a realtime model](#when-using-pipecat-with-a-realtime-model).

## Install

Install the integration along with the Pipecat service extras your pipeline uses:

<CodeGroup>
  ```bash pip theme={null}
  pip install "langsmith[pipecat]" "pipecat-ai[openai,local,tracing]"
  ```

  ```bash uv theme={null}
  uv add "langsmith[pipecat]" "pipecat-ai[openai,local,tracing]"
  ```
</CodeGroup>

## Set environment variables

The integration reads your LangSmith credentials from the environment and exports to LangSmith for you via OpenTelemetry:

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

## Set up tracing

Import `configure_pipecat` and call it once before building your pipeline. Enable tracing on the `PipelineTask`:

```python theme={null}
from langsmith.integrations.pipecat import configure_pipecat
from pipecat.pipeline.task import PipelineParams, PipelineTask

# Install the tracer and the LangSmith span processor.
configure_pipecat()

task = PipelineTask(
    pipeline,
    params=PipelineParams(enable_metrics=True),
    enable_tracing=True,
    enable_turn_tracking=True,
    conversation_id=conversation_id,
)
```

<Note>
  Set `enable_tracing=True`, `enable_turn_tracking=True`, and `enable_metrics=True`. Turn tracking is required for tracing, and metrics drive the latency and token data on each span.
</Note>

### Use a LangGraph or LangChain agent as the LLM

If your LLM stage is an in-process [LangGraph or LangChain](/oss/python/langgraph/overview) agent, its model and tool runs should nest inside Pipecat's `llm` span rather than forming a separate trace. To achieve this:

* Pass `configure_pipecat(llm_span_kind="chain")`. This avoids nested `llm` spans that don't actually represent inference requests.
* Set `LANGSMITH_TRACING_MODE=otel` in the environment. Without it, those runs post to LangSmith directly and form a separate trace instead of nesting.

### Use your own tracer provider

`configure_pipecat()` builds a `TracerProvider`, registers the LangSmith span processor, and wires it into Pipecat. To send spans through a `TracerProvider` you already manage (for example, one that also exports to another OpenTelemetry backend), skip `configure_pipecat` and add the processor to your provider directly:

```python theme={null}
from langsmith.integrations.pipecat import PipecatLangSmithSpanProcessor

provider.add_span_processor(PipecatLangSmithSpanProcessor())
```

## Group a conversation into a thread

To group a conversation's runs into a LangSmith [thread](/langsmith/threads) for thread-level views and token and cost aggregation, call `set_thread_id` once per conversation before its spans are emitted:

```python theme={null}
from langsmith.integrations.pipecat import configure_pipecat, set_thread_id

configure_pipecat()
set_thread_id(conversation_id)
```

## When using Pipecat with a realtime model

With a speech-to-speech (realtime) model there is no separate speech-to-text stage, so the user's transcript is never emitted as an OTel span. Instead it arrives through the user context aggregator's `on_user_turn_message_added` callback, which Pipecat fires once it has the finalized user text. Without wiring it up, the trace shows only the assistant side.

Call `instrument_user_aggregator` once, right after building the context aggregator, so the SDK subscribes to that callback for you and pairs each transcript with its turn. It correlates by the id you pass to `set_thread_id`, so set that first and pass the same id:

<Note>
  `instrument_user_aggregator` requires `langsmith[pipecat]>=0.10.6`.
</Note>

```python theme={null}
from langsmith.integrations.pipecat import configure_pipecat, set_thread_id
from pipecat.processors.aggregators.llm_context import LLMContext
from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair
from pipecat.services.openai.realtime.events import (
    AudioConfiguration,
    AudioInput,
    AudioOutput,
    InputAudioTranscription,
    SessionProperties,
)
from pipecat.services.openai.realtime.llm import OpenAIRealtimeLLMService

conversation_id = "..."  # any id that identifies the conversation
span_processor = configure_pipecat()
set_thread_id(conversation_id)

llm = OpenAIRealtimeLLMService(
    api_key=openai_api_key,
    settings=OpenAIRealtimeLLMService.Settings(
        model="gpt-realtime",
        session_properties=SessionProperties(
            # Enable input-audio transcription: OpenAI Realtime sends the model
            # raw audio and, by default, produces no user-side text. Without this
            # the context aggregator never fires, so the user's turns never reach
            # the trace.
            audio=AudioConfiguration(
                input=AudioInput(transcription=InputAudioTranscription()),
                output=AudioOutput(voice="marin"),
            ),
        ),
    ),
)

context = LLMContext(messages=[{"role": "system", "content": "..."}])
context_aggregator = LLMContextAggregatorPair(context, realtime_service_mode=True)
span_processor.instrument_user_aggregator(context_aggregator, conversation_id)  # capture the user transcript
```

For OpenAI Realtime, also enable input-audio transcription (`InputAudioTranscription`) on the session; otherwise the model receives raw audio and produces no user-side text, so the aggregator never fires. Other realtime services that surface the user's text through the aggregator themselves (for example, Gemini Live) need only the `instrument_user_aggregator` call, with no extra session configuration.

Only call `instrument_user_aggregator` for realtime models. In the STT/LLM/TTS cascade the transcript is already captured (from the speech-to-text stage), so calling it there would record the user's turns a second time.

## Record the conversation audio

Attach the conversation audio to the trace using Pipecat's [`AudioBufferProcessor`](https://docs.pipecat.ai/server/utilities/audio/audio-recording). Place it after `transport.output()` so it captures what was actually played (after any barge-in truncation), hand it to the integration, and start it once the session is running:

```python theme={null}
from pipecat.processors.audio.audio_buffer_processor import AudioBufferProcessor

span_processor = configure_pipecat()

# Stereo: user on the left channel, agent on the right.
audiobuffer = AudioBufferProcessor(num_channels=2, buffer_size=32_000)
span_processor.attach_audio_buffer(audiobuffer, conversation_id=conversation_id)

pipeline = Pipeline([
    transport.input(),
    stt,
    context_aggregator.user(),
    llm,
    tts,
    transport.output(),
    audiobuffer,                     # after output(): records what was heard
    context_aggregator.assistant(),
])

await audiobuffer.start_recording()
```

The integration attaches the recording to the conversation root when it ends. For the underlying attachment API, see [Upload files with traces](/langsmith/upload-files-with-traces).

## 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-with-pipecat.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>
</div>
