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
    interrupt モデル アクティブなモデルの応答をすぐに停止し、ツールのレスポンスを再生します。 アクティブなモデルの応答をすぐに停止し、ツールのレスポンスを再生します。
    割り込み ユーザー すぐに中断し、ユーザーにツールのレスポンスを再生します。 ユーザーが終了するまで待ってから、ツールのレスポンスを再生します。

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

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 を受け取った後。その後、send_client_content を繰り返し呼び出して、turn_complete=True が設定されている最後のメッセージまで履歴を構築できます。

セッション中のシステム指示とツールの更新

Gemini 2.5 Flash Live API ネイティブ音声では、system ロールでクライアント コンテンツを送信して、セッション中にシステム指示を更新します。

Gemini 3.8 Live では、Google Gen AI SDK で send_context_update を呼び出すか、WebSocket 経由で context_update メッセージを送信します。システム指示、ツールのリスト、またはその両方を置き換えることができます。詳細については、Gemini 3.8 Live でシステム指示とツールを更新するをご覧ください。

モデルの動作の違い

次の表に、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 を指定して初期履歴を設定します。

  • セッション: context_update でコンテキストを更新する: system ロールを使用するセッション内のシステム指示の更新を、Google Gen AI SDK の send_context_update 呼び出し、または WebSocket 経由の context_update メッセージに置き換えます。

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