توفّر مهام سير العمل المستندة إلى الوكلاء على الجهاز فقط (باستخدام فئة 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()). يؤدي ذلك إلى إلغاء الكوروتين المعلّق قيد التنفيذ وإرسال عملية إخلاء في الخلفية لجلسة المحادثة هذه.
التنفيذ المؤقت أحادي الجولة
بالنسبة إلى مهام الوكيل التي تُنفَّذ لمرة واحدة (مثل إنشاء ملخّص سريع أو التحقّق من صحة
إدخال أو الإجابة عن سؤال مستقل) والتي لا تتطلّب سياقًا سابقًا،
يمكنك استدعاء طريقة 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 جلسة مؤقتة داخليًا وتزيل تلقائيًا جميع حالات المحادثة من الذاكرة بعد اكتمال بث الرد أو إلغائه، ما يمنع تسرّب الذاكرة.
الخطوات التالية
- اربط البث التفاعلي للوكيل بـ Compose في أحداث البث ودمج واجهة المستخدم.
- يمكنك الاطّلاع على كيفية ضبط الأدوات في مقالة تحديد الأدوات.