เวิร์กโฟลว์แบบ Agentic ในอุปกรณ์ (โดยใช้คลาส AgentRunner) จะมีเซสชันแบบหลายเทิร์นที่มีการจัดการซึ่งจะบันทึกประวัติการสนทนาในหน่วยความจำโดยอัตโนมัติในเทิร์นต่างๆ คุณจึงไม่ต้องจัดการข้อความถอดเสียงด้วยตนเอง (หากต้องการจัดการประวัติการแชทของคุณเองโดยตรง คุณสามารถส่งออบเจ็กต์ List<Content> แบบหลายเทิร์นที่มีบทบาท USER และ MODEL และค่า sessionId ไปยังออบเจ็กต์ GenerateContentRequest โดยใช้การเข้าถึงโมเดลโดยตรง)
หน้านี้ครอบคลุมการจัดการอินสแตนซ์ AgentSession ในวงจรของคอมโพเนนต์ Android, การเปลี่ยนแปลงการกำหนดค่า และการเรียกคืนหน่วยความจำ
เซสชันแบบต่อเนื่อง
จัดการการสนทนาแบบหลายเทิร์นโดยใช้อินสแตนซ์ AgentSession ที่กำหนดขอบเขตซึ่งได้รับโดยใช้วิธี runner.getOrCreateSession(sessionId) ระบบจะบันทึกการสนทนา (ข้อความของผู้ใช้ การเรียกใช้เครื่องมือ และคำตอบของโมเดล) ไว้ในหน่วยความจำโดยอัตโนมัติภายในเซสชัน การเรียกใช้เมธอด session.runAsync(content) ในครั้งต่อๆ ไปจะเก็บเทิร์นก่อนหน้าไว้เป็นบริบท
ตัวระบุเซสชันต้องไม่เว้นว่าง มีอักขระได้ไม่เกิน 128 ตัว และมีเฉพาะอักขระที่เป็นตัวอักษรและตัวเลขคละกัน ขีดล่าง ขีดกลาง หรือจุด (^[a-zA-Z0-9_.-]+$ ยกเว้น . และ ..) สตริง UUID ที่สร้างขึ้นโดยใช้เมธอด UUID.randomUUID().toString() จะเป็นไปตามข้อจำกัดเหล่านี้
หากต้องการเริ่มการสนทนาแบบหลายตา ให้สร้างตัวระบุเซสชันและรับอินสแตนซ์ AgentSession จากอินสแตนซ์ AgentRunner ดังนี้
val sessionId = "user_chat_${System.currentTimeMillis()}"
val session = runner.getOrCreateSession(sessionId)
การเรียกใช้เมธอด session.runAsync(content) แต่ละครั้งจะส่งเทิร์นพรอมต์ใหม่ภายในเซสชันนั้น โมเดลจะรักษาบริบทจากรอบก่อนหน้าในการสนทนา
คงเซสชันไว้แม้จะมีการเปลี่ยนแปลงการกำหนดค่า
อินเทอร์เฟซ AgentSession จะเก็บประวัติการสนทนาไว้ในหน่วยความจำและไม่ได้ติดตั้งใช้งานอินเทอร์เฟซ Parcelable ในแอป Android ระบบจะทำลายและสร้างกิจกรรมและส่วนย่อยขึ้นมาใหม่ระหว่างการเปลี่ยนแปลงการกำหนดค่า (เช่น การหมุนหน้าจอ) หากคุณจัดเก็บเซสชันไว้ในกิจกรรมโดยตรง ประวัติการสนทนาจะหายไปเมื่อมีการหมุนเวียน
หากต้องการเก็บรักษาประวัติการสนทนาไว้แม้จะมีการเปลี่ยนแปลงการกำหนดค่า ให้เก็บอินสแตนซ์ AgentSession ไว้ในคลาส 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()
}
}
การจัดการหน่วยความจำและการล้างเซสชัน
จำกัดสถานะการสนทนาในหน่วยความจำเพื่อรักษาประสิทธิภาพของแอป ดังนี้
- การลบเซสชันอย่างชัดแจ้ง: เมื่อผู้ใช้ออกจากชุดข้อความการสนทนาหรือแตะ "แชทใหม่" ให้เรียกใช้เมธอด
session.delete()หรือrunner.deleteSession(sessionId)เพื่อเพิ่มพื้นที่ว่างในหน่วยความจำที่จัดสรรไว้สำหรับเทิร์นที่ผ่านมาและเอาต์พุตของเครื่องมือพร้อมกัน หรือจะเรียกใช้เมธอดsession.close()เพื่อส่งการนำออกในเบื้องหลังก็ได้ - การล้างข้อมูลเมื่อออกจากระบบ: เรียกใช้เมธอด
runner.clearAllSessions()เมื่อผู้ใช้ออกจากระบบหรือล้างข้อมูลแอป - การล้างเซสชันเมื่อสิ้นสุดวงจร: เรียกใช้เมธอด
session.close()เมื่อคลาสViewModelหรือคอมโพเนนต์หลักถูกทำลายอย่างถาวร (ในเมธอดonCleared()) การดำเนินการนี้จะยกเลิก Coroutine ที่รอดำเนินการอยู่และส่งการขับออกในเบื้องหลังสำหรับเซสชันการสนทนานั้น
การดำเนินการแบบรอบเดียวและไม่ถาวร
สำหรับงานของ Agent ที่ทำครั้งเดียว (เช่น การสร้างสรุปสั้นๆ การตรวจสอบอินพุต หรือการตอบคำถามแบบสแตนด์อโลน) ซึ่งไม่จำเป็นต้องใช้บริบทที่ผ่านมา ให้เรียกใช้เมธอด 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 จะจัดสรรเซสชันชั่วคราวภายในและล้างสถานะการสนทนาทั้งหมดออกจากหน่วยความจำโดยอัตโนมัติเมื่อสตรีมการตอบกลับเสร็จสมบูรณ์หรือยกเลิก เพื่อหลีกเลี่ยงหน่วยความจำรั่วไหล
ขั้นตอนถัดไป
- เชื่อมต่อสตรีมแบบรีแอ็กทีฟของ Agent กับ Compose ในเหตุการณ์สตรีมและการผสานรวม UI
- ดูข้อมูลเกี่ยวกับการกำหนดค่าเครื่องมือในกำหนดเครื่องมือ