Percakapan interaktif dengan Live API

Live API memungkinkan interaksi suara dan video dua arah dengan latensi rendah bersama Gemini.

Panduan ini membahas cara menyiapkan percakapan interaktif dua arah, menyesuaikan setelan audio, mengelola sesi, dan lainnya.

Model yang didukung

Anda dapat menggunakan Live API dengan model berikut:

Versi model Tingkat ketersediaan
gemini-live-2.5-flash GA Pribadi*
gemini-live-2.5-flash-preview-native-audio Pratinjau publik

* Hubungi perwakilan tim akun Google Anda untuk meminta akses.

Mulai percakapan

Konsol

  1. Buka Vertex AI Studio > Stream realtime.
  2. Klik Mulai sesi untuk memulai percakapan.

Untuk mengakhiri sesi, klik Hentikan sesi.

Python

Untuk mengaktifkan percakapan interaktif secara real-time, jalankan contoh berikut di komputer lokal dengan akses mikrofon dan speaker (bukan notebook Colab). Contoh ini menyiapkan percakapan dengan API, sehingga Anda dapat mengirim perintah audio dan menerima respons audio:

"""
# Installation
# on linux
sudo apt-get install portaudio19-dev

# on mac
brew install portaudio

python3 -m venv env
source env/bin/activate
pip install google-genai
"""

import asyncio
import pyaudio
from google import genai
from google.genai import types

CHUNK=4200
FORMAT=pyaudio.paInt16
CHANNELS=1
RECORD_SECONDS=5
MODEL = 'gemini-live-2.5-flash'
INPUT_RATE=16000
OUTPUT_RATE=24000

client = genai.Client(
    vertexai=True,
    project=GOOGLE_CLOUD_PROJECT,
    location=GOOGLE_CLOUD_LOCATION,
)
config = {
    "response_modalities": ["AUDIO"],
    "input_audio_transcription": {},  # Configure input transcription
    "output_audio_transcription": {},  # Configure output transcription
}

async def main():
    print(MODEL)
    p = pyaudio.PyAudio()
    async with client.aio.live.connect(model=MODEL, config=config) as session:
        #exit()
        async def send():
            stream = p.open(
                format=FORMAT, channels=CHANNELS, rate=INPUT_RATE, input=True, frames_per_buffer=CHUNK)
            while True:
                frame = stream.read(CHUNK)
                await session.send(input={"data": frame, "mime_type": "audio/pcm"})
                await asyncio.sleep(10**-12)
        async def receive():
            output_stream = p.open(
                format=FORMAT, channels=CHANNELS, rate=OUTPUT_RATE, output=True, frames_per_buffer=CHUNK)
            async for message in session.receive():
                if message.server_content.input_transcription:
                  print(message.server_content.model_dump(mode="json", exclude_none=True))
                if message.server_content.output_transcription:
                  print(message.server_content.model_dump(mode="json", exclude_none=True))
                if message.server_content.model_turn:
                    for part in message.server_content.model_turn.parts:
                        if part.inline_data.data:
                            audio_data=part.inline_data.data
                            output_stream.write(audio_data)
                            await asyncio.sleep(10**-12)
        send_task = asyncio.create_task(send())
        receive_task = asyncio.create_task(receive())
        await asyncio.gather(send_task, receive_task)

asyncio.run(main())
      

Python

Siapkan percakapan dengan API yang memungkinkan Anda mengirim perintah teks dan menerima respons audio:

# Set model generation_config
CONFIG = {"response_modalities": ["AUDIO"]}

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {bearer_token[0]}",
}

async def main() -> None:
    # Connect to the server
    async with connect(SERVICE_URL, additional_headers=headers) as ws:

        # Setup the session
        async def setup() -> None:
            await ws.send(
                json.dumps(
                    {
                        "setup": {
                            "model": "gemini-live-2.5-flash",
                            "generation_config": CONFIG,
                        }
                    }
                )
            )

            # Receive setup response
            raw_response = await ws.recv(decode=False)
            setup_response = json.loads(raw_response.decode("ascii"))
            print(f"Connected: {setup_response}")
            return

        # Send text message
        async def send() -> bool:
            text_input = input("Input > ")
            if text_input.lower() in ("q", "quit", "exit"):
                return False

            msg = {
                "client_content": {
                    "turns": [{"role": "user", "parts": [{"text": text_input}]}],
                    "turn_complete": True,
                }
            }

            await ws.send(json.dumps(msg))
            return True

        # Receive server response
        async def receive() -> None:
            responses = []

            # Receive chucks of server response
            async for raw_response in ws:
                response = json.loads(raw_response.decode())
                server_content = response.pop("serverContent", None)
                if server_content is None:
                    break

                model_turn = server_content.pop("modelTurn", None)
                if model_turn is not None:
                    parts = model_turn.pop("parts", None)
                    if parts is not None:
                        for part in parts:
                            pcm_data = base64.b64decode(part["inlineData"]["data"])
                            responses.append(np.frombuffer(pcm_data, dtype=np.int16))

                # End of turn
                turn_complete = server_content.pop("turnComplete", None)
                if turn_complete:
                    break

            # Play the returned audio message
            display(Markdown("**Response >**"))
            display(Audio(np.concatenate(responses), rate=24000, autoplay=True))
            return

        await setup()

        while True:
            if not await send():
                break
            await receive()
      

Mulai percakapan, masukkan perintah Anda, atau ketik q, quit, atau exit untuk keluar.

await main()
      

Mengubah setelan bahasa dan suara

Live API menggunakan Chirp 3 untuk mendukung respons ucapan yang disintesis dalam berbagai suara dan bahasa HD. Untuk mengetahui daftar lengkap dan demo setiap suara, lihat Chirp 3: Suara HD.

Untuk menyetel suara dan bahasa respons:

Konsol

  1. Buka Vertex AI Studio > Stream realtime.
  2. Di peluas Output, pilih suara dari drop-down Suara.
  3. Di perluasan yang sama, pilih bahasa dari menu drop-down Bahasa.
  4. Klik Mulai sesi untuk memulai sesi.

Python

config = LiveConnectConfig(
    response_modalities=["AUDIO"],
    speech_config=SpeechConfig(
        voice_config=VoiceConfig(
            prebuilt_voice_config=PrebuiltVoiceConfig(
                voice_name=voice_name,
            )
        ),
        language_code="en-US",
    ),
)
      

Mengubah setelan deteksi aktivitas suara

Deteksi aktivitas suara (VAD) memungkinkan model mengenali saat seseorang sedang berbicara. Hal ini penting untuk menciptakan percakapan yang alami, karena memungkinkan pengguna menginterupsi model kapan saja.

Model ini secara otomatis melakukan deteksi aktivitas suara (VAD) pada aliran input audio yang berkelanjutan. Anda dapat mengonfigurasi setelan VAD menggunakan kolom realtimeInputConfig.automaticActivityDetection dari pesan penyiapan. Saat VAD mendeteksi gangguan, pembuatan yang sedang berlangsung akan dibatalkan dan dibuang. Hanya informasi yang sudah dikirim ke klien yang dipertahankan dalam histori sesi. Kemudian, server akan mengirim pesan untuk melaporkan gangguan tersebut.

Jika streaming audio dijeda selama lebih dari satu detik (misalnya, jika pengguna menonaktifkan mikrofon), kirim peristiwa audioStreamEnd untuk menghapus semua audio yang di-cache. Klien dapat melanjutkan pengiriman data audio kapan saja.

Atau, nonaktifkan VAD otomatis dengan menyetel realtimeInputConfig.automaticActivityDetection.disabled ke true dalam pesan penyiapan. Dengan konfigurasi ini, klien mendeteksi ucapan pengguna dan mengirimkan pesan activityStart dan activityEnd pada waktu yang tepat. audioStreamEnd tidak dikirim. Interupsi ditandai dengan activityEnd.

Python

config = LiveConnectConfig(
    response_modalities=["TEXT"],
    realtime_input_config=RealtimeInputConfig(
        automatic_activity_detection=AutomaticActivityDetection(
            disabled=False,  # default
            start_of_speech_sensitivity=StartSensitivity.START_SENSITIVITY_LOW, # Either START_SENSITIVITY_LOW or START_SENSITIVITY_HIGH
            end_of_speech_sensitivity=EndSensitivity.END_SENSITIVITY_LOW, # Either END_SENSITIVITY_LOW or END_SENSITIVITY_HIGH
            prefix_padding_ms=20,
            silence_duration_ms=100,
        )
    ),
)

async with client.aio.live.connect(
    model=MODEL_ID,
    config=config,
) as session:
    audio_bytes = Path("sample.pcm").read_bytes()

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

    # if stream gets paused, send:
    # await session.send_realtime_input(audio_stream_end=True)

    response = []
    async for message in session.receive():
        if message.server_content.interrupted is True:
            # The model generation was interrupted
            response.append("The session was interrupted")

        if message.text:
            response.append(message.text)

    display(Markdown(f"**Response >** {''.join(response)}"))
      

Memperpanjang sesi

Durasi maksimum default sesi percakapan adalah 10 menit. Notifikasi goAway (BidiGenerateContentServerMessage.goAway) dikirim ke klien 60 detik sebelum sesi berakhir.

Anda dapat memperpanjang durasi sesi dalam kelipatan 10 menit menggunakan Gen AI SDK. Tidak ada batasan berapa kali Anda dapat memperpanjang sesi. Untuk contohnya, lihat Mengaktifkan dan menonaktifkan kelanjutan sesi.

Jendela konteks

Jendela konteks Live API digunakan untuk menyimpan data yang di-streaming secara real-time (25 token per detik (TPS) untuk audio dan 258 TPS untuk video) dan konten lainnya, termasuk input teks dan output model.

Jika periode konteks melebihi panjang maksimum (ditetapkan menggunakan penggeser Ukuran konten maksimum di Vertex AI Studio, atau trigger_tokens di API), giliran terlama akan dipangkas menggunakan kompresi periode konteks untuk mencegah penghentian sesi yang tiba-tiba. Kompresi jendela konteks dipicu setelah jendela konteks mencapai panjang maksimumnya (ditetapkan di Vertex AI Studio menggunakan penggeser Ukuran konteks target, atau menggunakan target_tokens di API) dan menghapus bagian percakapan yang paling lama hingga jumlah total token kembali ke ukuran target ini.

Misalnya, jika panjang konteks maksimum Anda ditetapkan ke 32000 token dan ukuran target Anda ditetapkan ke 16000 token:

  1. Giliran 1: Percakapan dimulai. Dalam contoh ini, permintaan menggunakan 12.000 token.
    • Ukuran total konteks: 12.000 token
  2. Giliran 2: Anda membuat permintaan lain. Permintaan ini menggunakan 12.000 token lainnya.
    • Ukuran total konteks: 24.000 token
  3. Giliran 3: Anda membuat permintaan lain. Permintaan ini menggunakan 14.000 token.
    • Total ukuran konteks: 38.000 token

Karena ukuran total konteks kini lebih tinggi dari maksimum 32.000 token, kompresi jendela konteks kini dipicu. Sistem akan kembali ke awal percakapan dan mulai menghapus giliran lama hingga total ukuran token kurang dari target 16.000 token:

  • Tindakan ini akan menghapus Turn 1 (12.000 token). Totalnya sekarang 26.000 token, yang masih lebih tinggi dari target 16.000 token.
  • Tindakan ini menghapus Turn 2 (12.000 token). Totalnya sekarang 14.000 token.

Hasil akhirnya adalah hanya Turn 3 yang tetap berada di memori aktif, dan percakapan berlanjut dari titik tersebut.

Panjang minimum dan maksimum untuk panjang konteks dan ukuran target adalah:

Setelan (flag API) Nilai minimum Nilai maksimum
Panjang konteks maksimum (trigger_tokens) 5.000 128.000
Ukuran konteks target (target_tokens) 0 128.000

Untuk menyetel jendela konteks:

Konsol

  1. Buka Vertex AI Studio > Stream realtime.
  2. Klik untuk membuka menu Lanjutan.
  3. Di bagian Konteks Sesi, gunakan penggeser Ukuran konteks maks untuk menetapkan ukuran konteks ke nilai antara 5.000 dan 128.000.
  4. (Opsional) Di bagian yang sama, gunakan penggeser Ukuran konteks target untuk menetapkan ukuran target ke nilai antara 0 dan 128.000.

Python

Tetapkan kolom context_window_compression.trigger_tokens dan context_window_compression.sliding_window.target_tokens dalam pesan penyiapan:

config = types.LiveConnectConfig(
      temperature=0.7,
      response_modalities=['TEXT'],
      system_instruction=types.Content(
          parts=[types.Part(text='test instruction')], role='user'
      ),
      context_window_compression=types.ContextWindowCompressionConfig(
          trigger_tokens=1000,
          sliding_window=types.SlidingWindow(target_tokens=10),
      ),
  )
      

Sesi serentak

Anda dapat memiliki hingga 5.000 sesi serentak per project.

Memperbarui petunjuk sistem selama sesi

Live API memungkinkan Anda memperbarui petunjuk sistem selama sesi aktif. Gunakan ini untuk menyesuaikan respons model, seperti mengubah bahasa respons atau mengubah gaya bahasa.

Untuk memperbarui petunjuk sistem di tengah sesi, Anda dapat mengirimkan konten teks dengan peran system. Petunjuk sistem yang diperbarui akan tetap berlaku untuk sesi yang tersisa.

Python

session.send_client_content(
      turns=types.Content(
          role="system", parts=[types.Part(text="new system instruction")]
      ),
      turn_complete=False
  )
      

Mengaktifkan dan menonaktifkan kelanjutan sesi

Lanjutan sesi memungkinkan Anda terhubung kembali ke sesi sebelumnya dalam waktu 24 jam. Hal ini dicapai dengan menyimpan data dalam cache, termasuk teks, video, perintah audio, dan output model. Privasi tingkat project diterapkan untuk data yang di-cache ini.

Secara default, kelanjutan sesi dinonaktifkan.

Untuk mengaktifkan fitur kelanjutan sesi, tetapkan kolom sessionResumption dari pesan BidiGenerateContentSetup. Jika diaktifkan, server akan mengambil snapshot konteks sesi yang di-cache saat ini secara berkala, dan menyimpannya di penyimpanan internal.

Saat snapshot berhasil diambil, resumptionUpdate akan ditampilkan dengan ID handle yang dapat Anda catat dan gunakan nanti untuk melanjutkan sesi dari snapshot.

Berikut adalah contoh pengaktifan kelanjutan sesi dan pengambilan ID handle:

Python

import asyncio
from google import genai
from google.genai import types

client = genai.Client(
    vertexai=True,
    project=GOOGLE_CLOUD_PROJECT,
    location=GOOGLE_CLOUD_LOCATION,
)
model = "gemini-live-2.5-flash"

async def main():
    print(f"Connecting to the service with handle {previous_session_handle}...")
    async with client.aio.live.connect(
        model=model,
        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:
        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

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

Untuk mencapai kelanjutan sesi yang lancar, aktifkan mode transparan:

Python

types.LiveConnectConfig(
            response_modalities=["AUDIO"],
            session_resumption=types.SessionResumptionConfig(
                transparent=True,
    ),
)
      

Setelah mode transparan diaktifkan, indeks pesan klien yang sesuai dengan snapshot konteks akan ditampilkan secara eksplisit. Hal ini membantu mengidentifikasi pesan klien mana yang perlu Anda kirim lagi, saat Anda melanjutkan sesi dari handle kelanjutan.

Informasi selengkapnya

Untuk mengetahui informasi selengkapnya tentang penggunaan Live API, lihat: