LangSmith can capture traces generated by Pipecat 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.
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.
Add the custom span processor file that enables LangSmith tracing. Save it as langsmith_processor.py in your project directory.
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:
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.
See the AudioRecorder implementation 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:
Copy
Ask AI
from pathlib import Pathfrom datetime import datetimefrom audio_recorder import AudioRecorder# Setup recording directoryrecordings_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 recorderaudio_recorder = AudioRecorder(str(recording_path))# Register with span processor for attachment to conversation spanspan_processor.register_recording( conversation_id, str(recording_path), audio_recorder=audio_recorder)# Add to your pipelinepipeline = Pipeline([ transport.input(), stt, context_aggregator.user(), llm, tts, audio_recorder, # Add audio recorder to pipeline transport.output(), context_aggregator.assistant(),])# Run pipelinerunner = PipelineRunner()try: await runner.run(task)finally: # IMPORTANT: Save recording BEFORE conversation span completes audio_recorder.save_recording()
See the TurnAudioRecorder implementation 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:
Copy
Ask AI
from turn_audio_recorder import TurnAudioRecorder# Create turn audio recorderturn_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 processorspan_processor.register_turn_audio_recorder(conversation_id, turn_audio_recorder)# Add to your pipelinepipeline = 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 tasktask = 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 creationif task.turn_tracking_observer: turn_audio_recorder.connect_to_turn_tracker(task.turn_tracking_observer)# Run pipelinerunner = PipelineRunner()try: await runner.run(task)finally: audio_recorder.save_recording()