Administra las sesiones y el ciclo de vida

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() o runner.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étodo session.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 clase ViewModel o componente superior se destruya de forma permanente (en el método onCleared()). 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