Sitzungen und Lebenszyklus verwalten

Agentische Workflows auf dem Gerät (mit der Klasse AgentRunner) bieten verwaltete Multi-Turn-Sitzungen, bei denen der Unterhaltungsverlauf automatisch über mehrere Turns hinweg im Arbeitsspeicher aufgezeichnet wird. Sie müssen Transkripte also nicht manuell verwalten. (Wenn Sie Ihren eigenen Chatverlauf lieber direkt verwalten möchten, können Sie ein Multi-Turn-List<Content>-Objekt mit den Rollen USER und MODEL und einem sessionId-Wert über den direkten Modellzugriff an ein GenerateContentRequest-Objekt übergeben.)

Auf dieser Seite wird die Verwaltung von AgentSession-Instanzen über die Lebenszyklen von Android-Komponenten, Konfigurationsänderungen und die Freigabe von Arbeitsspeicher hinweg beschrieben.

Multi-Turn-Sitzungen

Verwalten Sie Multi-Turn-Unterhaltungen mit bereichsbezogenen AgentSession-Instanzen, die mit der Methode runner.getOrCreateSession(sessionId) abgerufen wurden. Dialogrunden (Nutzernachrichten, Toolaufrufe und Modellantworten) werden während der Sitzung automatisch im Speicher aufgezeichnet. Bei nachfolgenden Aufrufen der Methode session.runAsync(content) werden vorherige Turns als Kontext beibehalten.

Sitzungskennungen dürfen nicht leer sein, maximal 128 Zeichen lang sein und nur alphanumerische Zeichen, Unterstriche, Bindestriche oder Punkte enthalten (^[a-zA-Z0-9_.-]+$, ausgenommen . und ..). UUID-Strings, die mit der Methode UUID.randomUUID().toString() generiert werden, entsprechen diesen Einschränkungen.

Wenn Sie eine Multi-Turn-Unterhaltung starten möchten, erstellen Sie eine Sitzungs-ID und rufen Sie eine AgentSession-Instanz aus Ihrer AgentRunner-Instanz ab:

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

Bei jedem Aufruf der Methode session.runAsync(content) wird ein neuer Prompt-Turn innerhalb dieser Sitzung gesendet. Das Modell behält den Kontext aus vorherigen Runden der Unterhaltung bei.

Sitzungen über Konfigurationsänderungen hinweg beibehalten

Die Schnittstelle AgentSession speichert den Dialogverlauf im Arbeitsspeicher und implementiert die Schnittstelle Parcelable nicht. In Android-Apps werden Aktivitäten und Fragmente bei Konfigurationsänderungen (z. B. Bildschirmdrehung) zerstört und neu erstellt. Wenn Sie die Sitzung direkt in einer Aktivität speichern, geht der Unterhaltungsverlauf bei der Rotation verloren.

Wenn Sie den Unterhaltungsverlauf über Konfigurationsänderungen hinweg beibehalten möchten, behalten Sie Ihre AgentSession-Instanz in einer AndroidX-ViewModel-Klasse bei:

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

Speicherverwaltung und Sitzungsbereinigung

Begrenzen Sie den im Arbeitsspeicher gespeicherten Unterhaltungsstatus, um die App-Leistung aufrechtzuerhalten:

  • Explizites Löschen von Sitzungen: Wenn ein Nutzer einen Unterhaltungsthread verlässt oder auf „Neuer Chat“ tippt, rufen Sie die Methode session.delete() oder runner.deleteSession(sessionId) auf, um den für frühere Runden und Toolausgaben zugewiesenen Arbeitsspeicher synchron freizugeben. Alternativ wird durch Aufrufen der Methode session.close() die Hintergrundentfernung ausgelöst.
  • Bereinigung bei Abmeldung: Rufe die Methode runner.clearAllSessions() auf, wenn sich der Nutzer abmeldet oder App-Daten löscht.
  • Sitzungsbereinigung am Ende des Lebenszyklus: Rufen Sie die Methode session.close() auf, wenn Ihre ViewModel-Klasse oder übergeordnete Komponente endgültig gelöscht wird (in der Methode onCleared()). Dadurch werden ausstehende, laufende Koroutinen abgebrochen und die Hintergrundbereinigung für diese Unterhaltungssitzung wird gestartet.

Kurzlebige Ausführung mit einzelner Antwort

Für einmalige Agentenaufgaben (z. B. das Generieren einer kurzen Zusammenfassung, das Validieren einer Eingabe oder das Beantworten einer eigenständigen Frage), bei denen kein Kontext aus der Vergangenheit erforderlich ist, rufen Sie die Methode runner.runSingleTurnAsync(content) direkt auf:

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

Wenn Sie die Methode runner.runSingleTurnAsync(content) direkt aufrufen, weist die Klasse AgentRunner intern eine temporäre Sitzung zu und löscht automatisch den gesamten Unterhaltungsstatus aus dem Arbeitsspeicher, sobald der Antwortstream abgeschlossen oder abgebrochen wird. So werden Speicherlecks vermieden.

Nächste Schritte