Why Your AI Voice Agent Answers Twice Per Turn - Zian AI

Why Your AI Voice Agent Answers Twice Per Turn

Quick answer: Check the agent’s audio before anything else. In 11 public duplicate-reply reports on LiveKit Agents and Pipecat, read on 24 September 2026, the audio played once in 2 and only the record was doubled. Of the 9 that callers heard, a tool call triggered the second reply in 4. 3 of the 11 are still open.

This page covers one symptom: an agent that says the same reply twice inside a single caller turn. The cases come from the public trackers of LiveKit Agents and Pipecat, and they involve Google’s Gemini Live (including on Vertex AI), the xAI Grok realtime API, Cartesia and Inworld speech, Deepgram Flux, the Smart Turn detector and a Telnyx line. OpenAI’s GPT Live appears only in September’s release notes. Each fix was checked against release notes and, where possible, the published wheel on PyPI; the one exception, row 9, is marked in the table. If you have not yet chosen between the two frameworks, our comparison of LiveKit Agents and Pipecat covers that decision.

Why does my AI voice agent say the same thing twice?

“My agent says the same thing twice” covers two different faults. When the caller hears a reply twice, two generations reached the speaker. When the reply is only logged twice, one generation was spoken once and then written to your transcript, event log or model context twice. The fixes don’t overlap. Tuning turn detection won’t touch a logging fault, and deduplicating the transcript won’t stop a caller hearing the same sentence again.

If callers did hear it twice, ask what started the second generation. The nine heard cases have three triggers:

  • A tool call sat between the two replies (4 reports). The model spoke, called a tool, and then the framework asked it to speak again once the tool’s result came back. Or two parallel tool calls each started a generation.
  • The caller’s turn was split, paused or interrupted (3 reports). One inference started on part of what the caller said, another on all of it, or an interruption dropped words the caller had already heard, so the model said them again.
  • The caller typed instead of speaking (2 reports), both on Gemini Live through LiveKit Agents, and both fixed in releases now more than ten months old.

These are counts of reports, not of how often each fault happens on calls. A cause that’s easy to reproduce gets written up. One that only shows under telephony load may never be reported.

The first test: Heard or Logged?

Run this before changing anything. It needs one affected call.

  1. Export the call’s turn events as JSON lines, one event per line with a time in seconds (t), a type (user, assistant, or anything else, such as tool_call) and a text or tool name. On LiveKit Agents, use the conversation_item_added and function_tools_executed session events. On Pipecat, use the aggregators’ on_user_turn_stopped and on_assistant_turn_stopped plus the LLM service’s on_function_calls_started. We confirmed all of these names in the livekit-agents 1.8.3 and pipecat-ai 1.11.0 wheels.
  2. List the suspect pairs. python3 twice.py pairs call.jsonl prints every pair of non-empty assistant lines that follow each other with no caller line between them and are at least 60% alike word for word, or where the second repeats the first and then carries on. It also prints whatever sat between them. Empty assistant lines are skipped, because LiveKit can log an empty assistant item beside a tool call (the log in #2884 shows one), and it would otherwise hide the duplicate behind it.
  3. Check the agent’s own audio channel. python3 twice.py bursts call.wav START END 1 prints the speech bursts on channel 1 inside that window. Pipecat’s AudioBufferProcessor writes stereo recordings with the user on the left and the bot on the right, so channel 1 is the agent. If your recorder mixes both sides to mono, listen to the clip instead.
  4. Read the verdict. One burst where the log shows two lines means Logged. Two bursts means Heard, and the “between” column tells you which trigger to look at.

The whole script, standard library only:

#!/usr/bin/env python3
"""Heard or Logged? Find replies that appear twice in one turn, then check the audio.

pairs  LOG.jsonl                  list back-to-back assistant lines with no user line between
bursts CALL.wav START END [CH]    print speech bursts on one channel between START and END seconds
"""
import array, difflib, json, math, re, sys, wave

def words(s):
    return re.sub(r"[^a-z0-9' ]+", " ", s.lower()).split()

def pairs(path):
    events = sorted((json.loads(l) for l in open(path) if l.strip()), key=lambda e: e["t"])
    prev, between = None, []
    for e in events:
        if e["type"] == "user":
            prev, between = None, []
        elif e["type"] == "assistant":
            if not words(e.get("text", "")):
                continue
            if prev is not None:
                a, b = words(prev["text"]), words(e["text"])
                sim = difflib.SequenceMatcher(None, a, b).ratio()
                if sim >= 0.6 or (a and b[:len(a)] == a):
                    what = ", ".join(between) or "nothing"
                    print(f"t={prev['t']:.1f}s and t={e['t']:.1f}s  gap={e['t']-prev['t']:.1f}s  "
                          f"similarity={sim:.2f}  between: {what}")
            prev, between = e, []
        else:
            between.append(e["type"] + (":" + e["name"] if "name" in e else ""))

def bursts(path, start, end, ch=0, floor=0.02, gap=0.4):
    w = wave.open(path)
    rate, n_ch = w.getframerate(), w.getnchannels()
    assert w.getsampwidth() == 2, "expects 16-bit PCM"
    assert ch < n_ch, f"file has {n_ch} channel(s), no channel {ch}"
    w.setpos(int(start * rate))
    pcm = array.array("h", w.readframes(int((end - start) * rate)))[ch::n_ch]
    step, on, out = rate // 10, None, []
    for i in range(0, len(pcm) - step + 1, step):
        win = pcm[i:i + step]
        rms = math.sqrt(sum(x * x for x in win) / len(win)) / 32768
        t = start + i / rate
        if rms >= floor:
            if on is None or t - on[1] > gap:
                on = [t, t + 0.1]; out.append(on)
            else:
                on[1] = t + 0.1
    for s, e in out:
        print(f"speech {s:.1f}s to {e:.1f}s")
    print(f"{len(out)} burst(s) on channel {ch}")

if __name__ == "__main__":
    if sys.argv[1] == "pairs":
        pairs(sys.argv[2])
    else:
        bursts(sys.argv[2], float(sys.argv[3]), float(sys.argv[4]),
               int(sys.argv[5]) if len(sys.argv) > 5 else 0)

We tested it on a fixture before publishing it. The fixture is a synthetic event log of four caller turns with a matching 16 kHz stereo WAV file, built so that each turn tests one case: a reply logged twice but played once, a reply heard twice with a check_calendar tool call between the copies, a reply heard twice with nothing between, and one ordinary turn as a negative control. Here is the output:

t=2.0s and t=3.0s  gap=1.0s  similarity=1.00  between: nothing
t=8.0s and t=11.5s  gap=3.5s  similarity=0.74  between: tool_call:check_calendar, tool_result:check_calendar
t=18.0s and t=21.0s  gap=3.0s  similarity=1.00  between: nothing

The control turn wasn’t flagged. On the agent channel, the 0 to 5 second window (logged-only case) returned 1 burst. The 7 to 16 and 17 to 25 second windows (the two heard cases) each returned 2, and the control window, 26 to 30 seconds, returned 1.

Two limits. A pause longer than 0.4 seconds inside one reply shows up as two bursts, and a transcript time is often when the line was committed, not when it played, so widen the window by a few seconds and listen before you call it a duplicate. The burst count tells you which clip to play. You still have to play it.

Eleven documented cases, and how they were selected

On 24 September 2026 we ran three title searches through GitHub’s search API across the issue trackers of livekit/agents and pipecat-ai/pipecat: “twice”, “duplicate response” and “repeats itself”. They returned 18 issues. Eleven describe an agent’s reply appearing twice within one turn, in the audio or in the record. The other seven describe something else: an agent joining a room twice, a room-input start call made twice, a template rendering twice, a flush or stop event firing twice, frames delivered twice inside a parallel pipeline, and a function-call entry repeated in an API request log. We left those seven out. A title search misses reports worded differently, so treat the table as a sample of what people titled this way, not as every case there is. We opened each issue’s full body and timeline, and each release in the last column was checked against its notes, except row 9, where only the reporter names the version.

# Issue (opened) Reported on What fires the second reply Heard or logged State, read 24 Sep 2026 Fix in a release?
1 livekit/agents #6411 (13 Jul 2026) livekit-agents 1.5.1, xAI Grok realtime The model speaks and calls a tool in one response. The tool returns a value, so the framework generates a second reply Heard, about 0.3 s after the first Closed 20 Jul 2026 by a maintainer as an instruction issue. Linked PR #6480 still open No. The option PR #6480 adds is not in the livekit-agents 1.8.3 wheel
2 livekit/agents #4554 (19 Jan 2026) livekit-agents 1.3.11, Gemini Live on Vertex AI One spoken reply while the tool runs, another after its result Heard Closed 2 Feb 2026 by the reporter after a prompt instruction worked No code change
3 pipecat #4908 (29 Jun 2026) pipecat-ai 1.4.0 Parallel tool calls. A fast call’s result runs the model before its slow sibling registers, then the slow one runs it again Heard Open. PR #4945 open No. The same guard is still in the 1.11.0 wheel
4 pipecat #5091 (21 Jul 2026) pipecat-ai 1.5.0, Pipecat Flows, Deepgram Flux A tool handler moves the flow to a new node while the caller’s turn is still open. The node’s auto-run and the turn’s own completion both generate the opening line Heard Open. PR #5283 closed without merging on 13 Sep 2026 No. The run is still pushed unconditionally in the 1.11.0 wheel
5 livekit/agents #323 (26 May 2024) livekit-agents 0.7.x The first inference runs on a fraction of the caller’s words, the second on all of them Heard Closed 26 Jul 2024 by PR #528. Re-reported on 1.2.4 in Aug 2025; a later reporter was asked to open a new issue Yes, 0.8.1. PR #528 is titled for a flush fault, but its description reads “fix #323”. A user reported the symptom gone on the 0.8.0 pre-release
6 pipecat #4707 (11 Jun 2026) pipecat-ai 1.2.1, incomplete-turn filtering with Smart Turn Each inference fired inside one paused turn produced its own completion, and each one was spoken Heard, 2 to 3 times Closed 3 Jul 2026 by PR #4938 Yes, 1.5.0. The one-completion latch is in the 1.5.0 wheel and absent from 1.4.0
7 pipecat #4996 (10 Jul 2026) pipecat-ai 1.5.0, Telnyx at 8 kHz On barge-in, the interruption overtakes words already played. The context loses them, so the next reply repeats them Heard Open. PRs #5008 and #5896 open No. The reporter’s script still fails on 1.11.0 (our run)
8 livekit/agents #3870 (10 Nov 2025) livekit-agents 1.2.18, Gemini Live 2.5 Flash Typed input. A placeholder message started a second response Heard Closed 12 Nov 2025 by PR #3898 Yes, livekit-agents 1.3.1 (17 Nov 2025)
9 livekit/agents #2884 (12 Jul 2025) livekit-agents 1.1.6, Gemini Live 2.5 A typed chat message produced back-to-back duplicate responses, with or without tools Heard Closed 28 Jul 2025 by the reporter. Re-reported as #3870 Reporter says 1.2.1. No PR named
10 pipecat #5082 (20 Jul 2026) pipecat-ai 1.5.0, Cartesia Back-to-back responses. Text already spoken was emitted a second time as the audio context closed Logged. Audio played once Closed 24 Jul 2026, fixed by PR #5098 Yes, 1.7.0. Force-complete is scoped to one context in the 1.7.0 wheel
11 pipecat #3762 (17 Feb 2026) pipecat 0.0.99, Inworld text-to-speech A private text setting was forced on, so two text paths each ended the assistant turn Logged. “The agent speaks once” Closed as not planned, 30 Mar 2026 Configuration: remove the override

Closed doesn’t mean fixed. Of the eleven, 4 were closed by a merged pull request that shipped in a named release (rows 5, 6, 8 and 10), though row 5 was reported again on a much later version. 1 was closed by its reporter after a later release made the symptom go away, with no pull request tied to it (row 9). 3 were closed with no code change at all (rows 1, 2 and 11), and 3 are still open (rows 3, 4 and 7). So 4 of the 11 were closed without a pull request tied to the duplicate itself.

My agent repeats itself after a tool call

Four reports, the largest group.

Realtime models that speak and call a tool in the same response (rows 1 and 2). The #6411 reporter’s wire capture shows about 6.4 seconds of speech, then a function_call in the same response, executed with reply_required=True, then a fresh response.create: “The caller audibly hears the agent answer the same turn twice.” The maintainer saw it differently. The first message usually just announces the tool call, the second is built from the tool’s output, and “if for some tools a reply is not needed, you can just return None from the tool to skip the tool reply.” The livekit-agents 1.8.3 wheel does exactly that: returning None sets reply_required to false, and FunctionToolsExecutedEvent.cancel_tool_reply() does the same for a whole batch. On #4554 the maintainer’s advice was to fix it through the instructions, with the wording “call the tool directly without saying anything”, and the reporter confirmed it worked in the system prompt.

Neither fix is free. The #6411 reporter tried both app-side guards, and cancelling the continuation “froze the agent mid-call whenever the bundle was a filler”, because a line like “one moment” does need a reply after the tool returns. Nothing on the wire tells a filler from a complete answer at decision time. So decide per tool, not per session: a tool whose result the caller needs to hear keeps its reply, and a tool that only writes something down returns None.

Parallel tool calls on Pipecat (row 3). When one completion asks for two tools, the aggregator is supposed to run the model once, after the last result. The #4908 report shows a fast call’s result arriving before its slow sibling is marked in progress. The “last sibling” check can’t see a call that has been announced but not yet started, so the model runs early and then runs again, producing “two (often near-identical) spoken responses”. The check still filters on f is not None in the pipecat-ai 1.11.0 wheel, and the fix, PR #4945, is still open.

A flow that changes node mid-turn (row 4). In Pipecat Flows, a node transition queues its own model run by default. If the caller is still talking when it lands, the caller’s turn then runs the model again, and “the bot speaks the node’s opening message twice, back to back, with no user speech in between”. A pull request to hold the run until the turn ended was closed without merging on 13 September 2026. The reporter’s workaround, which they say has run in production for about two months, is a subclassed user aggregator that ignores the run while a turn is open.

A tool call that fires before the caller has finished is also a correctness problem, not just a repetition problem. That is covered separately in gating AI agent tool calls on an unfinished turn, which is about stopping a booking from being committed on half a sentence.

The caller paused, interrupted or typed

In the other five heard cases the trigger was the caller’s turn or input, not a tool.

A pause read as the end of the turn (rows 5 and 6). LiveKit #323, from May 2024, describes one inference on part of the caller’s words and a second on all of them. A LiveKit maintainer confirmed “a bug in the current voice assistant code”, and a user reported “no more issues with missing/duplicated responses” on the 0.8.0 pre-release. The pull request that closed it, shipped in 0.8.1, says “fix #323” in its description. A user reported the same pattern on livekit-agents 1.2.4 in August 2025, and a later reporter was asked to open a new issue. Pipecat #4707 is the same pattern two years later: with incomplete-turn filtering on, a caller thinking aloud made the Smart Turn detector fire several inferences in one turn, and every completion was spoken, the same question about six seconds apart. Pipecat 1.5.0 added a latch that speaks at most one completion at a time and drops later duplicates until a new caller turn begins or the caller resumes speaking. It is in the 1.5.0 wheel and not in 1.4.0.

An interruption that loses words the caller already heard (row 7). Still open. On Pipecat the interruption is a system frame, so it jumps ahead of word frames that have already played. The assistant turn is committed without its last words, and those words then land on the front of the next assistant message. The model never sees the ending it spoke, so it says it again. A maintainer questioned an earlier version of the reproduction; the thread has no maintainer reply to the corrected one, which needs only Pipecat’s own test harness and which the reporter found failing on 1.8.1 on 5 September. We ran it against pipecat-ai 1.11.0 on 24 September and got the same result: the context held “The pool opens” where the caller heard “The pool opens at six”, and “at six” leaked into the next turn. Barge-in faults also cause the opposite symptom, which is covered in why an AI voice agent interrupts itself on a false interruption.

Typed input on Gemini Live (rows 8 and 9). Both reports say audio input behaved and typed input doubled the reply. #3870 was fixed in livekit-agents 1.3.1 by stopping a placeholder message from starting its own response. If you’re on anything from 1.3.1 up, look elsewhere first.

When only the transcript says it twice

Two of the eleven are record faults: the caller heard the reply once. On Pipecat #5082, two responses sent back to back to Cartesia had the second response’s text emitted twice inside one audio context. One copy came from the word timestamps and one from the force-complete step when the context closed. Anything that collects text per context, such as an assistant context aggregator, ended up with the turn doubled. The fix in 1.7.0 scopes force-complete to one context, and we found that change in the 1.7.0 wheel. On Pipecat #3762, a team had forced a private setting on for Inworld speech, which created a second text path. The maintainers closed it as not planned and told them to remove the override.

A logged duplicate still matters, because the doubled text can reach the model’s context and the stored record. How a stored transcript drifts from the call is set out in whether your AI call transcript is a record of what was said.

What changed in September 2026

Four releases this month bear on this. One shipped without notes, and none of the other three’s notes calls anything a fix for replies spoken twice. Read each entry for what it says.

  • livekit-agents 1.8.2 (15 September). The notes list “fix(openai): ignore incomplete and duplicate GPT Live backend tool calls” (#7230). Its pull request says GPT Live “emits a second call when the same completed item is delivered again”, and that the deduplication “does not claim exactly-once execution across reconnects or responses”. The status check is in the livekit-plugins-openai 1.8.2 wheel and not in 1.8.1. The same notes list #7266, “continue GPT Live only once every backend call is answered”, and #7233, “prevent llm fallback retries after output”, whose pull request shows a retry after partial output producing “The answer.The answer.”
  • livekit-agents 1.8.3 reached PyPI on 23 September 2026. Its GitHub tag page carried no release notes when we read it on 24 September, so we make no claim about what it changes.
  • pipecat-ai 1.10.0 (on PyPI 12 September; changelog heading 11 September). Async function calls “whose result arrives before the conversation moves on are now recorded as ordinary tool results, without the deferred-result message that asks the LLM to convey them.” Version 1.11.0 extends the same behaviour to calls where only the assistant’s own filler landed while the tool ran.
  • pipecat-ai 1.11.0 (on PyPI 18 September; changelog heading 17 September). GeminiLiveLLMService “holds the bot turn open while Gemini reports interaction_status: IN_PROGRESS, so a reply that spans several turn_complete messages is recorded as a single assistant turn.” This needs google-genai 2.19.0 or later. We found the interaction_status handling in the 1.11.0 wheel. It changes how one reply is recorded, not whether it is spoken twice.

Fix it yourself, or hand it over

Every branch can be fixed in-house. What varies is how long the fix keeps costing you.

Your case Rows What to do What it costs to keep
Logged only 10, 11 Upgrade Pipecat to 1.7.0 or later, or remove the private override One upgrade and a re-run of the pairs check
Heard, and a release fixed it 5, 6, 8, 9 Pin at or above the fixing version: livekit-agents 1.3.1 or later covers rows 8 and 9, and pipecat-ai 1.5.0 or later covers row 6. Row 5’s fix shipped in 0.8.1, but the same pattern was reported again on 1.2.4, so an upgrade alone may not settle it A version floor in your lockfile
Heard, closed with no code change 1, 2 Per-tool: return None for write-only tools, keep the reply for tools the caller must hear, and instruct the model not to speak before calling Prompt drift. The #6411 reporter found reasoning realtime models ignoring that instruction
Heard, still open 3, 4, 7 Carry a local patch like the ones the reporters describe Re-verify the patch on every framework release

That last row is where the cost adds up. Between 5 and 23 September 2026, PyPI shows four livekit-agents releases (1.8.0 to 1.8.3) and three pipecat-ai releases (1.9.0 to 1.11.0): seven releases in nineteen days, each a reason to re-run your duplicate check before upgrading. One team with one flow can keep pace. A team running several agents usually can’t, and a local patch that silently stops applying is how the duplicate comes back.

That maintenance is the work a platform takes on. Zian, currently in partnership-application beta, runs autonomous phone, SMS, email and WhatsApp sales agents, supports private model deployment on customer infrastructure, and has been running outbound acquisition since 2017. Its learning engine tracks around 420,000 data points across more than 10,000 leads a day. Whoever runs your agents, ask them to run the Heard or Logged test on a sample of your own calls and show you the result.

What this page does not cover

A reply said twice in one turn is not an agent that greets the caller again partway through a call. That usually means the realtime session was replaced and took the context with it, diagnosed in why a voice agent greets the caller again after a mid-call reconnect. The seven search results left out of the table, such as events, frames or request-log entries firing twice, don’t describe a caller hearing a reply twice.

Where every figure on this page comes from

Figure Who published it Link Date read
18 issues from three title searches; 11 in scope GitHub search API over livekit/agents and pipecat-ai/pipecat (our query) github.com/livekit/agents/issues (title search) and github.com/pipecat-ai/pipecat/issues (title search) 24 September 2026
Row 1: livekit-agents 1.5.1; about 6.4 s of speech then a function_call; duplicate about 0.3 s later; closed 20 Jul 2026; return None advice; guard polarities both failed LiveKit maintainers and issue reporter github.com/livekit/agents/issues/6411 24 September 2026
PR #6480 (tool_reply_after_audio) open LiveKit contributor github.com/livekit/agents/pull/6480 24 September 2026
Row 2: livekit-agents 1.3.11; prompt workaround; closed 2 Feb 2026 LiveKit maintainers and issue reporter github.com/livekit/agents/issues/4554 24 September 2026
Row 3: pipecat-ai 1.4.0; parallel sibling guard; open, PR #4945 open Pipecat issue reporter and contributor github.com/pipecat-ai/pipecat/issues/4908 24 September 2026
Row 4: pipecat-ai 1.5.0 Flows; open; workaround in production about two months Pipecat issue reporter github.com/pipecat-ai/pipecat/issues/5091 24 September 2026
PR #5283 closed without merging, 13 Sep 2026 Pipecat contributor github.com/pipecat-ai/pipecat/pull/5283 24 September 2026
Row 5: livekit-agents 0.7.x; closed 26 Jul 2024; reported gone on 0.8.0 pre-release; re-reported on 1.2.4, Aug 2025 LiveKit maintainers and users github.com/livekit/agents/issues/323 24 September 2026
PR #528 description “fix #323” LiveKit maintainer github.com/livekit/agents/pull/528 24 September 2026
PR #528 listed in livekit-agents 0.8.1 notes LiveKit livekit-agents 0.8.1 release 24 September 2026
Row 6: pipecat-ai 1.2.1; spoken 2 to 3 times, about six seconds apart; closed 3 Jul 2026 Pipecat issue reporter and maintainers github.com/pipecat-ai/pipecat/issues/4707 24 September 2026
Row 7: pipecat-ai 1.5.0, Telnyx 8 kHz; still failing on 1.8.1 on 5 Sep 2026; PRs #5008 and #5896 open Pipecat issue reporter github.com/pipecat-ai/pipecat/issues/4996 24 September 2026
Row 7 script still failing on pipecat-ai 1.11.0 Zian (our own run of the reporter’s script) github.com/pipecat-ai/pipecat/issues/4996 24 September 2026
Row 8: livekit-agents 1.2.18; closed 12 Nov 2025 by PR #3898 LiveKit github.com/livekit/agents/issues/3870 24 September 2026
PR #3898 listed in livekit-agents 1.3.1 notes, 17 Nov 2025 LiveKit livekit-agents 1.3.1 release 24 September 2026
Row 9: livekit-agents 1.1.6; closed 28 Jul 2025; solved in 1.2.1 per reporter LiveKit issue reporter github.com/livekit/agents/issues/2884 24 September 2026
Row 10: pipecat-ai 1.5.0, Cartesia; closed 24 Jul 2026, fixed by PR #5098 Pipecat issue reporter and maintainers github.com/pipecat-ai/pipecat/issues/5082 24 September 2026
Row 11: pipecat 0.0.99, Inworld; closed as not planned 30 Mar 2026 Pipecat maintainers github.com/pipecat-ai/pipecat/issues/3762 24 September 2026
PR #4938 in 1.5.0; PR #5098 in 1.7.0; 1.10.0 and 1.11.0 entries quoted Pipecat Pipecat CHANGELOG.md 24 September 2026
livekit-agents 1.8.2 entries #7230, #7266, #7233; released 15 Sep 2026 LiveKit livekit-agents 1.8.2 release 24 September 2026
#7230 wording: second call on redelivery; no exactly-once claim LiveKit contributor github.com/livekit/agents/pull/7230 24 September 2026
#7233 wording: appends duplicate output LiveKit github.com/livekit/agents/pull/7233 24 September 2026
livekit-agents 1.8.3 tag, no notes LiveKit livekit-agents 1.8.3 tag 24 September 2026
Four livekit-agents releases, 5 to 23 Sep 2026 PyPI pypi.org/project/livekit-agents 24 September 2026
Three pipecat-ai releases, 11 to 18 Sep 2026 PyPI pypi.org/project/pipecat-ai 24 September 2026
Around 420,000 data points; more than 10,000 leads a day; since 2017 Zian (first-party figures released by the owner) zian.ai 24 September 2026

Frequently asked questions

Why does my AI voice agent say the same thing twice?

Either two replies were generated and both were played, or one reply was played once and recorded twice. Check the agent audio channel first. If the audio played twice, look at what sat between the two replies: in 11 public reports read on 24 September 2026, a tool call was the most common trigger, followed by a caller who paused or interrupted.

Why does my voice agent repeat itself after a function call?

Many realtime models speak and call a tool in the same response, then the framework asks the model to reply again once the tool returns. On LiveKit Agents a maintainer advised that a tool which needs no reply can return None to skip it, as written in LiveKit Agents issue 6411. Decide this per tool, because a filler line such as one moment still needs the second reply.

My transcript shows the reply twice but the recording does not. Is that a bug?

It is a fault in the record, not in the speech. Two documented Pipecat cases doubled text only: a Cartesia path bug fixed in version 1.7.0, and a configuration that forced a private Inworld text setting on. The doubled text can still reach the model context, so fix it even though callers never heard it.

Does upgrading LiveKit Agents or Pipecat fix duplicate replies?

For some causes. Typed input on Gemini Live was fixed in livekit-agents 1.3.1, and repeated completions in one paused turn were fixed in pipecat-ai 1.5.0. Three Pipecat reports remain open as at 24 September 2026, covering parallel tool calls, a flow node change during an open turn, and interruptions that lose words already played.

Can I stop the reply after a tool call in LiveKit Agents?

Yes. Return None from the tool, raise StopResponse, or call cancel_tool_reply on the function_tools_executed event, which sets reply_required to false for that batch. A proposed setting that skips the reply only when audio was already played is still an open pull request and is not in version 1.8.3.

Apply For Partnership

Related Blogs

Related from Zian AI