Voice Agents Go Silent While Tools Run. Google's ADK Fix: Streaming Tools and response_scheduling
Google's Oct 19 guide shows how ADK streaming tools, background execution and response_scheduling keep a Gemini Live voice agent talking during slow tool calls. What it claims, the patterns, and the production cautions it lists.
In text chat, a slow tool call shows a spinner. In a voice call, it is silence, and users assume the call dropped.
Google's October 19 guide, Build a Voice Agent That Never Goes Silent using ADK, covers how to avoid that in the Agent Development Kit (ADK) with gemini-3.8-live. This article summarizes the guide. All numbers and behaviors are Google's, from its own demo workflow. I have not run the code.
The problem
A standard ADK tool is an async def that returns once. Google says that during a Gemini Live session (run_live), the loop waits for that return before the model generates more turns. If the tool takes 13 seconds, the agent is silent for 13 seconds. Prompting the model to "tell the user you are working on it" does not fix it, the guide says, because the model's turn is blocked waiting for the function response.
Google's headline number: in its benchmark sales-report workflow on gemini-3.8-live, switching from a blocking tool to a streaming tool cut the time to the agent's first words from 14.4 seconds to 1.2 seconds. That is one workflow, built by the vendor to show the feature.
Google is also clear on the limit: non-blocking tools do not make the backend faster. A 13-second query still takes 13 seconds. What changes is what the user hears.
Pattern 1: streaming tools
When a job has real stages, make the tool an async generator and change return to yield. Per the guide, ADK then marks the tool declaration as NON_BLOCKING and immediately sends the model a status acknowledgement, so the agent can speak right away. Each yield is sent as a partial function response, and the model paraphrases it. Google notes narration can trail the tool by several seconds. If the user asks something unrelated mid-job, the agent can answer without cancelling the task.
Google lists three production cautions:
- Single-flight calls. Models may try to call the tool again if prompted repeatedly. Put "Call this ONCE" in the docstring and consider an in-memory latch or idempotency key.
- Cancellation. Include a function named
stop_streaming(function_name: str)in the tools list. ADK intercepts it and cancels the generator'sasyncio.Task, raisingasyncio.CancelledErrorin your function so you can close connections cleanly. - Barge-in does not cancel tools. When the user talks over the agent, the Live API stops the model's output and ADK emits an event with
interrupted=Trueso the client can stop audio. Running tools are not cancelled and their results are still delivered. To stop one, the model has to callstop_streaming.
Pattern 2: background execution
When the wait has no story, Google suggests running quietly. Two approaches:
- Single-yield generator. An async generator that yields once, on completion. ADK issues an immediate pending response, so the agent acknowledges the request, stays quiet during the work, then presents results when ready or when the user finishes speaking.
FunctionToolwithresponse_scheduling. Keep a plain coroutine, wrap it inFunctionTool, and setresponse_scheduling = types.FunctionResponseScheduling.WHEN_IDLE. The guide notes the trade-off: with a return-once coroutine the model gets nothing until the function finishes, so it typically does not say an initial acknowledgement unless the user keeps talking. A note says that in ADK 2.10 and later you can setbehavior = types.Behavior.NON_BLOCKINGinstead.
Controlling when the result lands
response_scheduling sets when the model reacts to an incoming tool response. In Google's benchmark sessions on gemini-3.8-live:
- WHEN_IDLE: never cuts into a turn in progress. A report waited while the model finished a separate 20-second answer, then was delivered.
- INTERRUPT: the result cut off current speech mid-sentence, then the model finished its answer and added the figures.
- SILENT: the result went into conversation history for later turns without an announcement.
Execution shape (streaming versus single return) and delivery timing are independent and can be combined. On a streaming tool, a response_scheduling setting stamps every partial update. Per the guide, in ADK 2.8 and newer a streaming tool can choose scheduling per update by yielding types.FunctionResponse with a scheduling value, for example SILENT for intermediate progress and WHEN_IDLE for the final result.
Google's rule of thumb: if the wait has a story, stream it. If it is just a wait, run it in the background and let the result land when idle.
Requirements as stated
google-adk >= 2.10.0gemini-3.8-liveon Gemini Enterprise- A bidirectional live session (
run_live)
What I would check
These are my own untested suggestions.
1. Time your own tools first. If most finish in under a second or two, none of this matters.
2. Test the single-flight problem on purpose by asking for the same thing twice.
3. Decide what happens on barge-in. Google says the tool keeps running, so a user who says "never mind" needs a path to stop_streaming.
4. Choose scheduling per tool. A critical alert and a background report probably want different modes.
5. Listen to recordings. Google notes narration can lag, and no benchmark replaces hearing it.
What I would not conclude
- That 14.4 seconds to 1.2 seconds applies to your workflow. It is one vendor demo.
- That the model will narrate well. Google says the model paraphrases updates, and the exact words are its choice.
- That it works outside the stated setup. Requirements are specific to ADK 2.10+, a live session and
gemini-3.8-live.
Frequently asked questions
Why does a voice agent go silent during a tool call?
Per Google, the live loop waits for a standard tool's single return before generating more model turns.
What is a streaming tool in ADK?
An async generator tool that uses yield. ADK marks it NON_BLOCKING and sends partial updates the model can narrate.
Does this make my backend faster?
No. Google says a 13-second query still takes 13 seconds. Only the conversational experience changes.
What does WHEN_IDLE do?
It delivers the tool result at the next natural pause instead of cutting into a turn in progress.
Does interrupting the agent cancel a running tool?
Not according to the guide. Barge-in stops audio, but tools keep running and results are delivered. The model must call stop_streaming.
Can the model call a streaming tool twice?
Google says it may, and suggests a "Call this ONCE" docstring plus an idempotency key or latch.
What versions do I need?
The guide lists google-adk >= 2.10.0 and gemini-3.8-live on Gemini Enterprise, with run_live sessions.
Sources
- Google Developers Blog, Step by Step guide: Build a Voice Agent That Never Goes Silent using ADK (October 19, 2026): all claims above. I could not view its two summary table images, so I relied on the text.
Related reading
- Google's AQuA Reads Your Production Agent's Traces. What It Does, What It Costs, and What Google Has Not Shown
Google open-sourced AQuA, an ambient quality agent that samples production sessions, clusters failures and diagnoses them against deployed source. What Google's post says, with its own numbers and limits.
- GPT-6.1 Sol Ultrafast Costs 6x More for Up to 8x the Speed. Decide Where Latency Is Worth Buying
OpenAI added an Ultrafast tier to GPT-6.1 Sol. Here is what the published price, plan limits, and speed claim say, and a simple way to decide which agent steps deserve a faster, more expensive route.
The build log
Follow the work.
New essays and prototypes, in your feed reader. Email subscriptions are paused while I connect a working delivery service. No email is collected here.
Follow via RSS