Skip to main content
This tutorial demonstrates how to build a complete voice agent pipeline that converts speech to text, processes it with an LLM, and generates speech output. The entire pipeline is traced end-to-end using Maxim for full observability. The agent uses Elevenlabs’ transcription and synthesis capabilities with an external LLM to generate the response.

Prerequisites

  • Python 3.9+
  • ElevenLabs API key
  • OpenAI API key
  • Maxim account (API key, log repo ID)
  • Sample audio file for testing (optional)

Project Setup

Configure your environment variables in .env:

Install Dependencies

Add Dependencies to requirements.txt

Set Up a Virtual Environment

Create a Project Directory and Navigate into It


Code Walkthrough: Key Components

Below, each section of the code is presented with a technical explanation.

1. Imports and Configuration

  • Imports ElevenLabs SDK for STT and TTS operations.
  • Imports Maxim instrumentation utilities for automatic tracing.
  • Loads and validates environment variables to ensure all required API keys are present.

2. Initialize Maxim Logger and Instrument ElevenLabs

  • Creates a Maxim logger instance that automatically reads credentials from environment variables.
  • instrument_elevenlabs patches ElevenLabs SDK methods to automatically capture STT and TTS operations as spans.
  • MaximOpenAIClient wraps the OpenAI client to trace LLM calls within the same trace context.
The OpenAI integration is used to demonstrate how to trace LLM calls with Maxim in addition to ElevenLabs. You can use any other LLM provider you want.

3. OpenAI LLM Call with Trace Linking

  • Sends the transcribed text to OpenAI’s GPT-4o-mini model for processing.
  • Uses x-maxim-trace-id header to link this LLM call to the same trace as STT and TTS operations.
  • Returns the generated response text for TTS conversion.

4. STT-LLM-TTS Pipeline Agent

  • Generates a unique trace ID to correlate all operations in the pipeline.
  • Creates a Maxim trace with descriptive name and tags for easy filtering.
  • Configures RequestOptions with the trace ID header for ElevenLabs API calls.

5. Speech-to-Text Conversion

  • Reads the audio file and sends it to ElevenLabs Scribe STT model.
  • The request_options automatically links this operation to the trace.
  • Handles multiple response formats for robust transcript extraction.

6. Text-to-Speech Conversion

  • Passes the transcript to the OpenAI LLM for response generation.
  • Converts the LLM response to speech using ElevenLabs multilingual TTS model.
  • Uses the same request_options to maintain trace continuity.
  • Plays the generated audio output.

7. Fallback for Missing Audio File

  • Provides a fallback when no audio file is available for testing.
  • Manually sets the trace input using trace.set_input().
  • Demonstrates that the TTS portion works independently of STT.

8. Main Block

Entry point for the script. Ensures the logger is properly cleaned up after execution to flush all traces.

Pipeline Flow

The agent implements a complete voice interaction pipeline: All operations are traced under a single trace ID for unified observability.

How to Use

  1. Configure credentials: Set all API keys in your .env file.
  2. Prepare audio (optional): Place a sample_audio.wav file in a files/ subdirectory.
  3. Run the agent: Execute the script to process audio through the pipeline.
  4. Monitor in Maxim: View the complete trace including STT, LLM, and TTS spans.

Run the Script

Observability with Maxim

The instrumentation provides comprehensive tracing data:
  • Unified traces: All STT, LLM, and TTS operations linked under one trace ID
  • Input/Output capture: Audio files attached to STT spans, text captured for LLM and TTS
  • Timing metrics: Latency measurements for each pipeline stage
  • Custom tags: Filter traces by provider and operation type
  • Error tracking: Automatic capture of failures at any pipeline stage

Troubleshooting

  • No traces in Maxim
    • Verify MAXIM_API_KEY and MAXIM_LOG_REPO_ID are set correctly
    • Ensure logger.cleanup() is called before the process exits
    • Check that instrument_elevenlabs(logger) is called before creating the ElevenLabs client
  • STT not working
    • Confirm EL_API_KEY is valid
    • Ensure audio file is in a supported format (WAV, MP3, etc.)
    • Check file path is correct
  • LLM response empty
    • Verify OPENAI_API_KEY is set correctly
    • Check that the transcript was successfully extracted
  • TTS not producing audio
    • Confirm the voice ID is valid (use ElevenLabs dashboard to find available voices)
    • Check that the model ID is correct
  • Trace operations not linked
    • Ensure the same trace_id is passed to all operations
    • Verify x-maxim-trace-id header is included in request options

Complete Code: elevenlabs_agent.py

Resources

Cookbook Code

Python Code for ElevenLabs & Maxim

ElevenLabs Documentation

Learn more about ElevenLabs STT and TTS