Get started with Live API

Live API는 지연 시간이 짧은 Gemini와의 실시간 음성 및 동영상 상호작용을 지원합니다. 오디오, 동영상 또는 텍스트의 연속 스트림을 처리하여 즉각적이고 사람과 유사한 음성 응답을 제공하므로 사용자에게 자연스러운 대화형 환경을 제공합니다.

Live API 개요

Live API는 음성 활동 감지, 도구 사용 및 함수 호출, 세션 관리 (장기 대화 관리용), 일회성 토큰 (안전한 클라이언트 측 인증용)과 같은 포괄적인 기능 세트를 제공합니다.

이 페이지에서는 예시와 기본 코드 샘플을 통해 시작할 수 있습니다.

예시 애플리케이션

포괄적인 사용 사례에 Live API를 사용하는 방법을 보여주는 다음 예시 애플리케이션을 확인하세요.

  • JavaScript 라이브러리를 사용하여 Live API에 연결하고 마이크와 스피커를 통해 양방향 오디오를 스트리밍하는 AI Studio의 라이브 오디오 스타터 앱
  • Live API에 연결되는 Pyaudio를 사용하는 Live API Python 쿡북

파트너 연동

간단한 개발 프로세스를 선호하는 경우 Daily, LiveKit 또는 Voximplant를 사용할 수 있습니다. 이러한 플랫폼은 WebRTC 프로토콜을 통해 Gemini Live API를 이미 통합하여 실시간 오디오 및 동영상 애플리케이션 개발을 간소화한 서드 파티 파트너 플랫폼입니다.

빌드를 시작하기 전에

Live API로 빌드를 시작하기 전에 모델 선택과 구현 접근 방식 선택이라는 두 가지 중요한 결정을 내려야 합니다.

오디오 생성 아키텍처 선택

오디오 기반 사용 사례를 빌드하는 경우 모델 선택에 따라 오디오 응답을 만드는 데 사용되는 오디오 생성 아키텍처가 결정됩니다.

  • 네이티브 오디오: 이 옵션은 가장 자연스럽고 사실적인 음성과 더 나은 다국어 성능을 제공합니다. 또한 정서적 (감정 인식) 대화, 선제적 오디오 (모델이 특정 입력을 무시하거나 응답할 수 있음), '생각'과 같은 고급 기능을 사용할 수 있습니다. 네이티브 오디오는 다음 네이티브 오디오 모델에서 지원됩니다.
    • gemini-2.5-flash-preview-native-audio-dialog
    • gemini-2.5-flash-exp-native-audio-thinking-dialog
  • 하프 캐스케이드 오디오: 이 옵션은 캐스케이드 모델 아키텍처 (네이티브 오디오 입력 및 텍스트 음성 변환 출력)를 사용합니다. 특히 도구 사용과 관련하여 프로덕션 환경에서 더 나은 성능과 안정성을 제공합니다. 하프 캐스케이드 오디오는 다음 모델에서 지원됩니다.
    • gemini-live-2.5-flash-preview
    • gemini-2.0-flash-live-001

구현 접근 방식 선택

Live API와 통합할 때는 다음 구현 접근 방식 중 하나를 선택해야 합니다.

  • 서버 간: 백엔드가 WebSockets를 사용하여 Live API에 연결됩니다. 일반적으로 클라이언트는 스트림 데이터 (오디오, 동영상, 텍스트)를 서버로 전송하고 서버는 이를 Live API로 전달합니다.
  • 클라이언트-서버: 프런트엔드 코드가 WebSockets을 사용하여 Live API에 직접 연결하여 백엔드를 우회하여 데이터를 스트리밍합니다.

시작하기

이 예에서는 WAV 파일을 읽고 올바른 형식으로 전송하며 수신된 데이터를 WAV 파일로 저장합니다.

오디오를 16비트 PCM, 16kHz, 모노 형식으로 변환하여 전송할 수 있으며, AUDIO를 응답 모달리티로 설정하여 오디오를 수신할 수 있습니다. 출력은 샘플링 레이트 24kHz를 사용합니다.

Python

# Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
# Install helpers for converting files: pip install librosa soundfile
import asyncio
import io
from pathlib import Path
import wave
from google import genai
from google.genai import types
import soundfile as sf
import librosa

client = genai.Client()

# Half cascade model:
# model = "gemini-live-2.5-flash-preview"

# Native audio output model:
model = "gemini-2.5-flash-preview-native-audio-dialog"

config = {
  "response_modalities": ["AUDIO"],
  "system_instruction": "You are a helpful assistant and answer in a friendly tone.",
}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:

        buffer = io.BytesIO()
        y, sr = librosa.load("sample.wav", sr=16000)
        sf.write(buffer, y, sr, format='RAW', subtype='PCM_16')
        buffer.seek(0)
        audio_bytes = buffer.read()

        # If already in correct format, you can use this:
        # audio_bytes = Path("sample.pcm").read_bytes()

        await session.send_realtime_input(
            audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
        )

        wf = wave.open("audio.wav", "wb")
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)  # Output is 24kHz

        async for response in 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())

자바스크립트

// Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';  // npm install wavefile
const { WaveFile } = pkg;

const ai = new GoogleGenAI({});
// WARNING: Do not use API keys in client-side (browser based) applications
// Consider using Ephemeral Tokens instead
// More information at: https://ai.google.dev/gemini-api/docs/ephemeral-tokens

// Half cascade model:
// const model = "gemini-live-2.5-flash-preview"

// Native audio output model:
const model = "gemini-2.5-flash-preview-native-audio-dialog"

const config = {
  responseModalities: [Modality.AUDIO], 
  systemInstruction: "You are a helpful assistant and answer in a friendly tone."
};

async function live() {
    const responseQueue = [];

    async function waitMessage() {
        let done = false;
        let message = undefined;
        while (!done) {
            message = responseQueue.shift();
            if (message) {
                done = true;
            } else {
                await new Promise((resolve) => setTimeout(resolve, 100));
            }
        }
        return message;
    }

    async function handleTurn() {
        const turns = [];
        let done = false;
        while (!done) {
            const message = await waitMessage();
            turns.push(message);
            if (message.serverContent && message.serverContent.turnComplete) {
                done = true;
            }
        }
        return turns;
    }

    const session = await ai.live.connect({
        model: model,
        callbacks: {
            onopen: function () {
                console.debug('Opened');
            },
            onmessage: function (message) {
                responseQueue.push(message);
            },
            onerror: function (e) {
                console.debug('Error:', e.message);
            },
            onclose: function (e) {
                console.debug('Close:', e.reason);
            },
        },
        config: config,
    });

    // Send Audio Chunk
    const fileBuffer = fs.readFileSync("sample.wav");

    // Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
    const wav = new WaveFile();
    wav.fromBuffer(fileBuffer);
    wav.toSampleRate(16000);
    wav.toBitDepth("16");
    const base64Audio = wav.toBase64();

    // If already in correct format, you can use this:
    // const fileBuffer = fs.readFileSync("sample.pcm");
    // const base64Audio = Buffer.from(fileBuffer).toString('base64');

    session.sendRealtimeInput(
        {
            audio: {
                data: base64Audio,
                mimeType: "audio/pcm;rate=16000"
            }
        }

    );

    const turns = await handleTurn();

    // Combine audio data strings and save as wave file
    const combinedAudio = turns.reduce((acc, turn) => {
        if (turn.data) {
            const buffer = Buffer.from(turn.data, 'base64');
            const intArray = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Int16Array.BYTES_PER_ELEMENT);
            return acc.concat(Array.from(intArray));
        }
        return acc;
    }, []);

    const audioBuffer = new Int16Array(combinedAudio);

    const wf = new WaveFile();
    wf.fromScratch(1, 24000, '16', audioBuffer);  // output is 24kHz
    fs.writeFileSync('audio.wav', wf.toBuffer());

    session.close();
}

async function main() {
    await live().catch((e) => console.error('got error', e));
}

main();

다음 단계

  • 음성 활동 감지 및 네이티브 오디오 기능을 비롯한 주요 기능과 구성을 알아보려면 전체 Live API 기능 가이드를 참고하세요.
  • 도구 사용 가이드를 읽고 Live API를 도구 및 함수 호출과 통합하는 방법을 알아보세요.
  • 장기 실행 대화를 관리하려면 세션 관리 가이드를 참고하세요.
  • 클라이언트-서버 애플리케이션에서 보안 인증을 위해 임시 토큰 가이드를 읽어보세요.
  • 기본 WebSockets API에 관한 자세한 내용은 WebSockets API 참조를 참고하세요.