设备端 Agentic Workflows(使用 AgentRunner 类)提供代管式多轮会话,可自动记录各轮对话的内存中对话记录,因此您无需手动管理转写内容。(如果您希望直接管理自己的对话记录,可以使用直接模型访问,将具有 USER 和 MODEL 角色以及 sessionId 值的多轮 List<Content> 对象传递给 GenerateContentRequest 对象。)
本页介绍了如何在 Android 组件生命周期、配置更改和内存回收过程中管理 AgentSession 实例。
多轮会话
使用通过 runner.getOrCreateSession(sessionId) 方法获取的作用域限定的 AgentSession 实例来管理多轮对话。对话轮次(用户消息、工具调用和模型回答)会在会话期间自动记录在记忆中。后续对 session.runAsync(content) 方法的调用会将之前的对话轮次保留为上下文。
会话标识符必须为非空,最多包含 128 个字符,并且只能包含字母数字字符、下划线、连字符或英文句点(^[a-zA-Z0-9_.-]+$,不包括 . 和 ..)。使用 UUID.randomUUID().toString() 方法生成的 UUID 字符串符合这些限制。
如需开始多轮对话,请创建一个会话标识符,并从 AgentRunner 实例中获取 AgentSession 实例:
val sessionId = "user_chat_${System.currentTimeMillis()}"
val session = runner.getOrCreateSession(sessionId)
每次调用 session.runAsync(content) 方法都会在该会话中发送一个新的提示轮次。模型会保留对话中先前轮次的上下文。
在配置变更后保留会话
AgentSession 接口在内存中保存对话历史记录,不实现 Parcelable 接口。在 Android 应用中,Activity 和 Fragment 会在配置更改(例如屏幕旋转)期间被销毁并重新创建。如果您将对话直接存储在 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 类会在内部临时分配一个会话,并在响应流完成或取消后自动从内存中清除所有对话状态,从而避免内存泄漏。