The LiveKit integration requires
langsmith[livekit]. It is in development, so its API may change.Install
Install the integration along with the LiveKit plugins your agent uses:Set environment variables
The integration reads your LangSmith credentials from the environment and exports to LangSmith for you:.env
Set up tracing
Importconfigure_livekit and call it once before creating your AgentServer. It builds the tracer provider, registers the LangSmith span processor, and wires it into LiveKit:
AgentSession with a realtime model (for example, lk_openai.realtime.RealtimeModel(...)) and the tracing setup is unchanged.
Use your own tracer provider
There are two ways to install the tracing provider.configure_livekit() is the quick path: it builds a TracerProvider, registers the LangSmith span processor, and wires it into LiveKit. To use a TracerProvider you already manage, construct the processor yourself, add it to your provider, and register that provider with LiveKit’s tracer hook. LiveKit only emits spans through the provider its tracer is bound to:
Record the conversation audio
The integration attaches the call recording to the conversation root span. How you capture that recording differs between local development and production.Development: embed a local file
In console and local development, enable LiveKit’s session recording and pointaudio_path_provider at the audio.ogg LiveKit writes under ctx.session_directory. The integration reads that file and embeds the bytes in the trace.
--record on the command line. The recording reflects what was played to the client, so a barge-in shows up truncated.
Production: record with Egress and attach the file
In production, record the room with LiveKit Egress into your own object storage, then attach the finished recording to the trace as a real audio attachment. Egress finishes uploading after the call ends, so the integration holds the conversation’s root span open until you supply the bytes:- Call
processor.expect_recording(thread_id)when you start egress. The root span stays open. - After the call, wait for egress to complete, download the file from your storage, and call
processor.complete_recording(thread_id, audio_bytes). The integration embeds the bytes and exports the trace.
thread_id for both calls and for set_thread_id, so the integration can match the recording to the conversation.
wait_for_egress polls list_egress until the status is EGRESS_COMPLETE (or subscribe to the egress_ended webhook), and download_from_storage reads the object with your cloud provider’s client. LiveKit Egress also writes to Google Cloud Storage and Azure: swap s3= for gcp=api.GCPUpload(...) or azure=api.AzureBlobUpload(...).
Because the trace’s root span is held until
complete_recording runs, always call it, including on failure with data=None, so the trace is not left open. If the worker stops first, the integration flushes the trace without audio.Self-hosted LiveKit
This flow does not depend on LiveKit Cloud. LiveKit Server and Egress are open source, and the integration works the same whether your agent connects to LiveKit Cloud or to your own deployment. With self-hosted Egress you can also write the recording to a local or shared volume, in which case the developmentaudio_path_provider path can read it directly without a storage download.
For the underlying attachment API used by both paths, see Upload files with traces.
Next steps
Voice fundamentals
Core conventions for tracing voice agents.
Upload files with traces
Attach the conversation audio recording to your trace.
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

