Transmisión bidireccional con la API de Gemini Live 


Gemini Live API permite interacciones bidireccionales de texto y voz de baja latencia con Gemini. Con Live API, puedes brindarles a los usuarios finales la experiencia de conversaciones de voz naturales y similares a las humanas, con la capacidad de interrumpir las respuestas del modelo con comandos de texto o voz. El modelo puede procesar entradas de texto y audio (próximamente, también de video) y proporcionar salidas de texto y audio.

Puedes crear prototipos con instrucciones y el Live API en Vertex AI Studio.

La API de Live API es una API con estado que crea una conexión WebSocket para establecer una sesión entre el cliente y el servidor de Gemini. Para obtener más detalles, consulta la documentación de referencia de Live API.

Antes de comenzar

Solo está disponible cuando usas Vertex AI Gemini API como tu proveedor de la API.

Si aún no lo has hecho, completa la guía de introducción, en la que se describe cómo configurar tu proyecto de Firebase, conectar tu app a Firebase, agregar el SDK, inicializar el servicio de backend para Vertex AI Gemini API y crear una instancia de LiveModel.

Modelos que admiten esta capacidad

Live API solo es compatible con gemini-2.0-flash-live-preview-04-09 (no con gemini-2.0-flash).

Ten en cuenta también que gemini-2.0-flash-live-preview-04-09 solo se admite en la ubicación us-central1.

Usa las funciones estándar de Live API

En esta sección, se describe cómo usar las funciones estándar de Live API, específicamente para transmitir varios tipos de entradas y salidas:

Genera texto transmitido a partir de una entrada de texto transmitida

Antes de probar esta muestra, completa la sección Antes de comenzar de esta guía para configurar tu proyecto y tu app.
En esa sección, también harás clic en un botón para el proveedor de Gemini API que elijas, de modo que veas contenido específico del proveedor en esta página.

Puedes enviar entradas de texto transmitidas y recibir salidas de texto transmitidas. Asegúrate de crear una instancia de liveModel y establecer la modalidad de respuesta en Text.

Swift

La función Live API aún no es compatible con las apps para plataformas de Apple, pero vuelve a consultar pronto.

Kotlin

// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
val model = Firebase.ai(backend = GenerativeBackend.vertexAI(location = "us-central1")).liveModel(
    modelName = "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to respond with text
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.TEXT 
   }
)

val session = model.connect()

// Provide a text prompt
val text = "tell a short story"

session.send(text)

var outputText = ""
session.receive().collect {
    if(it.status == Status.TURN_COMPLETE) {
        // Optional: if you don't require to send more requests.
        session.stopReceiving();
    }
    outputText = outputText + it.text
}

// Output received from the server.
println(outputText)

Java

ExecutorService executor = Executors.newFixedThreadPool(1);
// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
LiveGenerativeModel lm = FirebaseAI.getInstance(GenerativeBackend.vertexAI("us-central1")).liveModel(
        "gemini-2.0-flash-live-preview-04-09",
        // Configure the model to respond with text
        new LiveGenerationConfig.Builder()
                .setResponseModalities(ResponseModality.TEXT)
                .build()
);
LiveModelFutures model = LiveModelFutures.from(lm);
ListenableFuture<LiveSession> sessionFuture =  model.connect();
class LiveContentResponseSubscriber implements Subscriber<LiveContentResponse> {
    @Override
    public void onSubscribe(Subscription s) {
        s.request(Long.MAX_VALUE); // Request an unlimited number of items
    }
    @Override
    public void onNext(LiveContentResponse liveContentResponse) {
       // Handle the response from the server.
	System.out.println(liveContentResponse.getText());
    }
    @Override
    public void onError(Throwable t) {
        System.err.println("Error: " + t.getMessage());
    }
    @Override
    public void onComplete() {
        System.out.println("Done receiving messages!");
    }
}
Futures.addCallback(sessionFuture, new FutureCallback<LiveSession>() {
    @Override
    public void onSuccess(LiveSession ses) {
	  LiveSessionFutures session = LiveSessionFutures.from(ses);
        // Provide a text prompt
        String text = "tell me a short story?";
        session.send(text);
        Publisher<LiveContentResponse> publisher = session.receive();
        publisher.subscribe(new LiveContentResponseSubscriber());
    }
    @Override
    public void onFailure(Throwable t) {
        // Handle exceptions
    }
}, executor);

Web

La función Live API aún no es compatible con las apps web, pero vuelve a consultar pronto.

Dart

import 'package:firebase_ai/firebase_ai.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

late LiveModelSession _session;

await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);

// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
final model = FirebaseAI.vertexAI(location: 'us-central1').liveModel(
  model: 'gemini-2.0-flash-live-preview-04-09',
  // Configure the model to respond with text
  config: LiveGenerationConfig(responseModalities: [ResponseModality.text]),
);

_session = await model.connect();

// Provide a text prompt
final prompt = Content.text('tell a short story');
await _session.send(input: prompt, turnComplete: true);

// In a separate thread, receive the response
await for (final message in _session.receive()) {
   // Process the received message 
}

Unity

using Firebase;
using Firebase.AI;

async Task SendTextReceiveText() {
  // Initialize the Vertex AI Gemini API backend service
  // Set the location to `us-central1` (the flash-live model is only supported in that location)
  // Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
  var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI(location: "us-central1")).GetLiveModel(
    modelName: "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to respond with text
    liveGenerationConfig: new LiveGenerationConfig(
        responseModalities: new[] { ResponseModality.Text })
  );

  LiveSession session = await model.ConnectAsync();

  // Provide a text prompt
  var prompt = ModelContent.Text("tell a short story");
  await session.SendAsync(content: prompt, turnComplete: true);

  // Receive the response
  await foreach (var message in session.ReceiveAsync()) {
    // Process the received message
    if (!string.IsNullOrEmpty(message.Text)) {
      UnityEngine.Debug.Log("Received message: " + message.Text);
    }
  }
}

Genera audio transmitido a partir de una entrada de audio transmitido

Antes de probar esta muestra, completa la sección Antes de comenzar de esta guía para configurar tu proyecto y tu app.
En esa sección, también harás clic en un botón para el proveedor de Gemini API que elijas, de modo que veas contenido específico del proveedor en esta página.

Puedes enviar entrada de audio transmitida y recibir salida de audio transmitida. Asegúrate de crear una instancia de LiveModel y establecer la modalidad de respuesta en Audio.

Obtén más información para configurar y personalizar la voz de respuesta (más adelante en esta página).

Swift

La función Live API aún no es compatible con las apps para plataformas de Apple, pero vuelve a consultar pronto.

Kotlin

// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
val model = Firebase.ai(backend = GenerativeBackend.vertexAI(location = "us-central1")).liveModel(
    modelName = "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to respond with text
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.AUDIO 
   }
)

val session = model.connect()

// This is the recommended way.
// However, you can create your own recorder and handle the stream.
session.startAudioConversation()

Java

ExecutorService executor = Executors.newFixedThreadPool(1);
// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
LiveGenerativeModel lm = FirebaseAI.getInstance(GenerativeBackend.vertexAI("us-central1")).liveModel(
        "gemini-2.0-flash-live-preview-04-09",
        // Configure the model to respond with text
        new LiveGenerationConfig.Builder()
                .setResponseModalities(ResponseModality.TEXT)
                .build()
);
LiveModelFutures model = LiveModelFutures.from(lm);
ListenableFuture<LiveSession> sessionFuture =  model.connect();

Futures.addCallback(sessionFuture, new FutureCallback<LiveSession>() {
    @Override
    public void onSuccess(LiveSession ses) {
	 LiveSessionFutures session = LiveSessionFutures.from(ses);
        session.startAudioConversation();
    }
    @Override
    public void onFailure(Throwable t) {
        // Handle exceptions
    }
}, executor);

Web

La función Live API aún no es compatible con las apps web, pero vuelve a consultar pronto.

Dart

import 'package:firebase_ai/firebase_ai.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:your_audio_recorder_package/your_audio_recorder_package.dart';

late LiveModelSession _session;
final _audioRecorder = YourAudioRecorder();

await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);

// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
final model = FirebaseAI.vertexAI(location: 'us-central1').liveModel(
  model: 'gemini-2.0-flash-live-preview-04-09',
   // Configure the model to respond with audio
   config: LiveGenerationConfig(responseModalities: [ResponseModality.audio]),
);

_session = await model.connect();

final audioRecordStream = _audioRecorder.startRecordingStream();
// Map the Uint8List stream to InlineDataPart stream
final mediaChunkStream = audioRecordStream.map((data) {
  return InlineDataPart('audio/pcm', data);
});
await _session.startMediaStream(mediaChunkStream);

// In a separate thread, receive the audio response from the model
await for (final message in _session.receive()) {
   // Process the received message 
}

Unity

using Firebase;
using Firebase.AI;

async Task SendTextReceiveAudio() {
  // Initialize the Vertex AI Gemini API backend service
  // Set the location to `us-central1` (the flash-live model is only supported in that location)
  // Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
  var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI(location: "us-central1")).GetLiveModel(
    modelName: "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to respond with audio
    liveGenerationConfig: new LiveGenerationConfig(
        responseModalities: new[] { ResponseModality.Audio })
  );

  LiveSession session = await model.ConnectAsync();

  // Start a coroutine to send audio from the Microphone
  var recordingCoroutine = StartCoroutine(SendAudio(session));

  // Start receiving the response
  await ReceiveAudio(session);
}

IEnumerator SendAudio(LiveSession liveSession) {
  string microphoneDeviceName = null;
  int recordingFrequency = 16000;
  int recordingBufferSeconds = 2;

  var recordingClip = Microphone.Start(microphoneDeviceName, true,
                                       recordingBufferSeconds, recordingFrequency);

  int lastSamplePosition = 0;
  while (true) {
    if (!Microphone.IsRecording(microphoneDeviceName)) {
      yield break;
    }

    int currentSamplePosition = Microphone.GetPosition(microphoneDeviceName);

    if (currentSamplePosition != lastSamplePosition) {
      // The Microphone uses a circular buffer, so we need to check if the
      // current position wrapped around to the beginning, and handle it
      // accordingly.
      int sampleCount;
      if (currentSamplePosition > lastSamplePosition) {
        sampleCount = currentSamplePosition - lastSamplePosition;
      } else {
        sampleCount = recordingClip.samples - lastSamplePosition + currentSamplePosition;
      }

      if (sampleCount > 0) {
        // Get the audio chunk
        float[] samples = new float[sampleCount];
        recordingClip.GetData(samples, lastSamplePosition);

        // Send the data, discarding the resulting Task to avoid the warning
        _ = liveSession.SendAudioAsync(samples);

        lastSamplePosition = currentSamplePosition;
      }
    }

    // Wait for a short delay before reading the next sample from the Microphone
    const float MicrophoneReadDelay = 0.5f;
    yield return new WaitForSeconds(MicrophoneReadDelay);
  }
}

Queue audioBuffer = new();

async Task ReceiveAudio(LiveSession liveSession) {
  int sampleRate = 24000;
  int channelCount = 1;

  // Create a looping AudioClip to fill with the received audio data
  int bufferSamples = (int)(sampleRate * channelCount);
  AudioClip clip = AudioClip.Create("StreamingPCM", bufferSamples, channelCount,
                                    sampleRate, true, OnAudioRead);

  // Attach the clip to an AudioSource and start playing it
  AudioSource audioSource = GetComponent();
  audioSource.clip = clip;
  audioSource.loop = true;
  audioSource.Play();

  // Start receiving the response
  await foreach (var message in liveSession.ReceiveAsync()) {
    // Process the received message
    foreach (float[] pcmData in message.AudioAsFloat) {
      lock (audioBuffer) {
        foreach (float sample in pcmData) {
          audioBuffer.Enqueue(sample);
        }
      }
    }
  }
}

// This method is called by the AudioClip to load audio data.
private void OnAudioRead(float[] data) {
  int samplesToProvide = data.Length;
  int samplesProvided = 0;

  lock(audioBuffer) {
    while (samplesProvided < samplesToProvide && audioBuffer.Count > 0) {
      data[samplesProvided] = audioBuffer.Dequeue();
      samplesProvided++;
    }
  }

  while (samplesProvided < samplesToProvide) {
    data[samplesProvided] = 0.0f;
    samplesProvided++;
  }
}



Crea experiencias más interactivas y atractivas

En esta sección, se describe cómo crear y administrar funciones más interactivas o atractivas de Live API.

Cómo cambiar la voz de la respuesta

Live API usa Chirp 3 para admitir respuestas de voz sintetizada. Cuando usas Firebase AI Logic, puedes enviar audio en una variedad de idiomas con voces en HD. Para obtener una lista completa y demostraciones de cómo suena cada voz, consulta Chirp 3: Voces en HD.

Para especificar una voz, configura el nombre de la voz dentro del objeto speechConfig como parte de la configuración del modelo. Si no especificas una voz, la predeterminada es Puck.

Swift

La función Live API aún no es compatible con las apps para plataformas de Apple, pero vuelve a consultar pronto.

Kotlin

// ...

val model = Firebase.ai(backend = GenerativeBackend.vertexAI()).liveModel(
    modelName = "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to use a specific voice for its audio response
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.AUDIO
        speechConfig = SpeechConfig(voice = Voices.FENRIR)
    }
)

// ...

Java

// ...

LiveModel model = FirebaseAI.getInstance(GenerativeBackend.vertexAI()).liveModel(
    "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to use a specific voice for its audio response
    new LiveGenerationConfig.Builder()
        .setResponseModalities(ResponseModality.AUDIO)
        .setSpeechConfig(new SpeechConfig(Voices.FENRIR))
        .build()
);

// ...

Web

La función Live API aún no es compatible con las apps web, pero vuelve a consultar pronto.

Dart

// ...

final model = FirebaseAI.vertexAI().liveGenerativeModel(
  model: 'gemini-2.0-flash-live-preview-04-09',
  // Configure the model to use a specific voice for its audio response
  config: LiveGenerationConfig(
    responseModality: ResponseModality.audio,
    speechConfig: SpeechConfig(voiceName: 'Fenrir'),
  ),
);

// ...

Unity

var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI()).GetLiveModel(
  modelName: "gemini-2.0-flash-live-preview-04-09",
  liveGenerationConfig: new LiveGenerationConfig(
    responseModalities: new[] { ResponseModality.Audio },
    speechConfig: SpeechConfig.UsePrebuiltVoice("Fenrir"),
);

Para obtener los mejores resultados cuando le pidas al modelo que responda en un idioma que no sea inglés, incluye lo siguiente como parte de tus instrucciones del sistema:

RESPOND IN LANGUAGE. YOU MUST RESPOND UNMISTAKABLY IN LANGUAGE.

Mantener el contexto en las sesiones y solicitudes

Puedes usar una estructura de chat para mantener el contexto en todas las sesiones y solicitudes. Ten en cuenta que esta opción solo funciona con entrada y salida de texto.

Este enfoque es mejor para contextos cortos. Puedes enviar interacciones paso a paso para representar la secuencia exacta de eventos. Para contextos más largos, te recomendamos que proporciones un solo resumen del mensaje para liberar la ventana de contexto para interacciones posteriores.

Cómo controlar las interrupciones

Firebase AI Logic aún no admite el control de interrupciones. Vuelva a consultar más tarde.

Usa llamadas a función (herramientas)

Puedes definir herramientas, como funciones disponibles, para usar con la API en vivo, al igual que con los métodos estándar de generación de contenido. En esta sección, se describen algunos detalles que se deben tener en cuenta cuando se usa la API de Live con la llamada a funciones. Para obtener una descripción completa y ejemplos de la llamada a función, consulta la guía de llamada a función.

A partir de una sola instrucción, el modelo puede generar varias llamadas a funciones y el código necesario para encadenar sus resultados. Este código se ejecuta en un entorno de zona de pruebas y genera mensajes BidiGenerateContentToolCall posteriores. La ejecución se pausa hasta que los resultados de cada llamada a función estén disponibles, lo que garantiza el procesamiento secuencial.

Además, usar la API de Live con la llamada a funciones es particularmente potente porque el modelo puede solicitar información de seguimiento o aclaratoria al usuario. Por ejemplo, si el modelo no tiene suficiente información para proporcionar un valor de parámetro a una función que quiere llamar, puede pedirle al usuario que proporcione más información o que aclare la que ya proporcionó.

El cliente debe responder con BidiGenerateContentToolResponse.



Limitaciones y requisitos

Ten en cuenta las siguientes limitaciones y requisitos de Live API.

Transcripción

Firebase AI Logic aún no admite transcripciones. Vuelva a consultar más tarde.

Lenguajes

Formatos de audio

La herramienta Live API admite los siguientes formatos de audio:

  • Formato de audio de entrada: Audio PCM sin procesar de 16 bits a 16 kHz little-endian
  • Formato de audio de salida: Audio PCM sin procesar de 16 bits a 24 kHz en formato little-endian

Límites de frecuencia

Se aplican los siguientes límites de frecuencia:

  • 10 sesiones simultáneas por proyecto de Firebase
  • 4 millones de tokens por minuto

Duración de la sesión

La duración predeterminada de una sesión es de 30 minutos. Cuando la duración de la sesión supera el límite, se finaliza la conexión.

El modelo también está limitado por el tamaño del contexto. Enviar grandes fragmentos de entrada puede provocar que la sesión finalice antes.

Detección de actividad de voz (VAD)

El modelo realiza automáticamente la detección de actividad de voz (VAD) en una transmisión de entrada de audio continua. El VAD está habilitado de forma predeterminada.

Recuento de tokens

No puedes usar la API de CountTokens con Live API.


Envía comentarios sobre tu experiencia con Firebase AI Logic