Live API

Live API를 사용하면 지연 시간이 짧은 Gemini와의 양방향 음성 및 동영상 상호작용이 가능합니다. Live API를 사용하면 최종 사용자에게 자연스럽고 인간과 같은 음성 대화 환경을 제공하고 음성 명령을 사용하여 모델의 응답을 중단할 수 있습니다. 이 모델은 텍스트, 오디오, 동영상 입력을 처리하고 텍스트 및 오디오 출력을 제공할 수 있습니다.

Google AI Studio에서 Live API를 사용해 볼 수 있습니다.

새로운 소식

Live API에 새로운 기능과 기능이 추가되었습니다.

새로운 기능:

  • 구성 가능한 출력 언어와 함께 2개의 새로운 음성 및 30개의 새로운 언어
  • 구성 가능한 이미지 해상도 66/256 토큰
  • 구성 가능한 회전 범위: 항상 모든 입력을 전송하거나 사용자가 말할 때만 전송
  • 입력이 모델을 중단해야 하는지 여부 구성
  • 구성 가능한 음성 활동 감지 및 대화 종료 신호의 새 클라이언트 이벤트
  • 토큰 수
  • 스트림 종료 신호를 위한 클라이언트 이벤트
  • 텍스트 스트리밍
  • 서버에 24시간 동안 세션 데이터를 저장하는 구성 가능한 세션 재개
  • 슬라이딩 컨텍스트 창을 사용한 더 긴 세션 지원

새로운 고객 이벤트:

  • 오디오 스트림 종료 / 마이크 닫힘
  • 회전 전환을 수동으로 제어하기 위한 활동 시작/종료 이벤트

새로운 서버 이벤트:

  • 세션을 다시 시작해야 한다는 알림이 사라짐
  • 생성 완료

Live API 사용

이 섹션에서는 SDK 중 하나와 함께 Live API를 사용하는 방법을 설명합니다. 기본 WebSockets API에 관한 자세한 내용은 WebSockets API 참조를 참고하세요.

문자 메시지 주고받기

import asyncio
from google import genai

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        while True:
            message = input("User> ")
            if message.lower() == "exit":
                break
            await session.send_client_content(
                turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
            )

            async for response in session.receive():
                if response.text is not None:
                    print(response.text, end="")

if __name__ == "__main__":
    asyncio.run(main())

오디오 수신

다음 예는 오디오 데이터를 수신하여 .wav 파일에 쓰는 방법을 보여줍니다.

import asyncio
import wave
from google import genai

client = genai.Client(api_key="GEMINI_API_KEY", http_options={'api_version': 'v1alpha'})
model = "gemini-2.0-flash-live-001"

config = {"response_modalities": ["AUDIO"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        wf = wave.open("audio.wav", "wb")
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)

        message = "Hello? Gemini are you there?"
        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for idx,response in async_enumerate(session.receive()):
            if response.data is not None:
                wf.writeframes(response.data)

            # Un-comment this code to print audio data info
            # if response.server_content.model_turn is not None:
            #      print(response.server_content.model_turn.parts[0].inline_data.mime_type)

        wf.close()

if __name__ == "__main__":
    asyncio.run(main())

오디오 형식

Live API는 다음 오디오 형식을 지원합니다.

  • 입력 오디오 형식: 16kHz little-endian의 원시 16비트 PCM 오디오
  • 출력 오디오 형식: 24kHz little-endian의 원시 16비트 PCM 오디오

오디오 및 동영상 스트리밍

시스템 안내

시스템 안내를 사용하면 특정 요구사항 및 사용 사례에 따라 모델의 동작을 조정할 수 있습니다. 시스템 안내는 설정 구성에서 설정할 수 있으며 전체 세션 동안 적용됩니다.

from google.genai import types

config = {
    "system_instruction": types.Content(
        parts=[
            types.Part(
                text="You are a helpful assistant and answer in a friendly tone."
            )
        ]
    ),
    "response_modalities": ["TEXT"],
}

증분 콘텐츠 업데이트

증분 업데이트를 사용하여 텍스트 입력을 전송하거나, 세션 컨텍스트를 설정하거나, 세션 컨텍스트를 복원합니다. 짧은 컨텍스트의 경우 세부 경로 상호작용을 전송하여 정확한 이벤트 시퀀스를 나타낼 수 있습니다.

PythonJSON
turns = [
    {"role": "user", "parts": [{"text": "What is the capital of France?"}]},
    {"role": "model", "parts": [{"text": "Paris"}]},
]

await session.send_client_content(turns=turns, turn_complete=False)

turns = [{"role": "user", "parts": [{"text": "What is the capital of Germany?"}]}]

await session.send_client_content(turns=turns, turn_complete=True)
{
  "clientContent": {
    "turns": [
      {
        "parts":[
          {
            "text": ""
          }
        ],
        "role":"user"
      },
      {
        "parts":[
          {
            "text": ""
          }
        ],
        "role":"model"
      }
    ],
    "turnComplete": true
  }
}

컨텍스트가 긴 경우 후속 상호작용을 위해 컨텍스트 창을 확보할 수 있도록 단일 메시지 요약을 제공하는 것이 좋습니다.

음성 변경

Live API는 Puck, Charon, Kore, Fenrir, Aoede, Leda, Orus, Zephyr 음성을 지원합니다.

음성을 지정하려면 speechConfig 객체 내에서 음성 이름을 세션 구성의 일부로 설정합니다.

PythonJSON
from google.genai import types

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    speech_config=types.SpeechConfig(
        voice_config=types.VoiceConfig(
            prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Kore")
        )
    )
)
{
  "voiceConfig": {
    "prebuiltVoiceConfig": {
      "voiceName": "Kore"
    }
  }
}

함수 호출 사용

Live API를 사용하여 도구를 정의할 수 있습니다. 함수 호출에 관한 자세한 내용은 함수 호출 튜토리얼을 참고하세요.

도구는 세션 구성의 일부로 정의되어야 합니다.

config = types.LiveConnectConfig(
    response_modalities=["TEXT"],
    tools=[set_light_values]
)

async with client.aio.live.connect(model=model, config=config) as session:
    await session.send_client_content(
        turns={
            "role": "user",
            "parts": [{"text": "Turn the lights down to a romantic level"}],
        },
        turn_complete=True,
    )

    async for response in session.receive():
        print(response.tool_call)

모델은 단일 프롬프트에서 여러 함수 호출과 출력을 연결하는 데 필요한 코드를 생성할 수 있습니다. 이 코드는 샌드박스 환경에서 실행되어 후속 BidiGenerateContentToolCall 메시지를 생성합니다. 각 함수 호출의 결과를 사용할 수 있을 때까지 실행이 일시중지되므로 순차 처리가 보장됩니다.

클라이언트는 BidiGenerateContentToolResponse로 응답해야 합니다.

오디오 입력과 오디오 출력은 모델의 함수 호출 사용 능력에 부정적인 영향을 미칩니다.

방해 요소 처리

사용자는 언제든지 모델의 출력을 중단할 수 있습니다. 음성 활동 감지 (VAD)가 중단을 감지하면 진행 중인 생성이 취소되고 삭제됩니다. 이미 클라이언트로 전송된 정보만 세션 기록에 보관됩니다. 그런 다음 서버는 중단을 보고하기 위해 BidiGenerateContentServerContent 메시지를 전송합니다.

또한 Gemini 서버는 대기 중인 모든 함수 호출을 삭제하고 취소된 호출의 ID가 포함된 BidiGenerateContentServerContent 메시지를 전송합니다.

async for response in session.receive():
    if response.server_content.interrupted is not None:
        # The generation was interrupted

음성 활동 감지 (VAD) 구성

기본적으로 모델은 연속 오디오 입력 스트림에서 음성 활동 감지 (VAD)를 자동으로 실행합니다. VAD는 설정 구성realtimeInputConfig.automaticActivityDetection 필드로 구성할 수 있습니다.

오디오 스트림이 1초 이상 일시중지되면 (예: 사용자가 마이크를 껐기 때문에) 캐시된 오디오를 플러시하기 위해 audioStreamEnd 이벤트를 전송해야 합니다. 클라이언트는 언제든지 오디오 데이터 전송을 재개할 수 있습니다.

또는 설정 메시지에서 realtimeInputConfig.automaticActivityDetection.disabledtrue로 설정하여 자동 VAD를 사용 중지할 수 있습니다. 이 구성에서 클라이언트는 사용자 음성을 감지하고 적절한 시점에 activityStartactivityEnd 메시지를 전송합니다. 이 구성에서는 audioStreamEnd가 전송되지 않습니다. 대신 스트림이 중단되면 activityEnd 메시지로 표시됩니다.

이 기능에 대한 SDK 지원은 앞으로 몇 주 이내에 제공될 예정입니다.

토큰 수 가져오기

소비된 총 토큰 수는 반환된 서버 메시지의 usageMetadata 필드에서 확인할 수 있습니다.

from google.genai import types

async with client.aio.live.connect(
    model='gemini-2.0-flash-live-001',
    config=types.LiveConnectConfig(
        response_modalities=['AUDIO'],
    ),
) as session:
    # Session connected
    while True:
        await session.send_client_content(
            turns=types.Content(role='user', parts=[types.Part(text='Hello world!')])
        )
        async for message in session.receive():
            # The server will periodically send messages that include
            # UsageMetadata.
            if message.usage_metadata:
                usage = message.usage_metadata
                print(
                    f'Used {usage.total_token_count} tokens in total. Response token'
                    ' breakdown:'
                )
            for detail in usage.response_tokens_details:
                match detail:
                  case types.ModalityTokenCount(modality=modality, token_count=count):
                      print(f'{modality}: {count}')

            # For the purposes of this example, placeholder input is continually fed
            # to the model. In non-sample code, the model inputs would come from
            # the user.
            if message.server_content and message.server_content.turn_complete:
                break

세션 재개 구성

서버가 주기적으로 WebSocket 연결을 재설정할 때 세션 종료를 방지하려면 설정 구성 내에서 sessionResumption 필드를 구성합니다.

이 구성을 전달하면 서버가 SessionResumptionUpdate 메시지를 전송합니다. 이 메시지는 마지막 재개 토큰을 후속 연결의 SessionResumptionConfig.handle로 전달하여 세션을 재개하는 데 사용할 수 있습니다.

from google.genai import types

print(f"Connecting to the service with handle {previous_session_handle}...")
async with client.aio.live.connect(
    model="gemini-2.0-flash-live-001",
    config=types.LiveConnectConfig(
        response_modalities=["AUDIO"],
        session_resumption=types.SessionResumptionConfig(
            # The handle of the session to resume is passed here,
            # or else None to start a new session.
            handle=previous_session_handle
        ),
    ),
) as session:
    # Session connected
    while True:
        await session.send_client_content(
            turns=types.Content(
                role="user", parts=[types.Part(text="Hello world!")]
            )
        )
        async for message in session.receive():
            # Periodically, the server will send update messages that may
            # contain a handle for the current state of the session.
            if message.session_resumption_update:
                update = message.session_resumption_update
                if update.resumable and update.new_handle:
                    # The handle should be retained and linked to the session.
                    return update.new_handle

            # For the purposes of this example, placeholder input is continually fed
            # to the model. In non-sample code, the model inputs would come from
            # the user.
            if message.server_content and message.server_content.turn_complete:
                break

세션 연결이 끊기기 전에 메시지 수신

서버는 현재 연결이 곧 종료됨을 알리는 GoAway 메시지를 전송합니다. 이 메시지에는 남은 시간을 나타내는 timeLeft가 포함되며, 연결이 ABORTED로 종료되기 전에 추가 조치를 취할 수 있습니다.

생성이 완료되면 메시지 수신

서버는 모델이 응답 생성을 완료했음을 알리는 generationComplete 메시지를 전송합니다.

컨텍스트 창 압축 사용 설정

세션을 더 길게 사용하고 갑작스러운 연결 종료를 방지하려면 contextWindowCompression 필드를 세션 구성의 일부로 설정하여 컨텍스트 창 압축을 사용 설정할 수 있습니다.

ContextWindowCompressionConfig에서 슬라이딩 창 메커니즘과 압축을 트리거하는 토큰 수를 구성할 수 있습니다.

from google.genai import types

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    context_window_compression=(
        # Configures compression with default parameters.
        types.ContextWindowCompressionConfig(
            sliding_window=types.SlidingWindow(),
        )
    ),
)

미디어 해상도 변경

mediaResolution 필드를 세션 구성의 일부로 설정하여 입력 미디어의 미디어 해상도를 지정할 수 있습니다.

from google.genai import types

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

제한사항

프로젝트를 계획할 때는 Live API 및 Gemini 2.0의 다음 제한사항을 고려하세요.

클라이언트 인증

Live API는 서버 간 인증만 제공하며 직접 클라이언트에서 사용하지 않는 것이 좋습니다. Live API와 안전하게 인증하려면 클라이언트 입력을 중간 애플리케이션 서버를 통해 라우팅해야 합니다.

세션 시간

세션 압축을 사용 설정하면 세션 시간을 무제한으로 연장할 수 있습니다. 압축을 사용하지 않으면 오디오 전용 세션은 15분으로 제한되고 오디오 및 동영상 세션은 2분으로 제한됩니다. 압축 없이 이 한도를 초과하면 연결이 종료됩니다.

컨텍스트 윈도우

세션의 컨텍스트 윈도우 한도는 32,000개의 토큰입니다.

타사 통합

웹 및 모바일 앱 배포의 경우 다음 옵션을 살펴볼 수 있습니다.