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가 단일 턴 내에서 중복된 연속 함수 호출을 실행하는 경우가 있습니다. 여기에는 다양한 매개변수를 반복하고 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 목록
    창이 비어 있는 유효한 쿼리 더 광범위한 질문이 실제로 도움이 됩니다. 합리적인 재시도를 한 번 실행합니다. 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 네이티브 오디오와 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를 제공하여 초기 기록을 설정합니다.

  • 생각: 프롬프트 수준의 사고방식 해킹 삭제: 오디오가 삭제되지 않도록 단계별 사고방식 스키마 또는 토큰 한도를 적용하려는 모든 프롬프트 텍스트를 삭제합니다.