管理工作階段和生命週期

裝置端 Agentic Workflows (使用 AgentRunner 類別) 提供代管的多輪對話工作階段,會自動記錄各輪對話的記憶體內對話記錄,因此您不必手動管理轉錄稿。(如要直接管理自己的對話記錄,可以使用直接存取模型,將具有 USER 和 MODEL 角色和 sessionId 值的多輪 List<Content> 物件傳遞至 GenerateContentRequest 物件)。

本頁面說明如何在 Android 元件生命週期、設定變更和記憶體回收期間管理 AgentSession 執行個體。

多輪對話

使用透過 runner.getOrCreateSession(sessionId) 方法取得的限定範圍 AgentSession 執行個體,管理多輪對話。對話輪次 (使用者訊息、工具叫用和模型回覆) 會自動記錄在工作階段的記憶體中。後續呼叫 session.runAsync(content) 方法時,會保留先前的對話做為背景資訊。

工作階段 ID 不得為空白,長度最多 128 個字元,且只能包含英數字元、底線、連字號或半形句號 (^[a-zA-Z0-9_.-]+$,不含 . 和 ..)。使用 UUID.randomUUID().toString() 方法產生的 UUID 字串符合這些限制。

如要展開多輪對話,請建立工作階段 ID,並從 AgentRunner 執行個體取得 AgentSession 執行個體:

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

每次呼叫 session.runAsync(content) 方法,都會在該工作階段中傳送新的提示。模型會保留先前對話的情境。

在設定變更時保留工作階段

AgentSession 介面會將對話記錄保留在記憶體中,且不會實作 Parcelable 介面。在 Android 應用程式中,系統會在設定變更 (例如螢幕旋轉) 期間刪除並重新建立活動和片段。如果直接將工作階段儲存在 Activity 中,對話記錄會在旋轉時遺失。

如要在設定變更時保留對話記錄,請將 AgentSession 執行個體保留在 AndroidX ViewModel 類別中:

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

記憶體管理和工作階段清除

限制記憶體中的對話狀態,維持應用程式效能:

  • 明確刪除工作階段:當使用者離開對話串或輕觸「新增對話」時,請呼叫 session.delete() 或 runner.deleteSession(sessionId) 方法,同步釋出分配給過去對話和工具輸出的記憶體配置。或者,呼叫 session.close() 方法會調度背景清除作業。
  • 登出清除:當使用者登出或清除應用程式資料時,呼叫 runner.clearAllSessions() 方法。
  • 在生命週期結束時清除工作階段:當 ViewModel 類別或父項元件永久刪除時 (在 onCleared() 方法中),呼叫 session.close() 方法。這會取消待處理的執行中協同程式,並調度該對話工作階段的背景清除作業。

單輪臨時執行

如果是一次性的代理工作 (例如生成快速摘要、驗證輸入內容或回答獨立問題),不需要過去的背景資訊,請直接呼叫 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)
        }
    }

直接叫用 runner.runSingleTurnAsync(content) 方法時,AgentRunner 類別會在內部配置臨時工作階段,並在回應串流完成或取消後,自動從記憶體中清除所有對話狀態,避免記憶體流失。

後續步驟