.webp)
When a user types "my order hasn't arrived" vs says it with audible anxiety โ the transcript looks identical, but the signals are completely different.
Text strips out:
๐ก "I'm fine" said with relief and "I'm fine" said with frustration are the same transcript, different interaction.
A system that only reads transcripts is working with half the information.
This means voice agents need to handle dimensions that text agents never had to consider:
These aren't minor additions โ they require architectural decisions from the ground up.
There are three specific problems that make voice harder than it looks.
Humans know when someone has finished speaking through:
Standard voice systems use Voice Activity Detection (VAD) โ which only detects silence.
User: "I'd like to book a flight to... [thinking pause]"
Bot: [interrupts] "Sure! Where would you like to go?"
User: "...Tokyo."
โ ๏ธ The system is technically functional but conversationally broken.
Passing conversation history to an LLM at each turn is necessary but not sufficient.
The same words mean different things depending on delivery. A voice system that ignores emotional tone will always sound slightly off โ even if every individual model is strong.
Teams that build their own voice orchestration end up permanently maintaining:
This is not a one-time build. It becomes ongoing infrastructure work.
This is the recommended technical pattern for adding voice to an existing text agent.
[User Microphone]
โ
[Client] โโโWebSocket 1โโโ [ElevenLabs API]
โ
Transcription happens here
โ
[ElevenLabs API] โโโWebSocket 2โโโ [Your Server]
โ
[Your LLM]
โ
Response streams back
โ
Audio synthesis begins
(before LLM finishes generating)
| Component | What It Does |
|---|---|
| WebSocket 1 | Carries audio from client to ElevenLabs |
| WebSocket 2 | Carries transcripts + history to your server |
onTranscript method | Fires at end of each turn, passes full conversation history to LLM |
contextualUpdate | Carries over text conversation history when user switches to voice |
Audio synthesis begins before the LLM finishes generating โ this keeps first-byte latency low, which is critical for conversations feeling natural.
๐ The user hears a response starting quickly, even if the full response isn't ready yet.
When building this system, four specific choices significantly impact quality.
| Context | Priority |
|---|---|
| Text chat | Reasoning quality |
| Voice | Speed |
Deep reasoning models introduce pauses that register as unnatural hesitation in audio. Even if the response is better, it feels worse.
โ For real-time voice: faster models almost always win on perceived quality.
WebRTC comes with built-in:
WebSockets for audio means you handle all of that yourself.
โ Use WebRTC for audio transport, especially for mobile or noisy environments.
Asking users to pick a language breaks conversational flow.
Better pattern:
โ The system should adapt to the user โ not the other way around.
Using your LLM to decide when a user has finished speaking adds:
A dedicated turn-taking model handles this:
โ Treat turn-taking as its own architectural component, not an LLM task.
This is a strategic decision, not just a technical one.
If you already have a working text chatbot:
[Existing Text Agent]
- Your LLM โ
- Your business logic โ
- Your orchestration โ
+
[Voice Layer Added on Top]
- Audio interface only
- No rebuilding required
โ Fastest path. Lowest risk. You're adding an audio interface to something that already works.
If you need:
Then handing more of the stack to a voice agent platform makes sense.
These two paths are not mutually exclusive.
Start lightweight โ validate the use case โ layer in platform capabilities as needs grow.
CONCEPT 1: Voice โ Text
โโโ Tone, rhythm, emotion are lost in transcripts
CONCEPT 2: Three Hard Problems
โโโ Turn-taking / Context continuity / Engineering overhead
CONCEPT 3: Dual WebSocket Architecture
โโโ Two connections + onTranscript + contextualUpdate = low latency voice layer
CONCEPT 4: Four Engineering Decisions
โโโ Fast LLM / WebRTC / Auto language detection / Separate turn-taking model
CONCEPT 5: Build Strategy
โโโ Start with a voice layer on top โ scale to platform as needed
You don't need to rebuild your chatbot to give it a voice. You need to add an audio interface โ and make smart decisions about the four engineering choices that determine whether it sounds human or broken.