Conversazioni interattive con l'API Live

L'API Live consente interazioni vocali e video bidirezionali a bassa latenza con Gemini.

Questa guida spiega come impostare una conversazione interattiva bidirezionale, regolare le impostazioni audio, gestire le sessioni e altro ancora.

Modelli supportati

Puoi utilizzare l'API Live con i seguenti modelli:

Versione del modello Livello di disponibilità
gemini-live-2.5-flash GA privato*
gemini-live-2.5-flash-preview-native-audio Anteprima pubblica

* Contatta il rappresentante del team dedicato al tuo Account Google per richiedere l'accesso.

Avvia una conversazione

Console

  1. Apri Vertex AI Studio > Stream realtime.
  2. Fai clic su Avvia sessione per iniziare la conversazione.

Per terminare la sessione, fai clic su Interrompi sessione.

Python

Per attivare conversazioni interattive in tempo reale, esegui il seguente esempio su un computer locale con accesso a microfono e altoparlante (non un blocco note Colab). Questo esempio configura una conversazione con l'API, consentendoti di inviare prompt audio e ricevere risposte 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

Configura una conversazione con l'API che ti consente di inviare prompt di testo e ricevere risposte 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()
      

Avvia la conversazione, inserisci i prompt o digita q, quit o exit per uscire.

await main()
      

Modificare le impostazioni di lingua e voce

L'API Live utilizza Chirp 3 per supportare le risposte vocali sintetizzate in una varietà di voci e lingue HD. Per un elenco completo e le demo di ogni voce, vedi Chirp 3: voci in HD.

Per impostare la voce e la lingua della risposta:

Console

  1. Apri Vertex AI Studio > Stream realtime.
  2. Nell'expander Output, seleziona una voce dal menu a discesa Voce.
  3. Nello stesso riquadro espandibile, seleziona una lingua dal menu a discesa Lingua.
  4. Fai clic su Avvia sessione per avviare la sessione.

Python

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

Modificare le impostazioni di rilevamento dell'attività vocale

Il rilevamento dell'attività vocale (VAD) consente al modello di riconoscere quando una persona sta parlando. Ciò è essenziale per creare conversazioni naturali, in quanto consente a un utente di interrompere il modello in qualsiasi momento.

Il modello esegue automaticamente il rilevamento dell'attività vocale (VAD) su un flusso di input audio continuo. Puoi configurare le impostazioni VAD utilizzando il campo realtimeInputConfig.automaticActivityDetection del messaggio di configurazione. Quando VAD rileva un'interruzione, la generazione in corso viene annullata e ignorata. Nella cronologia della sessione vengono conservate solo le informazioni già inviate al cliente. Il server invia quindi un messaggio per segnalare l'interruzione.

Se il flusso audio si interrompe per più di un secondo (ad esempio, se l'utente disattiva il microfono), invia un evento audioStreamEnd per svuotare l'audio memorizzato nella cache. Il client può riprendere l'invio dei dati audio in qualsiasi momento.

In alternativa, disattiva il rilevamento automatico dell'attività vocale impostando realtimeInputConfig.automaticActivityDetection.disabled su true nel messaggio di configurazione. Con questa configurazione, il client rileva la voce dell'utente e invia activityStart e activityEnd messaggi nei momenti opportuni. Un audioStreamEnd non viene inviato. Le interruzioni sono contrassegnate da 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)}"))
      

Estendere una sessione

La durata massima predefinita di una sessione di conversazione è di 10 minuti. Una notifica goAway (BidiGenerateContentServerMessage.goAway) viene inviata al cliente 60 secondi prima della fine della sessione.

Puoi estendere la durata della sessione con incrementi di 10 minuti utilizzando l'SDK Gen AI. Non esiste un limite al numero di volte in cui puoi estendere una sessione. Per un esempio, vedi Attivare e disattivare la ripresa della sessione.

Finestra di contesto

La finestra contestuale dell'API Live viene utilizzata per archiviare i dati trasmessi in streaming in tempo reale (25 token al secondo (TPS) per l'audio e 258 TPS per il video) e altri contenuti, inclusi input di testo e output del modello.

Se la finestra contestuale supera la lunghezza massima (impostata utilizzando il cursore Dimensioni massime dei contenuti in Vertex AI Studio o trigger_tokens nell'API), i turni più vecchi vengono troncati utilizzando la compressione della finestra contestuale per evitare l'interruzione improvvisa della sessione. La compressione della finestra contestuale viene attivata quando la finestra contestuale raggiunge la lunghezza massima (impostata in Vertex AI Studio utilizzando il cursore Dimensioni del contesto target o utilizzando target_tokens nell'API) ed elimina le parti più vecchie della conversazione finché il conteggio totale dei token non torna a questa dimensione target.

Ad esempio, se la lunghezza massima del contesto è impostata su 32000 token e la dimensione target è impostata su 16000 token:

  1. Turno 1: inizia la conversazione. In questo esempio, la richiesta utilizza 12.000 token.
    • Dimensioni totali del contesto: 12.000 token
  2. Turno 2: fai un'altra richiesta. Questa richiesta utilizza altri 12.000 token.
    • Dimensione totale del contesto: 24.000 token
  3. Turno 3: fai un'altra richiesta. Questa richiesta utilizza 14.000 token.
    • Dimensione totale del contesto: 38.000 token

Poiché le dimensioni totali del contesto sono ora superiori al massimo di 32.000 token, viene attivata la compressione della finestra contestuale. Il sistema torna all'inizio della conversazione e inizia a eliminare i turni precedenti finché la dimensione totale dei token non è inferiore al target di 16.000 token:

  • Elimina Turno 1 (12.000 token). Il totale è ora di 26.000 token, che è ancora superiore al target di 16.000 token.
  • Elimina Turno 2 (12.000 token). Il totale è ora di 14.000 token.

Il risultato finale è che solo Turno 3 rimane nella memoria attiva e la conversazione continua da quel punto.

Le lunghezze minime e massime per la lunghezza del contesto e le dimensioni del target sono:

Impostazione (flag API) Valore minimo Valore massimo
Lunghezza massima del contesto (trigger_tokens) 5000 128.000
Dimensioni del contesto target (target_tokens) 0 128.000

Per impostare la finestra contestuale:

Console

  1. Apri Vertex AI Studio > Stream realtime.
  2. Fai clic per aprire il menu Avanzate.
  3. Nella sezione Contesto della sessione, utilizza il cursore Dimensione massima del contesto per impostare la dimensione del contesto su un valore compreso tra 5000 e 128.000.
  4. (Facoltativo) Nella stessa sezione, utilizza il cursore Dimensione contesto target per impostare la dimensione target su un valore compreso tra 0 e 128.000.

Python

Imposta i campi context_window_compression.trigger_tokens e context_window_compression.sliding_window.target_tokens nel messaggio di configurazione:

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

Sessioni simultanee

Puoi avere fino a 5000 sessioni simultanee per progetto.

Aggiornare le istruzioni di sistema durante una sessione

L'API Live ti consente di aggiornare le istruzioni di sistema durante una sessione attiva. Utilizzalo per adattare le risposte del modello, ad esempio modificando la lingua della risposta o il tono.

Per aggiornare le istruzioni di sistema a metà sessione, puoi inviare contenuti di testo con il ruolo system. L'istruzione di sistema aggiornata rimarrà in vigore per la sessione rimanente.

Python

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

Attivare e disattivare la ripresa della sessione

La ripresa della sessione ti consente di riconnetterti a una sessione precedente entro 24 ore. Ciò si ottiene memorizzando i dati memorizzati nella cache, inclusi testo, video, prompt audio e output del modello. Per questi dati memorizzati nella cache viene applicata la privacy a livello di progetto.

Per impostazione predefinita, la ripresa della sessione è disattivata.

Per attivare la funzionalità di ripresa della sessione, imposta il campo sessionResumption del messaggio BidiGenerateContentSetup. Se abilitata, il server acquisisce periodicamente uno snapshot dei contesti di sessione correnti memorizzati nella cache e lo archivia nella memoria interna.

Quando uno snapshot viene acquisito correttamente, viene restituito un resumptionUpdate con l'ID handle che puoi registrare e utilizzare in un secondo momento per riprendere la sessione dallo snapshot.

Ecco un esempio di attivazione della ripresa della sessione e recupero dell'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())
      

Per riprendere la sessione senza interruzioni, attiva la modalità trasparente:

Python

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

Una volta attivata la modalità trasparente, viene restituito esplicitamente l'indice del messaggio del client che corrisponde allo snapshot del contesto. In questo modo puoi identificare il messaggio del cliente che devi inviare di nuovo quando riprendi la sessione dal punto di ripresa.

Ulteriori informazioni

Per ulteriori informazioni sull'utilizzo dell'API Live, consulta: