Gemini 2.5 Flash Live API ネイティブ音声から Gemini 3.8 Live に移行する

このドキュメントでは、Gemini 2.5 Flash Live API ネイティブ音声から Gemini 3.8 Live に移行する際に必要な変更について説明します。

関数呼び出しの変更

Gemini 2.5 Flash Live API ネイティブ音声サーバーでは、非同期ツール呼び出しが可能です。一方、Gemini 3.8 Live は、次の動作変更を伴う非同期関数呼び出しをサポートしています。

  • Gemini 3.8 Live は、関数宣言で設定に behavior=BLOCKING が宣言されている場合に、関数呼び出しのブロックをサポートします。ブロッキング関数呼び出しの実行中に新しい入力が受信されると、Live API サーバーは現在の関数呼び出しをキャンセルします。

  • scheduling=interrupt オプションから FunctionResponse オプションへの動作変更:

    FunctionResponse のスケジュール設定 発言中の参加者 Gemini 2.5 Flash Live API ネイティブ音声 Gemini 3.8 Live
    割り込む モデル アクティブなモデルの即時応答を停止し、ツールのレスポンスを再生します。 アクティブなモデルの即時応答を停止し、ツールの応答を再生します。
    割り込む ユーザー 直ちに中断し、ユーザーの音声に重ねてツールのレスポンスを再生します。 ユーザーが終了するまで待ってから、ツールのレスポンスを再生します。

冗長なスイープと関数呼び出しの再試行を軽減する

ツールが結果を返さない場合、Gemini 3.8 Live は 1 つのターン内で冗長な関数呼び出しを連続して行うことがあります。これには、応答前にさまざまなパラメータを繰り返したり、2 ~ 5 回スイープしたりすることが含まれます。この動作により、音声開始までの時間(TTFA)が増加し、不正確なフォールバック音声が生成されます。

冗長な連続関数呼び出しは、Gemini 3.8 Live がクエリの解決を試みていることが原因です。ツールが {"results": [], "total_available": 0} や None などの情報のないレスポンスや空のレスポンスを返した場合、モデルは「永続的に枯渇」、「クエリ ウィンドウが狭すぎる」、「無効な引数」を区別できません。モデルは、結果を改善するためにクエリを広げたり変更したりして、スイープを開始します。

次の補完的なプラクティスを適用します。

  • 有益な関数レスポンスを返す: すべてのツール レスポンスには、エラーまたは結果に関する情報が含まれている必要があります。これにより、Gemini 3.8 Live モデルが次の手順を把握できます。

    次の表に、ケース、モデルの回答方法、モデルを支援するために必要なペイロードの例を示します。

    ケース モデルがすべきこと 必須のペイロード コンテンツ
    結果を返さない有効なクエリ。再試行しても解決しません。 検索を停止し、お客様に通知して、代替案を提示します。 status: 'no_results'、
    retryable: false、
    および明確な説明文。
    無効な引数または存在しない引数(「プロバイダが間違っている」など)。 検索を中止し、お客様に明確化または確認を依頼します。 status: 'invalid_argument'、
    reason_code、
    retryable: false、
    valid_options リスト
    空のウィンドウを含む有効なクエリ。より広範なクエリは本当に役立ちます。 妥当な再試行を 1 回実行します。 status: 'no_results_in_range'、
    retryable: true、
    retry_hint

    次の例は、search_appointment が呼び出されたが、候補となる日付がすべて利用できないペイロードの例を示しています。ユーザーは、日付をスイープするのではなく、ベンダーを試すことを期待しています。

    def search_appointment(vendor: str, date: Datetime):
    
    # BEFORE (Invites Sweeping):
    {
      "results": [],
      "total_available": 0
    }
    
    # AFTER - Exhausted / Dead End (Stops Sweeping):
    {
      "results": [],
      "status": "no_availability",
      "retryable": false,
      "message": "No appointments are available for this provider for the foreseeable future. Searching other dates will not surface anything; openings only come from cancellations.",
      "suggested_next_step": "offer_waitlist_or_a_different_provider"
    }
    
    # AFTER - Invalid Argument (Prompts User Clarification):
    {
      "results": [],
      "status": "invalid_argument",
      "reason": "no_such_provider",
      "retryable": false,
      "message": "There is no provider named 'Mr. Johnson'. Ask the caller to confirm the name.",
      "valid_options": ["Dr. Johnson", "Dr. Chen"]
    }
    

    次の例は、check_user_account が完全一致を返さない場合の処理を示しています。期待される結果は、再試行するのではなく、検索クエリを変更するか、制御をユーザーに戻すことです。

    def check_user_account(user_name: str, phone_suffix: str):...
    
    # Checked user account but not existing
    # BEFORE: insufficient error information
    {
     "found": false,
     "matches": []
    }
    
    # AFTER: providing sufficient information to the LiveAPI to avoid further retries because the retries have been exhausted.
    {
     "status": "EXHAUSTED",
     "retryable": false,
     "search_criteria": {
       "name": "Alex Rivera",
       "phone_suffix": "4921"
     },
     "search_scope": "Checked active orders, archived accounts, and guest checkouts across all regions.",
     "guidance": "Exhaustive search completed with 0 matches. Do NOT retry with parameter substrings or variations. Inform the user that no account was found matching those details, and ask if they have an Order ID or billing email."
    }
    
  • システム指示の再試行ポリシー: システム指示で明示的な制約を使用して、情報提供型のレスポンスを補完します。

    "When a tool returns no results, tell the user the result before calling the
    tool again. If a call fails for a reason fundamental to the arguments (for
    example, the entity does not exist), do not silently retry with variations;
    ask the user to clarify or confirm. You may broaden a query once when a
    result set is simply empty. Do not run repeated searches with different
    parameters on your own initiative. Hard cap: Never issue more than two
    consecutive function calls without saying something back to the user."
    

セッション履歴の交換

Gemini 2.5 Flash Live API ネイティブ音声では、send_client_content は最初のターン前に履歴シードを設定し、セッション中に履歴を追加するために使用されます。

Gemini 3.8 Live で、send_client_content メソッドを使用して履歴シードを設定する場合は、設定メッセージの HistoryConfig セクションで initial_history_in_client_content=True を設定します。setup_complete を受け取った後。その後、turn_complete=True が設定されている最後のメッセージまで send_client_content を繰り返し呼び出して履歴を構築できます。

モデルの動作の違い

次の表に、Gemini 2.5 Flash Live API ネイティブ音声と Gemini 3.8 Live の音声、マルチモーダル、出力のモデル動作の違いを示します。

機能 Gemini 2.5 Flash Live API ネイティブ音声 Gemini 3.8 Live
アフェクティブ ダイアログ enable_affective_dialog フラグでサポートされています。 デフォルトで常に有効。
コンテキストに応じた音声にのみ対応 proactivity フラグでサポートされています。 デフォルトで常に有効。
画像または動画のフレーム トークン デフォルトのフレームあたりの予算を減らします。 画像フレームを渡す場合、media_resolution は常にサポートされます。費用と精度のバランスを取ることができます。
文字起こしとコンテンツ 安定したベースラインの文字起こし。 custom_vocabulary を追加して、分野固有の単語にバイアスを適用し、精度を高めることができます。

次の Python コードは、media_resolution と custom_vocabulary を設定する方法を示しています。

# Example: Setting media_resolution for image frames in Gemini 3.8 Live
from google import genai
from google.genai import types

client = genai.Client()

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    media_resolution=types.MediaResolution.MEDIA_RESOLUTION_LOW,  # or MEDIA_RESOLUTION_LOW or MEDIA_RESOLUTION_MEDIUM
)

async with client.aio.live.connect(
    model="gemini-3.8-live",
    config=config,
) as session:
    # Send image frames with the configured resolution budget
    ...


# Example: Setting custom_vocabulary for domain-specific word biasing in Gemini 3.8 Live
from google import genai
from google.genai import types

client = genai.Client()

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    input_audio_transcription=types.AudioTranscriptionConfig(
        custom_vocabulary=["Gemini", "MagicWord", "Lagrangian"],
    ),
)

async with client.aio.live.connect(
    model="gemini-3.8-live",
    config=config,
) as session:
    ...

サードパーティ フレームワークの互換性

以降のセクションでは、サードパーティのフレームワークが Gemini 3.8 Live と連携する仕組みについて説明します。

LiveKit

LiveKit の Google プラグイン RealtimeModel は Gemini 3.8 Live をサポートしていますが、LiveKit の Google プラグインでは次の設定はサポートされていません。

  • thinking_level
  • enable_affective_dialog
  • proactivity

LiveKit の Google プラグインは、Gemini 3.8 Live と連携させるために慎重な適応が必要となるため、使用する際は十分にご注意ください。

Pipecat

Pipecat は Gemini 3.8 Live をサポートしています。変更点は次のとおりです。

  • 思考の構成: Gemini 3.8 Live でサポートされていないため、思考レベルを削除しました。

  • Pipecat は、GeminiLiveLLMService コネクタを介して GoogleVertexLLMService を使用して Agent Platform エンドポイントを接続します。

ワイヤーレベルのトークン使用量テレメトリー

サーバーのターンごとに usage_metadata フレームが返されます。これは、Gemini 2.5 Flash Live API ネイティブ音声と Gemini 3.8 Live で一貫しています。使用状況メタデータは、キャッシュ保存されたトークン、ツール使用トークン、さまざまなモダリティのトークンなど、より細かく分類されます。

既知のモデルの制限事項と緩和策

Gemini 3.8 Live を使用してアプリケーションを開発する際の既知の制限事項と軽減策については、既知の制限事項をご覧ください。

移行チェックリスト

Gemini 2.5 Flash Live API ネイティブ音声から Gemini 3.8 Live に移行する際に使用できるクライアント移行チェックリストは次のとおりです。

  • 関数呼び出し:

    • 情報提供ツール レスポンス: すべてのツール ハンドラをリファクタリングして、明示的なステータス コード、再試行可能なフラグ、自然言語の説明を返すようにします。裸の None や空の {} を返すことはありません。

    • システム指示ポリシー: サイレント ツール再試行を禁止し、引数の失敗時にユーザーの確認を求め、連続するツール呼び出しを制限する明示的な制約を追加します。

    • ツール呼び出し ID の照合: FunctionResponse がすべてのツール応答で id=fc.id を渡すことを確認します。

    • 関数スケジューリングの動作の変更: ユーザーが話しているとき、scheduling=interrupt は scheduling=when_idle にダウングレードされ、よりスムーズなユーザー エクスペリエンスが提供されます。

  • セッション: send_client_content を制限: send_client_content を使用して、適切な HistoryConfig を指定することで初期履歴を設定します。

  • 思考: プロンプト レベルの思考ハックを削除: 音声のドロップを防ぐため、ステップバイステップの思考スキーマやトークン制限を強制しようとするプロンプト テキストをすべて削除します。