Transmisión bidireccional con la API de Gemini Live 


Gemini Live API permite interacciones de voz y texto bidireccionales de baja latencia con Gemini. Con Live API, puedes proporcionar 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, video) y puede proporcionar salidas de texto y audio.

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

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 información, consulta la documentación de referencia de Live API.

Antes de comenzar

Solo está disponible cuando usas Vertex AI Gemini API como 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, cómo conectar tu app a Firebase, agregar el SDK, inicializar el servicio de backend para el Vertex AI Gemini API y crear una instancia de LiveModel.

Modelos que admiten esta función

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

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 app.
En esa sección, también harás clic en un botón del proveedor de Gemini API que elijas para ver 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 configurar la modalidad de respuesta en Text.

Swift

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
// Create a `LiveModel` instance with the model that supports the Live API
val model = Firebase.vertexAI.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
// Create a `LiveModel` instance with the model that supports the Live API
LiveGenerativeModel lm = FirebaseAI.getInstance(GenerativeBackend.vertexAI()).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

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
// Create a `LiveModel` instance with the model that supports the Live API
final model = FirebaseAI.vertexAI().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
  // Create a `LiveModel` instance with the model that supports the Live API
  var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI()).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);
    }
  }
}

Aprende a elegir un modelo apropiado para tu caso de uso y tu app.

Genera audio transmitido desde una entrada de audio transmitida

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

Puedes enviar entradas de audio transmitidas y recibir salidas de audio transmitidas. Asegúrate de crear una instancia de LiveModel y configurar la modalidad de respuesta en Audio.

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

Swift

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
// Create a `LiveModel` instance with the model that supports the Live API
val model = Firebase.vertexAI.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
// Create a `LiveModel` instance with the model that supports the Live API
LiveGenerativeModel lm = FirebaseAI.getInstance(GenerativeBackend.vertexAI()).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

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
// Create a `LiveModel` instance with the model that supports the Live API
final model = FirebaseAI.vertexAI().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
  // Create a `LiveModel` instance with the model that supports the Live API
  var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI()).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++;
  }
}

Aprende a elegir un modelo apropiado para tu caso de uso y tu app.



Crea experiencias más interactivas y atractivas

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

Cambia 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 5 voces de alta definición y 31 idiomas.

Si no especificas una voz, el valor predeterminado es Puck. Como alternativa, puedes configurar el modelo para que responda con cualquiera de las siguientes voces:

Aoede (mujer)
Charon (hombre)
Fenrir (hombre)
Kore (mujer)
Puck (hombre)

Para ver demostraciones de cómo suenan estas voces y obtener la lista completa de los idiomas disponibles, consulta Chirp 3: Voces en HD.

Para especificar una voz, establece el nombre de la voz dentro del objeto speechConfig como parte de la configuración del modelo:

Swift

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

Kotlin

// ...

val model = Firebase.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 = Firebase.getVertexAI().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

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

Dart

// ...

final model = FirebaseVertexAI.instance.liveModel(
  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(voice: Voice.fenrir),
  ),
);

// ...

Unity

Snippets coming soon!

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 las instrucciones del sistema:

RESPOND IN LANGUAGE. YOU MUST RESPOND UNMISTAKABLY IN LANGUAGE.

Mantén el contexto en todas las sesiones y solicitudes

Puedes usar una estructura de chat para mantener el contexto en todas las sesiones y solicitudes. Ten en cuenta que esto solo funciona para la 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 resumen de un solo mensaje para liberar la ventana de contexto para interacciones posteriores.

Controla las interrupciones

Firebase AI Logic aún no admite el manejo 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 de Live, al igual que con los métodos de generación de contenido estándar. En esta sección, se describen algunos matices cuando se usa la API en vivo con llamadas a funciones. Para obtener una descripción completa y ejemplos de llamadas a funciones, consulta la guía de llamadas a funciones.

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 en vivo con llamadas a funciones es particularmente potente porque el modelo puede solicitarle al usuario información de seguimiento o de aclaración. Por ejemplo, si el modelo no tiene suficiente información para proporcionar un valor de parámetro a una función a la que desea llamar, puede pedirle al usuario que proporcione más información o que aclare la información.

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

Live API admite los siguientes formatos de audio:

  • Formato de audio de entrada: Audio PCM sin procesar de 16 bits a 16 kHz en formato 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 se limita por el tamaño del contexto. Enviar grandes fragmentos de entrada puede generar el cierre anticipado de la sesión.

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. La VAD está habilitada 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