Gemini Live API の音声応答が 6 秒遅れる原因は thinking
リアルタイム音声対話の検証で、Gemini Live API にテキストを送ってから音声が返り始めるまでの時間を計測していました。最初の計測で、初動に 6 秒かかりました。
テキスト送信 → 最初の音声チャンク受信: 6,186ms会話として成立しない数字です。回線やモデルの地力の問題かと思いましたが、原因は設定でした。native audio モデルは thinking(思考モード)が既定で有効になっていて、音声を返す前に考え込んでいます。
まず実測
計測環境は次のとおりです(2026-08-18 計測)。
- Node 22 から WebSocket 直結(v1beta の
BidiGenerateContentを SDK なしで直接叩く構成) - データセンター級の回線
- テキストキューを注入して音声応答を受ける形。
responseModalities: ["AUDIO"]、outputAudioTranscription有効、contextWindowCompression有効 - 7 種類のテキストキューを順に送る 1 セッションを、条件ごとに実施
「テキスト送信から最初の音声チャンク受信まで」を初動遅延として、条件別の結果です。
- gemini-2.5-flash-native-audio-preview-12-2025 / thinking 既定(有効): 中央値 1,569ms、最悪値 5,399ms、応答率 7/7
- 同モデル / thinkingBudget: 0: 中央値 976ms、最悪値 1,300ms、応答率 7/7
- gemini-3.1-flash-live-preview / thinkingBudget: 0: 中央値 598ms、最悪値 719ms、応答率 7/7
数字を並べると中央値の差は 1.6 倍程度に見えますが、実際の体感を壊すのは分散です。thinking 有効時は 925〜5,399ms とばらつき、冒頭の 6,186ms のような外れ値も出ます。無効化すると 553〜1,300ms に収まりました。「たまに黙り込む」が消えるのが大きいです。
なお WebSocket の接続確立自体は全条件 340〜480ms で、ここは差がありません。遅いのは接続ではなく、最初の音声が出てくるまでです。
なぜ待たされるのか
公式ドキュメント(Live API guide、2026-08 時点)にこう書かれています。
Uses thinkingBudget to set the number of thinking tokens. Dynamic thinking is enabled by default.Gemini 2.5 系の native audio モデルは、応答の前に思考トークンを消費する動作が既定で有効です。テキストのチャット用途なら思考時間は品質との交換として受け入れられますが、音声対話では思考時間がそのまま沈黙になります。しかも dynamic(入力に応じて思考量が変わる)なので、遅延が読めません。分散が大きかったのはこのためです。
直し方
setup メッセージの generationConfig に thinkingConfig を足すだけです。
{
"setup": {
"model": "models/gemini-2.5-flash-native-audio-preview-12-2025",
"generationConfig": {
"responseModalities": ["AUDIO"],
"thinkingConfig": { "thinkingBudget": 0 }
},
"systemInstruction": { "parts": [{ "text": "..." }] },
"outputAudioTranscription": {},
"contextWindowCompression": { "slidingWindow": {} }
}
}これで初動の中央値は 976ms、最悪でも 1,300ms になりました。
3.1 系(gemini-3.1-flash-live-preview)の計測も同じ setup(thinkingBudget: 0 を指定)で行い、中央値 598ms でした。ただしドキュメント上、3.1 系の thinking の制御は thinkingLevel(minimal / low / medium / high)に変わっていて、既定は「レイテンシ最優先の minimal」と記載されています(2026-08 時点)。つまり 3.1 系は放っておいても考え込みにくい方向の既定です。既定で長考するのは 2.5 系 native audio の側で、今回の「6 秒」もそちらで起きました。
副次的に見つけたこと
thinking 有効時に、システムプロンプトで定義していた角括弧の舞台指示風テキスト([EVENT:PACK_COUNT n=0] のような形式)を、モデルが勝手に捏造して出力するのを 1 件観測しました。thinking を切ると、3.1 系ではゼロ、2.5 系でも 14 発話中 1 件まで減りました。因果を断定できるだけの試行数はありませんが、初動遅延を疑って thinking を切ったら別の事故モードも減った、という観測結果です。
どこまで信じてよい数字か
- どちらも preview モデルです。モデル ID と計測日(2026-08-18)を明記したのはそのためで、数字は世代が変わればずれます。ただ「native audio の初動が遅いときは、まず thinking の設定を疑う」という切り分け自体は、設定項目が残る限り使えます
- thinking を切るということは、思考が必要なタスクの品質を捨てるということです。今回の用途は短いテキストキューへの即応なので迷いませんでしたが、ツール呼び出しの判断や複雑な推論を音声セッション内でやらせるなら、
thinkingBudgetをゼロではなく小さい値にする選択肢もあります。そこの品質差は今回計測していません - 計測は 1 セッション×条件ごと 7 発話です。傾向をつかむには足りますが、統計的に厳密な比較ではありません
この構成で気をつけること
- native audio(2.5 系)の初動が数秒かかるときは、回線やモデルを疑う前に `thinkingConfig` を確認する
- 音声用途で即応が欲しいなら `thinkingBudget: 0`。分散が消えて最悪値が安定する
- preview モデルの数字は計測日つきで記録しておく。世代交代で前提ごと変わる
- 接続確立時間と初動遅延を分けて計測する。混ぜると原因を取り違える
初動 6 秒の正体が「既定で有効な思考モード」だったというのは、ドキュメントを最初から丁寧に読んでいれば気づけた話ではあります。ただ、テキスト用途の感覚で「thinking は明示的に有効化するもの」と思い込んでいると、まさか音声モデルが既定で長考するとは考えません。計測して初めて疑えた設定でした。