ブログ一覧

Gemini Live API にテキストを送っても音声が返らない原因

更新: Web開発者向け

リアルタイム音声対話の検証で、アプリ側から Gemini Live API にテキストを送り、それをきっかけに喋らせる仕組みを作っていました。clientContent でテキストを送ったのに、音声が返ってきません。エラーも返ってきません。転写も、ターン終了のイベントも、何も来ません。

原因は送信メッセージの 1 フィールドでした。`turnComplete: false` で送ったテキストは、完全に無視されます。

まず実測

7 種類のテキストキュー × 2 モデルで、turnComplete の値だけを変えて比較しました(2026-08-18 計測、v1beta の WebSocket 直結)。

  • gemini-2.5-flash-native-audio-preview-12-2025
    • turnComplete: true: 7/7 応答(初動の中央値 976ms)
    • turnComplete: false: 0/7。完全に無応答
  • gemini-3.1-flash-live-preview
    • turnComplete: true: 7/7 応答(初動の中央値 598ms)
    • turnComplete: false: 0/7。完全に無応答

false のときに何が返ってくるかというと、何も返ってきません。音声チャンクなし、転写なし、turnComplete イベントなし、そしてエラーもなしです。接続は生きたまま、ただ沈黙します。ここがハマりどころで、エラーが返れば送信側を疑えますが、無言で無視されると「モデルが不調なのか」「接続が死んでいるのか」「送り方が悪いのか」の切り分けから始めることになります。

なぜ無視されるのか

turnComplete は「ユーザーのターンがここで終わった」という宣言です。false は「まだ入力の途中」を意味するので、モデルは続きを待ちます。仕様として一貫した動作ではあります。

問題は、テキストを分割送信したい場面や「文脈だけ渡して応答はさせたくない」場面で false を使いたくなることです。少なくとも「あとで true を送れば溜めた分に応答してくれるだろう」という期待で false を使うと、応答が来ない理由を延々と探すことになります。アプリ主導でテキストキューを送って喋らせたいなら、答えは単純で、毎回 `turnComplete: true` で送ることです。

{
  "clientContent": {
    "turns": [{ "role": "user", "parts": [{ "text": "[PHASE:OPENING]" }] }],
    "turnComplete": true
  }
}

ドキュメントとの食い違い

もうひとつ書き残しておくべきことがあります。公式の capabilities ガイド(2026-08 時点)には、3.1 系 live モデルについてこう書かれています。

send_client_content is only supported for seeding initial context history (requires setting initial_history_in_client_content in session config). To send text updates during the conversation, use send_realtime_input instead.

つまり 3.1 系では clientContent は初期履歴の投入専用で、会話中のテキストは realtimeInput で送れ、という記述です。しかし上の実測のとおり、gemini-3.1-flash-live-preview は会話中の clientContentturnComplete: true)に 7/7 で応答しました。initial_history_in_client_content は設定していません。

どちらを信じるべきかで言えば、設計はドキュメントに寄せておくのが安全です。実測で動いているのは事実ですが、「ドキュメント上サポート外の経路がたまたま動いている」状態は、ドキュメントに明記された動作より先に消える可能性があります。私は当面 clientContent + turnComplete: true で運用しつつ、3.1 系に本格移行する時点で realtimeInput への切り替えを検証項目に入れています。

事前に心配していた事故は起きなかった

テキストキュー方式で心配していたのは、注入したテキストにモデルが口頭で返事してしまうこと(「了解です」と喋ってしまう)でした。これは 35 発話で 0 件でした。ただし条件付きです。システムプロンプトに「角括弧内は舞台指示。読み上げない。返事もしない」と明記した上での数字です。

代わりに実在した事故モードは転写への混入です。2.5 系で 14 発話中 1 件、角括弧テキスト([RIPPING] など)がそのまま出力転写に混ざりました。3.1 系では 0 件でした。転写をそのまま UI に出す設計なら、角括弧のフィルタを 1 枚挟んでおく必要があります。

この構成で気をつけること

  • テキストを送って喋らせたいなら `turnComplete: true`false は両モデルで完全に無視される(2026-08-18 実測)
  • 無視は無言で起きる。エラーが返らないので、応答がないときはまずこのフィールドを確認する
  • 3.1 系の clientContent は、ドキュメント上は初期履歴シード専用。実測では応答するが、恒久的な設計は realtimeInput 側に寄せておく
  • 舞台指示テキストは「読み上げない・返事しない」をシステムプロンプトに明記する。それでも転写混入は起き得るので、転写を表示するならフィルタを挟む

preview モデルでの計測なので、この挙動自体が今後変わる可能性はあります。ただ「応答がない、エラーもない」という症状に当たったとき、turnComplete が最初の容疑者になることは覚えておいて損がありません。

関連

この記事をシェア