Los flujos de trabajo de agentes integrados en el dispositivo (con la clase AgentRunner) proporcionan sesiones de varios turnos administradas que registran automáticamente el historial de conversaciones en la memoria en todos los turnos, por lo que no tienes que administrar las transcripciones de forma manual. (Si prefieres administrar
tu propio historial de chat directamente, puedes pasar un objeto List<Content>
de varios turnos con roles USER y MODEL, y un valor sessionId a un
objeto GenerateContentRequest con el acceso directo al modelo).
En esta página, se explica cómo administrar instancias de AgentSession en los ciclos de vida de los componentes de Android, los cambios de configuración y la recuperación de memoria.
Sesiones de varios turnos
Administra conversaciones de varios turnos con instancias de AgentSession con alcance obtenidas
con el método runner.getOrCreateSession(sessionId). Los turnos de diálogo (mensajes del usuario, invocaciones de herramientas y respuestas del modelo) se registran en la memoria automáticamente dentro de la sesión. Las llamadas posteriores al método session.runAsync(content) conservan los turnos anteriores como contexto.
Los identificadores de sesión no deben estar en blanco, deben tener como máximo 128 caracteres y solo deben contener
caracteres alfanuméricos, guiones bajos, guiones o puntos
(^[a-zA-Z0-9_.-]+$, sin incluir . ni ..). Las cadenas de UUID generadas con el
método UUID.randomUUID().toString() cumplen con estas restricciones.
Para iniciar una conversación de varios turnos, crea un identificador de sesión y obtén una
instancia de AgentSession de tu instancia de AgentRunner:
val sessionId = "user_chat_${System.currentTimeMillis()}"
val session = runner.getOrCreateSession(sessionId)
Cada llamada al método session.runAsync(content) envía un nuevo turno de instrucción dentro de esa
sesión. El modelo mantiene el contexto de los turnos anteriores de la conversación.
Cómo conservar las sesiones durante los cambios de configuración
La interfaz AgentSession conserva el historial de diálogos en la memoria y no
implementa la interfaz Parcelable. En las apps para Android, las actividades y los fragmentos se destruyen y se vuelven a crear durante los cambios de configuración (como la rotación de la pantalla). Si almacenas la sesión directamente en una actividad, el historial de conversaciones se perderá cuando se rote la pantalla.
Para conservar el historial de conversaciones durante los cambios de configuración, conserva tu
instancia de AgentSession dentro de una clase ViewModel de AndroidX:
package com.example.ai.agent.ui
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.mlkit.genai.agent.AgentRunner
import com.google.mlkit.genai.agent.AgentSession
import com.google.mlkit.genai.agent.textTokens
import com.google.mlkit.genai.prompt.Content
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
class ChatViewModel(
private val runner: AgentRunner,
private val sessionId: String = "default_chat_session"
) : ViewModel() {
// Retain the session inside the ViewModel to survive screen rotations
private val session: AgentSession = runner.getOrCreateSession(sessionId)
private val _responseText = MutableStateFlow("")
val responseText: StateFlow<String> = _responseText.asStateFlow()
fun sendMessage(userPrompt: String) {
viewModelScope.launch {
val content = Content.builder().text(userPrompt).build()
session.runAsync(content)
.textTokens()
.collect { token ->
_responseText.update { it + token }
}
}
}
override fun onCleared() {
super.onCleared()
// Release session memory and cancel active coroutines when ViewModel is destroyed
session.close()
}
}
Administración de la memoria y limpieza de sesiones
Mantén el estado de la conversación en la memoria limitado para mantener el rendimiento de la app:
- Borrado explícito de sesiones: Cuando un usuario abandona un hilo de conversación o
presiona "Nuevo chat", llama al método
session.delete()orunner.deleteSession(sessionId)para liberar de forma síncrona la memoria asignada a los turnos y los resultados de las herramientas anteriores. Como alternativa, llamar al métodosession.close()envía la expulsión en segundo plano. - Limpieza de salida: Llama al método
runner.clearAllSessions()cuando el usuario salga de la app o borre los datos de app. - Limpieza de la sesión al final del ciclo de vida: Llama al método
session.close()cuando tu claseViewModelo componente superior se destruya de forma permanente (en el métodoonCleared()). Esto cancela las corrutinas en curso pendientes y envía la expulsión en segundo plano para esa sesión de conversación.
Ejecución efímera de un solo turno
Para tareas de agentes únicas (como generar un resumen rápido, validar una
entrada o responder una pregunta independiente) en las que no se necesita el contexto anterior,
llama al método runner.runSingleTurnAsync(content) directamente:
import com.google.mlkit.genai.agent.AgentEvent
import com.google.mlkit.genai.prompt.Content
val content = Content.builder()
.text("Summarize order history for customer #1042: ...")
.build()
runner.runSingleTurnAsync(content)
.collect { event ->
if (event is AgentEvent.TextMessage && !event.isPartial) {
displaySummary(event.text)
}
}
Cuando se invoca el método runner.runSingleTurnAsync(content) directamente, la clase AgentRunner
asigna una sesión temporal de forma interna y borra automáticamente todo
el estado de la conversación de la memoria una vez que se completa o cancela el flujo de respuesta,
lo que evita las fugas de memoria.
Próximos pasos
- Conecta el flujo reactivo del agente a Compose en Transmite eventos y la integración de la IU.
- Obtén más información para configurar herramientas en Define herramientas.