Get started with Live API

Live API cho phép bạn tương tác bằng giọng nói và video theo thời gian thực với độ trễ thấp với Gemini. Nó xử lý luồng âm thanh, video hoặc văn bản liên tục để đưa ra các câu trả lời bằng lời nói tức thì, giống như con người, tạo ra trải nghiệm trò chuyện tự nhiên cho người dùng.

Tổng quan về Live API

Live API cung cấp một bộ tính năng toàn diện như Phát hiện hoạt động bằng giọng nói, sử dụng công cụ và gọi hàm, quản lý phiên (để quản lý các cuộc trò chuyện kéo dài) và mã thông báo tạm thời (để xác thực an toàn phía máy khách).

Trang này giúp bạn bắt đầu với các ví dụ và mã mẫu cơ bản.

Ứng dụng mẫu

Hãy xem các ứng dụng mẫu sau đây minh hoạ cách sử dụng Live API cho các trường hợp sử dụng toàn diện:

Nền tảng tích hợp của đối tác

Nếu muốn có quy trình phát triển đơn giản hơn, bạn có thể sử dụng Daily, LiveKit hoặc Voximplant. Đây là những nền tảng đối tác bên thứ ba đã tích hợp Gemini Live API qua giao thức WebRTC để đơn giản hoá quá trình phát triển các ứng dụng âm thanh và video theo thời gian thực.

Trước khi bạn bắt đầu xây dựng

Bạn cần đưa ra 2 quyết định quan trọng trước khi bắt đầu xây dựng bằng Live API: chọn một mô hình và chọn một phương pháp triển khai.

Chọn một cấu trúc tạo âm thanh

Nếu bạn đang xây dựng một trường hợp sử dụng dựa trên âm thanh, thì lựa chọn mô hình của bạn sẽ xác định cấu trúc tạo âm thanh được dùng để tạo phản hồi âm thanh:

  • Âm thanh gốc: Tuỳ chọn này mang đến giọng nói tự nhiên và chân thực nhất, đồng thời cải thiện hiệu suất đa ngôn ngữ. Tính năng này cũng cho phép các tính năng nâng cao như đối thoại cảm xúc, âm thanh chủ động (trong đó mô hình có thể quyết định bỏ qua hoặc phản hồi một số thông tin đầu vào nhất định) và "suy nghĩ". Các mô hình âm thanh gốc sau đây hỗ trợ âm thanh gốc:
    • gemini-2.5-flash-preview-native-audio-dialog
    • gemini-2.5-flash-exp-native-audio-thinking-dialog
  • Âm thanh bán xếp tầng: Lựa chọn này sử dụng cấu trúc mô hình xếp tầng (đầu vào âm thanh gốc và đầu ra chuyển văn bản sang lời nói). Tính năng này mang lại hiệu suất và độ tin cậy cao hơn trong môi trường sản xuất, đặc biệt là khi sử dụng công cụ. Các mô hình sau đây hỗ trợ âm thanh bán xếp tầng:
    • gemini-live-2.5-flash-preview
    • gemini-2.0-flash-live-001

Chọn một phương pháp triển khai

Khi tích hợp với Live API, bạn cần chọn một trong các phương pháp triển khai sau:

  • Máy chủ với máy chủ: Phần phụ trợ của bạn kết nối với Live API bằng WebSockets. Thông thường, ứng dụng sẽ gửi dữ liệu phát trực tiếp (âm thanh, video, văn bản) đến máy chủ của bạn, sau đó máy chủ sẽ chuyển tiếp dữ liệu đó đến Live API.
  • Từ máy khách đến máy chủ: Mã giao diện người dùng của bạn kết nối trực tiếp với Live API bằng WebSockets để truyền phát dữ liệu, bỏ qua phần phụ trợ.

Bắt đầu

Ví dụ này đọc một tệp WAV, gửi tệp đó ở định dạng chính xác và lưu dữ liệu nhận được dưới dạng tệp WAV.

Bạn có thể gửi âm thanh bằng cách chuyển đổi âm thanh đó sang định dạng đơn âm 16 bit PCM, 16 kHz và bạn có thể nhận âm thanh bằng cách đặt AUDIO làm phương thức phản hồi. Đầu ra sử dụng tốc độ lấy mẫu là 24 kHz.

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())

JavaScript

// 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();

Bước tiếp theo