Get started with Live API

API Trực tiếp cho phép tương tác bằng giọng nói và video theo thời gian thực, độ trễ thấp với Gemini. Công cụ này xử lý các 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 thoạ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 diễn ra trong thời gian 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à chạy bằng 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:

Tích hợp đố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 hoặc LiveKit. Đây là các nền tảng đối tác bên thứ ba đã tích hợp API Gemini Live thông 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ắt đầu xây dựng

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

Chọn một mô hình

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ì mô hình bạn chọn sẽ xác định cấu trúc tạo âm thanh dùng để tạo phản hồi âm thanh:

  • Âm thanh gốc bằng Gemini 2.5 Flash: Tuỳ chọn này cung cấp giọng nói tự nhiên và chân thực nhất, đồng thời mang lại hiệu suất đa ngôn ngữ tốt hơn. Mô hình này cũng hỗ trợ các tính năng nâng cao như cuộc trò chuyện có cảm xúc (nhận biết 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ố dữ liệu đầ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 dạng thác nước bằng Gemini 2.0 Flash: Tuỳ chọn này có trong mô hình gemini-2.0-flash-live-001, sử dụng cấu trúc mô hình dạng thác nước (đầu vào âm thanh gốc và đầu ra văn bản sang lời nói). API 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ụ.

Chọn 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 API Trực tiếp bằng cách sử dụng WebSockets. Thông thường, ứng dụng khách sẽ gửi dữ liệu luồng (âm thanh, video, văn bản) đến máy chủ, sau đó máy chủ sẽ chuyển tiếp dữ liệu đó đến API Trực tiếp.
  • Khách hàng đến máy chủ: Mã giao diện người dùng kết nối trực tiếp với API trực tiếp bằng cách sử dụng WebSockets để truyền trực tuyến dữ liệu, bỏ qua phần phụ trợ.

Bắt đầu

Ví dụ này đọc 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 thành định dạng PCM 16 bit, 16 kHz, đơn âm 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(api_key="GEMINI_API_KEY")

# Half cascade model:
# model = "gemini-2.0-flash-live-001"

# 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({ apiKey: "GEMINI_API_KEY" });
// 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-2.0-flash-live-001"

// 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