Gestisci le sessioni e il ciclo di vita

Gli Agentic Workflow on-device (utilizzando la classe AgentRunner) forniscono sessioni multi-turn gestite che registrano automaticamente la cronologia delle conversazioni in memoria tra i turni, in modo da non dover gestire manualmente le trascrizioni. Se preferisci gestire direttamente la tua cronologia della chat, puoi passare un oggetto List<Content> multi-turn con ruoli USER e MODEL e un valore sessionId a un oggetto GenerateContentRequest utilizzando l'accesso diretto al modello.

Questa pagina illustra la gestione delle istanze AgentSession nei cicli di vita dei componenti Android, nelle modifiche alla configurazione e nel recupero della memoria.

Sessioni multi-turno

Gestisci le conversazioni a più turni utilizzando istanze AgentSession con ambito ottenute utilizzando il metodo runner.getOrCreateSession(sessionId). I turni di dialogo (messaggi dell'utente, chiamate degli strumenti e risposte del modello) vengono registrati automaticamente nella memoria all'interno della sessione. Le chiamate successive al metodo session.runAsync(content) conservano i turni precedenti come contesto.

Gli identificatori di sessione non devono essere vuoti, devono contenere al massimo 128 caratteri e solo caratteri alfanumerici, trattini bassi, trattini o punti (^[a-zA-Z0-9_.-]+$, esclusi . e ..). Le stringhe UUID generate utilizzando il metodo UUID.randomUUID().toString() sono conformi a questi vincoli.

Per avviare una conversazione a più turni, crea un identificatore di sessione e ottieni un'istanza AgentSession dalla tua istanza AgentRunner:

val sessionId = "user_chat_${System.currentTimeMillis()}"
val session = runner.getOrCreateSession(sessionId)

Ogni chiamata al metodo session.runAsync(content) invia un nuovo turno di prompt all'interno della sessione. Il modello mantiene il contesto dei turni precedenti della conversazione.

Conserva le sessioni durante le modifiche alla configurazione

L'interfaccia AgentSession conserva la cronologia dei dialoghi in memoria e non implementa l'interfaccia Parcelable. Nelle app per Android, le attività e i frammenti vengono eliminati e ricreati durante le modifiche alla configurazione (ad esempio la rotazione dello schermo). Se memorizzi la sessione direttamente in un'attività, la cronologia della conversazione viene persa durante la rotazione.

Per conservare la cronologia delle conversazioni tra le modifiche alla configurazione, conserva l'istanza AgentSession all'interno di una classe ViewModel 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()
    }
}

Gestione della memoria e pulizia della sessione

Mantieni limitato lo stato della conversazione in memoria per mantenere le prestazioni dell'app:

  • Eliminazione esplicita della sessione: quando un utente abbandona un thread di conversazione o tocca "Nuova chat", chiama il metodo session.delete() o runner.deleteSession(sessionId) per liberare in modo sincrono l'allocazione della memoria per i turni e gli output degli strumenti precedenti. In alternativa, la chiamata al metodo session.close() invia l'eviction in background.
  • Pulizia alla disconnessione: chiama il metodo runner.clearAllSessions() quando l'utente si disconnette o cancella i dati dell'app.
  • Pulizia della sessione al termine del ciclo di vita: chiama il metodo session.close() quando la classe ViewModel o il componente principale vengono eliminati definitivamente (nel metodo onCleared()). In questo modo, le coroutine in corso in attesa vengono annullate e viene inviata l'evizione in background per la sessione di conversazione.

Esecuzione temporanea in un solo passaggio

Per le attività degli agenti una tantum (come la generazione di un riepilogo rapido, la convalida di un input o la risposta a una domanda autonoma) in cui non è necessario il contesto passato, chiama direttamente il metodo runner.runSingleTurnAsync(content):

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)
        }
    }

Quando richiami direttamente il metodo runner.runSingleTurnAsync(content), la classe AgentRunner alloca internamente una sessione temporanea e cancella automaticamente dalla memoria tutto lo stato della conversazione una volta completato o annullato lo stream di risposta, evitando perdite di memoria.

Passaggi successivi