One of our customers runs a recruitment product where candidates talk to an AI by voice. The whole pitch is the conversation. It should feel like talking to a person, not navigating a phone tree. And users were getting frustrated and dropping out. The voice sounded natural, but the agent kept failing to do things mid-conversation: pull up the right information or trigger the right action on screen. A natural-sounding agent that doesn't do what you asked is worse than a clunky one that does.
The founder was worried, and he was right to be. For a product whose entire value is trust in a conversation, this was the one thing that couldn't be broken.
Tracing it to the architecture
We had built on OpenAI's Realtime API: speech in, speech out, with one model handling the conversation and tool calls. The demos were strong, but the user complaints clustered around actions that did not fire reliably. The transcript could read naturally while the requested change on screen failed. Documentation and community reports from that period described similar problems with tool calling on the Realtime preview.
We first tuned the prompt and rewrote the tool descriptions. Reliability improved a little, then plateaued. More prompt work was no longer producing evidence that the architecture could meet the product requirement.
Reframing it as a product decision
We reframed the choice with the founder around what candidates came to do. They could tolerate a short pause, but a missed action broke the conversation and sometimes ended it. That made tool reliability the primary requirement and voice naturalness a secondary one.
We researched Pipecat and LiveKit and spent about a month building a stitched-pipeline POC: speech-to-text, a text LLM with tool calling, and text-to-speech. It added latency and gave us three components to operate instead of one.
We built a test set of statements a candidate might say and measured tool-trigger reliability on the pipeline. Around 40 of 50 statements triggered the right tool in our first baseline pass. That result came from our rough internal harness rather than a published benchmark. The misses were more informative than the score: most traced to overlapping tool descriptions that we could separate. We had not found an equally actionable pattern in the Realtime failures.
The cost was real: responses landed at roughly 1.2 seconds, noticeably slower than the Realtime path. We took the tradeoff with our eyes open, because for this workflow a beat of silence was survivable and a wrong action was not.
The important detail is that the 1.2 seconds became inspectable. In the fused path, "it felt slow" and "it chose the wrong action" were hard to separate. In the stitched path, each stage had a receipt. If STT was slow, we saw it. If the LLM spent the budget choosing a tool, we saw it. If TTS blocked playback, we saw it. That is the hidden value of an uglier architecture: it gives you places to put instruments.
Voice architecture
Where can you inspect the decision?
Switch between the two architectures and follow a tool-using turn. The diagram changes the model boundaries and the checkpoints you can inspect.
Scenario
Architecture sketch of the historical comparison. Realtime sessions can expose events and transcripts; fused does not mean unobservable.
Sequence
- Speech entersCurrent
- One voice modelUpcoming
- Application executesUpcoming
- Audio returnsUpcoming
Speech enters
Audio enters the realtime session. Turn detection and interruption handling still matter.
Read the full explanation
Fused voice
Architecture sketch of the historical comparison. Realtime sessions can expose events and transcripts; fused does not mean unobservable.
- Speech enters. Audio enters the realtime session. Turn detection and interruption handling still matter.
- One voice model. Speech understanding and speech generation share a realtime model session. Tool calls are proposals sent to the application.
- Application executes. Application code validates the proposed action, executes the tool, and sends the result back to the session. The speech model does not own the side effect.
- Audio returns. The session continues with the tool result and produces audio. Natural turn shape did not compensate for the historical workflow’s unreliable actions.
Stitched pipeline
Historical internal baseline: around 40 of 50 tool triggers; roughly 1.2 seconds overall. Neither number is a current benchmark or a stage allocation.
- Speech enters. Keep the incoming speech and its turn boundary tied to one trace.
- Inspect hearing. Speech-to-text exposes what the decision model received. Compare this transcript with the intended utterance before changing a prompt.
- Inspect the decision. The text model proposes a tool call. The trace exposes its tool name and arguments separately from speech generation.
- Validate and execute. The application validates the proposal against screen state and allowed transitions, executes the tool, and returns the result to the text model.
- Inspect delivery. After the tool result informs the response, text-to-speech generates audio. Playback and cancellation remain application orchestration concerns.
- Hear the response. Correlate speech, transcript, tool proposal, result, and delivery in one case. Stage boundaries give the next investigation places to look.
Fused voice
Architecture sketch of the historical comparison. Realtime sessions can expose events and transcripts; fused does not mean unobservable.
- Speech enters. Audio enters the realtime session. Turn detection and interruption handling still matter.
- One voice model. Speech understanding and speech generation share a realtime model session. Tool calls are proposals sent to the application.
- Application executes. Application code validates the proposed action, executes the tool, and sends the result back to the session. The speech model does not own the side effect.
- Audio returns. The session continues with the tool result and produces audio. Natural turn shape did not compensate for the historical workflow’s unreliable actions.
Stitched pipeline
Historical internal baseline: around 40 of 50 tool triggers; roughly 1.2 seconds overall. Neither number is a current benchmark or a stage allocation.
- Speech enters. Keep the incoming speech and its turn boundary tied to one trace.
- Inspect hearing. Speech-to-text exposes what the decision model received. Compare this transcript with the intended utterance before changing a prompt.
- Inspect the decision. The text model proposes a tool call. The trace exposes its tool name and arguments separately from speech generation.
- Validate and execute. The application validates the proposal against screen state and allowed transitions, executes the tool, and returns the result to the text model.
- Inspect delivery. After the tool result informs the response, text-to-speech generates audio. Playback and cancellation remain application orchestration concerns.
- Hear the response. Correlate speech, transcript, tool proposal, result, and delivery in one case. Stage boundaries give the next investigation places to look.
Set the product’s acceptance bar
Choose an acceptable wait and number of correct actions. Compare both architectures against those constraints, then inspect the stage budgets.
A hypothetical, serial budget for one tool-using turn. Every number is an editable assumption, separate from the article’s historical POC. Bars group component time; the text-model budget includes both decision and continuation after the tool. Real stages may overlap; network delay, retries, and jitter need separate measurement.
STT → text model → TTS
Vertical mark: 1400 ms limit · 150 ms remaining
43 / 50 correct · outlined cell marks the required 42.
Meets both constraints
Action threshold met. Waiting budget met.
Realtime voice session
Vertical mark: 1400 ms limit · 500 ms remaining
38 / 50 correct · outlined cell marks the required 42.
Does not meet both constraints
4 more correct actions needed. Waiting budget met.
Change the assumed stage budgets
The grid is a chosen test result, not a statistical reliability estimate or a benchmark. A faster path does not automatically meet the action contract; more checkpoints do not automatically make a path correct.
Measured in our rough internal harness, not a public benchmark.
Observed in the POC path and judged against the workflow tolerance.
The category has moved quickly; I would rerun the same evals before making the same call today.
- LiveKit model architecturesOfficial distinction between an STT–LLM–TTS pipeline and direct speech-to-speech models. The guide retains the historical internal results without assigning latency to individual stages.
- Application-side function executionThe application executes a proposed function and returns its result; a model tool call is not the side effect itself.
- OpenAI Realtime and audio guideThe current official framing for realtime sessions, voice-agent sessions, tools, and conversation state.
- LiveKit turn detection documentationBreaks voice timing into VAD, endpointing, interruption handling, and speech scheduling; those are the variables behind the delivery failures described here.
- Pipecat OpenAI Realtime function calling issueA concrete example of realtime voice tool calling getting tangled with context, transcription, and continuation behavior.
- LiveKit AgentsShows the current production components of a voice agent: STT/LLM/TTS pipelines, turn detection, tools, and tests.
- Need help building a real-time voice AI agentPractitioners compare platform choices through turn-taking and latency problems they encountered. I treat it as field context, not benchmark evidence.
What happened after
We shipped it. The reliability complaints stopped. And that "temporary" stitched architecture stayed the core of the product for about a year and a half, long past the point where anyone called it a compromise.
Continuing to patch prompts would have delayed an architectural change that the production evidence already supported. The 1.2-second response time was acceptable only because candidates valued a correct action more than the missing fraction of a second; another voice product could make the opposite trade.
Realtime voice models have improved since this decision. I would rerun the same evaluation before choosing an architecture today and let the new results, rather than the previous choice, decide.

