Para las aplicaciones que requieren asistencia por voz en tiempo real y con baja latencia, como los chatbots o las interacciones con agentes, la API de Gemini Live proporciona una forma optimizada de transmitir la entrada y la salida de un modelo de Gemini. Con Firebase AI Logic, puedes llamar a la API de Gemini Live directamente desde tu app para Android sin necesidad de una integración de backend. En esta guía, se muestra cómo usar la API de Gemini Live en tu app para Android con Firebase AI Logic.
Comenzar
Antes de comenzar, asegúrate de que tu app se oriente al nivel de API 21 o superior.
Si aún no lo has hecho, configura un proyecto de Firebase y conecta tu app a Firebase. Para obtener más detalles, consulta la documentación de Firebase AI Logic.
Configura tu proyecto de Android
Agrega la dependencia de la biblioteca de Firebase AI Logic a tu archivo build.gradle.kts
o build.gradle
a nivel de la app. Usa la BoM de Firebase para Android para administrar las versiones de las bibliotecas.
dependencies {
// Import the Firebase BoM
implementation(platform("com.google.firebase:firebase-bom:34.1.0"))
// Add the dependency for the Firebase AI Logic library
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation("com.google.firebase:firebase-ai")
}
Después de agregar la dependencia, sincroniza tu proyecto de Android con Gradle.
Integra Firebase AI Logic e inicializa un modelo generativo
Agrega el permiso RECORD_AUDIO
al archivo AndroidManifest.xml
de tu aplicación:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Inicializa el servicio de backend de la API para desarrolladores de Gemini y accede a LiveModel
.
Usa un modelo que admita la API de Live, como gemini-2.0-flash-live-preview-04-09
. Consulta la documentación de Firebase para conocer los modelos disponibles.
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
.
Kotlin
// Initialize the `LiveModel`
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
modelName = "gemini-2.0-flash-live-preview-04-09",
generationConfig = liveGenerationConfig {
responseModality = ResponseModality.AUDIO
speechConfig = SpeechConfig(voice= Voice("FENRIR"))
})
Java
// Initialize the `LiveModel`
LiveGenerativeModel model = FirebaseAI
.getInstance(GenerativeBackend.googleAI())
.liveModel(
"gemini-2.0-flash-live-preview-04-09",
new LiveGenerationConfig.Builder()
.setResponseModality(ResponseModality.AUDIO)
.setSpeechConfig(new SpeechConfig(new Voice("FENRIR"))
).build(),
null,
null
);
De manera opcional, puedes definir un arquetipo o un rol que desempeñe el modelo configurando una instrucción del sistema:
Kotlin
val systemInstruction = content {
text("You are a helpful assistant, you main role is [...]")}
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
modelName = "gemini-2.0-flash-live-preview-04-09",
generationConfig = liveGenerationConfig {
responseModality = ResponseModality.AUDIO
speechConfig = SpeechConfig(voice= Voice("FENRIR"))
},
systemInstruction = systemInstruction,
)
Java
Content systemInstruction = new Content.Builder()
.addText("You are a helpful assistant, you main role is [...]")
.build();
LiveGenerativeModel model = FirebaseAI
.getInstance(GenerativeBackend.googleAI())
.liveModel(
"gemini-2.0-flash-live-preview-04-09",
new LiveGenerationConfig.Builder()
.setResponseModality(ResponseModality.AUDIO)
.setSpeechConfig(new SpeechConfig(new Voice("FENRIR"))
).build(),
tools, // null if you don't want to use function calling
systemInstruction
);
Puedes especializar aún más la conversación con el modelo usando instrucciones del sistema para proporcionar contexto específico de tu app (por ejemplo, el historial de actividad del usuario en la app).
Inicializa una sesión de la API de Live
Una vez que crees la instancia de LiveModel
, llama a model.connect()
para crear un objeto LiveSession
y establecer una conexión persistente con el modelo con transmisión de baja latencia. LiveSession
te permite interactuar con el modelo iniciando y deteniendo la sesión de voz, y también enviando y recibiendo texto.
Luego, puedes llamar a startAudioConversation()
para iniciar la conversación con el modelo:
Kotlin
val session = model.connect()
session.startAudioConversation()
Java
LiveModelFutures model = LiveModelFutures.from(liveModel);
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);
Además, en tus conversaciones con el modelo, ten en cuenta que no maneja interrupciones. Tenemos la intención de agregar esta función en el futuro.
También puedes usar la API de Gemini Live para generar audio transmitido a partir de texto y generar texto a partir de audio transmitido. Ten en cuenta que la API de Live es bidireccional, por lo que usas la misma conexión para enviar y recibir contenido. Con el tiempo, también podrás enviar imágenes y una transmisión de video en vivo al modelo.
Llamada a función: Conecta la API de Gemini Live a tu app
Para ir un paso más allá, también puedes habilitar el modelo para que interactúe directamente con la lógica de tu app a través de la llamada a función.
Las llamadas a función (o llamadas a herramientas) son una característica de las implementaciones de IA generativa que permite que el modelo llame a funciones por su propia iniciativa para realizar acciones. Si la función tiene un resultado, el modelo lo agrega a su contexto y lo usa para las generaciones posteriores.
Para implementar la llamada a función en tu app, comienza por crear un objeto FunctionDeclaration
para cada función que quieras exponer al modelo.
Por ejemplo, para exponer una función addList
que agrega una cadena a una lista de cadenas a Gemini, comienza por crear una variable FunctionDeclaration
con un nombre y una descripción breve en inglés simple de la función y su parámetro:
Kotlin
val itemList = mutableListOf<String>()
fun addList(item: String){
itemList.add(item)
}
val addListFunctionDeclaration = FunctionDeclaration(
name = "addList",
description = "Function adding an item the list",
parameters = mapOf("item" to Schema.string("A short string
describing the item to add to the list"))
)
Java
HashMap<String, Schema> addListParams = new HashMap<String, Schema>(1);
addListParams.put("item", Schema.str("A short string describing the item
to add to the list"));
FunctionDeclaration addListFunctionDeclaration = new FunctionDeclaration(
"addList",
"Function adding an item the list",
addListParams,
Collections.emptyList()
);
Luego, pasa este FunctionDeclaration
como un Tool
al modelo cuando lo instancias:
Kotlin
val addListTool = Tool.functionDeclarations(listOf(addListFunctionDeclaration))
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
modelName = "gemini-2.0-flash-live-preview-04-09",
generationConfig = liveGenerationConfig {
responseModality = ResponseModality.AUDIO
speechConfig = SpeechConfig(voice= Voice("FENRIR"))
},
systemInstruction = systemInstruction,
tools = listOf(addListTool)
)
Java
LiveGenerativeModel model = FirebaseAI.getInstance(
GenerativeBackend.googleAI()).liveModel(
"gemini-2.0-flash-live-preview-04-09",
new LiveGenerationConfig.Builder()
.setResponseModalities(ResponseModality.AUDIO)
.setSpeechConfig(new SpeechConfig(new Voice("FENRIR")))
.build(),
List.of(Tool.functionDeclarations(List.of(addListFunctionDeclaration))),
null,
systemInstruction
);
Por último, implementa una función de controlador para controlar la llamada a la herramienta que realiza el modelo y pasarle la respuesta. Esta función de controlador proporcionada a LiveSession
cuando llamas a startAudioConversation
, toma un parámetro FunctionCallPart
y devuelve FunctionResponsePart
:
Kotlin
session.startAudioConversation(::functionCallHandler)
// ...
fun functionCallHandler(functionCall: FunctionCallPart): FunctionResponsePart {
return when (functionCall.name) {
"addList" -> {
// Extract function parameter from functionCallPart
val itemName = functionCall.args["item"]!!.jsonPrimitive.content
// Call function with parameter
addList(itemName)
// Confirm the function call to the model
val response = JsonObject(
mapOf(
"success" to JsonPrimitive(true),
"message" to JsonPrimitive("Item $itemName added to the todo list")
)
)
FunctionResponsePart(functionCall.name, response)
}
else -> {
val response = JsonObject(
mapOf(
"error" to JsonPrimitive("Unknown function: ${functionCall.name}")
)
)
FunctionResponsePart(functionCall.name, response)
}
}
}
Java
Futures.addCallback(sessionFuture, new FutureCallback<LiveSessionFutures>() {
@RequiresPermission(Manifest.permission.RECORD_AUDIO)
@Override
@OptIn(markerClass = PublicPreviewAPI.class)
public void onSuccess(LiveSessionFutures ses) {
ses.startAudioConversation(::handleFunctionCallFuture);
}
@Override
public void onFailure(Throwable t) {
// Handle exceptions
}
}, executor);
// ...
ListenableFuture<JsonObject> handleFunctionCallFuture = Futures.transform(response, result -> {
for (FunctionCallPart functionCall : result.getFunctionCalls()) {
if (functionCall.getName().equals("addList")) {
Map<String, JsonElement> args = functionCall.getArgs();
String item =
JsonElementKt.getContentOrNull(
JsonElementKt.getJsonPrimitive(
locationJsonObject.get("item")));
return addList(item);
}
}
return null;
}, Executors.newSingleThreadExecutor());
Próximos pasos
- Experimenta con la API de Gemini Live en la app de ejemplo del catálogo de IA de Android.
- Obtén más información sobre la API de Gemini Live en la documentación de Firebase AI Logic.
- Obtén más información sobre los modelos de Gemini disponibles.
- Obtén más información sobre las llamadas a funciones.
- Explora las estrategias de diseño de instrucciones.