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

# Trace Pipecat applications

LangSmith can capture traces generated by [Pipecat](https://pipecat.ai/) using OpenTelemetry instrumentation. This guide shows you how to automatically capture traces from your Pipecat voice AI pipelines and send them to LangSmith for monitoring and analysis.

For a complete implementation, see the [demo repository](https://github.com/langchain-ai/voice-agents-tracing).

## Installation

Install the required packages:

<CodeGroup>
  ```bash pip theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  pip install langsmith "pipecat-ai[whisper,openai,local]" opentelemetry-exporter-otlp python-dotenv
  ```

  ```bash uv theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  uv add langsmith "pipecat-ai[whisper,openai,local]" opentelemetry-exporter-otlp python-dotenv
  ```
</CodeGroup>

<Info>
  If you plan to use the advanced audio recording features, also install: `pip install scipy numpy`
</Info>

## Quickstart tutorial

Follow this step-by-step tutorial to create a voice AI agent with Pipecat and LangSmith tracing. You'll build a complete working example by copying and pasting code snippets.

### Step 1: Set up your environment

Create a `.env` file in your project directory:

```bash .env theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.smith.langchain.com/otel
OTEL_EXPORTER_OTLP_HEADERS=x-api-key=<your-langsmith-api-key>, Langsmith-Project=pipecat-voice
OPENAI_API_KEY=<your-openai-api-key>
```

### Step 2: Download the span processor

Add the [custom span processor file](https://github.com/langchain-ai/voice-agents-tracing/blob/main/pipecat/langsmith_processor.py) that enables LangSmith tracing. Save it as `langsmith_processor.py` in your project directory.

<Accordion title="What does the span processor do?">
  The span processor enriches Pipecat's OpenTelemetry spans with LangSmith-compatible attributes so your traces display properly in LangSmith.

  **Key functions:**

  * Converts Pipecat span types (stt, llm, tts, turn, conversation) to LangSmith format.
  * Adds `gen_ai.prompt.*` and `gen_ai.completion.*` attributes for message visualization.
  * Tracks and aggregates conversation messages across turns.
  * Handles audio file attachments (for advanced usage).

  The processor automatically activates when you import it in your code.
</Accordion>

### Step 3: Create your voice agent file

Create a new file called `agent.py` and add the following code. We'll build it section by section so you can copy and paste each part.

#### Part 1: Import dependencies

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import asyncio
import uuid
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

# Import Pipecat components
from pipecat.audio.vad.silero import SileroVADAnalyzer
from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.runner import PipelineRunner
from pipecat.pipeline.task import PipelineParams, PipelineTask
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
from pipecat.services.whisper.stt import WhisperSTTService
from pipecat.services.openai import OpenAILLMService, OpenAITTSService
from pipecat.transports.local.audio import LocalAudioTransport, LocalAudioTransportParams

# Import span processor to enable LangSmith tracing
from langsmith_processor import span_processor
```

#### Part 2: Define the main function

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
async def main():
    # Generate unique conversation ID for LangSmith
    conversation_id = str(uuid.uuid4())
    print(f"Starting conversation: {conversation_id}")

    # Configure audio input/output with voice activity detection
    transport = LocalAudioTransport(
        LocalAudioTransportParams(
            audio_in_enabled=True,
            audio_out_enabled=True,
            vad_analyzer=SileroVADAnalyzer(),
        )
    )

    # Initialize AI services
    stt = WhisperSTTService()
    llm = OpenAILLMService(model="gpt-5.4-mini")
    tts = OpenAITTSService(voice="alloy")

    # Set up conversation context with system prompt
    context = OpenAILLMContext(
        messages=[
            {
                "role": "system",
                "content": "You are a helpful voice assistant. Keep responses concise and conversational."
            }
        ]
    )
    context_aggregator = llm.create_context_aggregator(context)

    # Build the processing pipeline
    pipeline = Pipeline([
        transport.input(),           # Capture microphone input
        stt,                         # Convert speech to text
        context_aggregator.user(),   # Add user message to context
        llm,                         # Generate AI response
        tts,                         # Convert response to speech
        transport.output(),          # Play through speakers
        context_aggregator.assistant(),  # Add assistant response to context
    ])

    # Create task with tracing enabled
    task = PipelineTask(
        pipeline,
        params=PipelineParams(enable_metrics=True),
        enable_tracing=True,
        enable_turn_tracking=True,
        conversation_id=conversation_id,
    )

    # Run the agent
    runner = PipelineRunner()
    await runner.run(task)
```

#### Part 3: Add the entry point

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
if __name__ == "__main__":
    asyncio.run(main())
```

### Step 4: Run your agent

Run your voice agent:

```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
python agent.py
```

Speak to the agent through your microphone. All traces will automatically appear in LangSmith. Here is an example of a trace in LangSmith: [LangSmith trace with Pipecat](https://smith.langchain.com/public/07721f41-cd27-413e-bc79-90bd23b6807d/r).

View the complete [agent.py code](https://github.com/langchain-ai/voice-agents-tracing/blob/main/pipecat/agent.py).

## Advanced usage

### Custom metadata and tags

You can add custom metadata to your traces using span attributes:

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from opentelemetry import trace

tracer = trace.get_tracer(__name__)

async def run_voice_session():
    with tracer.start_as_current_span("voice_conversation") as span:
        # Add custom metadata
        span.set_attribute("langsmith.metadata.session_type", "voice_assistant")
        span.set_attribute("langsmith.metadata.user_id", "user_123")
        span.set_attribute("langsmith.span.tags", "pipecat,voice-ai,stt-llm-tts")

        # Your Pipecat pipeline code here
        task = PipelineTask(pipeline, enable_tracing=True)
        await task.queue_frames([TextFrame("Hello")])
```

### Recording and attaching audio to traces

You can capture audio from your voice conversations and attach it to traces in LangSmith. This allows you to listen to the actual audio alongside the transcriptions and AI responses.

#### Full conversation recording

See the [AudioRecorder implementation](https://github.com/langchain-ai/voice-agents-tracing/blob/main/pipecat/audio_recorder.py) which handles sample rate mismatches between input (microphone) and output (TTS) audio.

Capture all audio from start to finish and attach it to the conversation span:

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from pathlib import Path
from datetime import datetime
from audio_recorder import AudioRecorder

# Setup recording directory
recordings_dir = Path(__file__).parent / "recordings"
recordings_dir.mkdir(exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
recording_path = recordings_dir / f"conversation_{timestamp}.wav"

# Create audio recorder
audio_recorder = AudioRecorder(str(recording_path))

# Register with span processor for attachment to conversation span
span_processor.register_recording(
    conversation_id,
    str(recording_path),
    audio_recorder=audio_recorder
)

# Add to your pipeline
pipeline = Pipeline([
    transport.input(),
    stt,
    context_aggregator.user(),
    llm,
    tts,
    audio_recorder,              # Add audio recorder to pipeline
    transport.output(),
    context_aggregator.assistant(),
])

# Run pipeline
runner = PipelineRunner()
try:
    await runner.run(task)
finally:
    # IMPORTANT: Save recording BEFORE conversation span completes
    audio_recorder.save_recording()
```

#### Per-turn recording

See the [TurnAudioRecorder implementation](https://github.com/langchain-ai/voice-agents-tracing/blob/main/pipecat/turn_audio_recorder.py) which captures user speech and AI responses separately for each turn.

Capture separate audio snippets for each conversational turn, with user speech and AI responses saved as individual files:

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from turn_audio_recorder import TurnAudioRecorder

# Create turn audio recorder
turn_audio_recorder = TurnAudioRecorder(
    span_processor=span_processor,
    conversation_id=conversation_id,
    recordings_dir=recordings_dir,
    turn_tracker=None,  # Will be set after task creation
)

# Register with span processor
span_processor.register_turn_audio_recorder(conversation_id, turn_audio_recorder)

# Add to your pipeline
pipeline = Pipeline([
    transport.input(),
    stt,
    context_aggregator.user(),
    llm,
    tts,
    audio_recorder,              # Full conversation recording
    turn_audio_recorder,         # Per-turn audio snippets
    transport.output(),
    context_aggregator.assistant(),
])

# Create task
task = PipelineTask(
    pipeline,
    params=PipelineParams(enable_metrics=True),
    enable_tracing=True,
    enable_turn_tracking=True,  # Required for turn audio recording
    conversation_id=conversation_id,
)

# Connect turn tracker after task creation
if task.turn_tracking_observer:
    turn_audio_recorder.connect_to_turn_tracker(task.turn_tracking_observer)

# Run pipeline
runner = PipelineRunner()
try:
    await runner.run(task)
finally:
    audio_recorder.save_recording()
```

## Troubleshooting

### Spans not appearing in LangSmith

If traces aren't showing up in LangSmith:

1. **Verify environment variables**: Ensure `OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_EXPORTER_OTLP_HEADERS` are set correctly in your `.env` file.
2. **Check API key**: Confirm your LangSmith API key has write permissions.
3. **Verify import**: Make sure you're importing `span_processor` from `langsmith_processor.py`.
4. **Check .env loading**: Ensure `load_dotenv()` is called before importing Pipecat components.

### Messages not showing correctly

If conversation messages aren't displaying properly:

1. **Check span processor**: Verify `langsmith_processor.py` is in your project directory and imported correctly.
2. **Verify conversation ID**: Ensure you're setting a unique `conversation_id` in `PipelineTask`.
3. **Enable turn tracking**: Make sure `enable_turn_tracking=True` is set in `PipelineTask`.

### Audio not working

If your microphone or speakers aren't working:

1. **Check permissions**: Ensure your terminal/IDE has microphone access.
2. **Test audio devices**: Verify your microphone and speakers work in other applications.
3. **VAD settings**: Try adjusting `SileroVADAnalyzer()` settings if speech isn't being detected.
4. **Check services**: Ensure OpenAI API key is valid and has access to Whisper and TTS.

### Import errors

If you're getting import errors:

1. **Install dependencies**: Run `pip install langsmith "pipecat-ai[whisper,openai,local]" opentelemetry-exporter-otlp python-dotenv`.
2. **Check Python version**: Ensure you're using Python 3.9 or higher.
3. **Verify langsmith\_processor**: Make sure `langsmith_processor.py` is downloaded and in the same directory as your `agent.py`.

### Performance issues

If responses are slow:

1. **Use faster models**: Switch to `gpt-5.4-mini` for the LLM (already in the tutorial).
2. **Check network**: Ensure stable internet connection for API calls.
3. **Local STT**: Consider using local Whisper instead of API-based services.

### Advanced: Audio recording troubleshooting

For issues with the advanced audio recording features, see the [complete demo documentation](https://github.com/langchain-ai/voice-agents-tracing).

***

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