الجلسات
توفر الجلسات في adk-rust إدارة سياق المحادثة، مما يسمح للوكلاء بالحفاظ على الحالة عبر تفاعلات متعددة. تخزن الجلسات سجل المحادثة (events) وبيانات الحالة العشوائية التي تستمر طوال المحادثة.
نظرة عامة
تمثل الجلسة محادثة واحدة بين مستخدم ووكيل. كل جلسة:
- لها معرف فريد
- تنتمي إلى تطبيق (
app_name) ومستخدم (user_id) - تحتوي على قائمة من الأحداث (سجل المحادثة)
- تحافظ على بيانات الحالة (أزواج المفتاح والقيمة)
- تتتبع وقت آخر تحديث
سمة Session
تحدد سمة Session الواجهة لكائنات الجلسة:
use adk_session::{Events, State};
use chrono::{DateTime, Utc};
pub trait Session: Send + Sync {
/// معرف الجلسة الفريد
fn id(&self) -> &str;
/// اسم التطبيق الذي تنتمي إليه هذه الجلسة
fn app_name(&self) -> &str;
/// معرف المستخدم
fn user_id(&self) -> &str;
/// الوصول إلى حالة الجلسة
fn state(&self) -> &dyn State;
/// الوصول إلى أحداث المحادثة
fn events(&self) -> &dyn Events;
/// آخر مرة تم فيها تحديث الجلسة
fn last_update_time(&self) -> DateTime<Utc>;
}
سمة SessionService
تحدد سمة SessionService العمليات لإدارة الجلسات:
use adk_session::{CreateRequest, GetRequest, ListRequest, DeleteRequest, Event, Session};
use adk_core::Result;
use async_trait::async_trait;
#[async_trait]
pub trait SessionService: Send + Sync {
/// إنشاء جلسة جديدة
async fn create(&self, req: CreateRequest) -> Result<Box<dyn Session>>;
/// استرداد جلسة موجودة
async fn get(&self, req: GetRequest) -> Result<Box<dyn Session>>;
/// سرد جميع الجلسات لتطبيق/مستخدم
async fn list(&self, req: ListRequest) -> Result<Vec<Box<dyn Session>>>;
/// حذف جلسة
async fn delete(&self, req: DeleteRequest) -> Result<()>;
/// إلحاق حدث بجلسة
async fn append_event(&self, session_id: &str, event: Event) -> Result<()>;
}
أنواع الطلبات
CreateRequest
use adk_session::CreateRequest;
use std::collections::HashMap;
let request = CreateRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: None, // إنشاء UUID تلقائيًا إذا كان None
state: HashMap::new(), // الحالة الأولية
};
GetRequest
use adk_session::GetRequest;
let request = GetRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: "session_abc".to_string(),
num_recent_events: Some(10), // تحديد عدد الأحداث المرجعة
after: None, // تصفية الأحداث بعد الطابع الزمني
};
ListRequest
use adk_session::ListRequest;
let request = ListRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
};
DeleteRequest
use adk_session::DeleteRequest;
let request = DeleteRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: "session_abc".to_string(),
};
تطبيقات SessionService
يوفر ADK-Rust تطبيقين لخدمة Session:
InMemorySessionService
تخزن الجلسات في الذاكرة. مثالية للتطوير والاختبار والنشر على مثيل واحد.
use adk_session::{InMemorySessionService, SessionService, CreateRequest};
use std::collections::HashMap;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create the service
let session_service = InMemorySessionService::new();
// Create a session
let session = session_service.create(CreateRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: None,
state: HashMap::new(),
}).await?;
println!("Session ID: {}", session.id());
println!("App: {}", session.app_name());
println!("User: {}", session.user_id());
Ok(())
}
DatabaseSessionService
تخزن الجلسات في قاعدة بيانات SQLite. مناسبة لعمليات النشر في الإنتاج التي تتطلب استمرارية.
use adk_session::{DatabaseSessionService, SessionService, CreateRequest};
use std::collections::HashMap;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Connect to database
let session_service = DatabaseSessionService::new("sqlite:sessions.db").await?;
// Run migrations to create tables
session_service.migrate().await?;
// Create a session
let session = session_service.create(CreateRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: None,
state: HashMap::new(),
}).await?;
println!("Session persisted: {}", session.id());
Ok(())
}
ملاحظة: يتطلب
DatabaseSessionServiceعلامة الميزةdatabase:adk-session = { version = "0.2", features = ["database"] }
دورة حياة Session
1. الإنشاء
يتم إنشاء الجلسات باستخدام CreateRequest. إذا لم يتم توفير session_id، يتم إنشاء UUID تلقائيًا.
use adk_session::{InMemorySessionService, SessionService, CreateRequest};
use std::collections::HashMap;
let service = InMemorySessionService::new();
// Create with auto-generated ID
let session = service.create(CreateRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: None,
state: HashMap::new(),
}).await?;
// Create with specific ID
let session = service.create(CreateRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: Some("my-custom-id".to_string()),
state: HashMap::new(),
}).await?;
2. الاسترداد
استرداد الجلسة بواسطة معرفاتها:
use adk_session::GetRequest;
let session = service.get(GetRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: "session_abc".to_string(),
num_recent_events: None,
after: None,
}).await?;
println!("Retrieved session: {}", session.id());
println!("Events: {}", session.events().len());
3. إلحاق الأحداث
يتم إلحاق الأحداث بالجلسات مع تقدم المحادثة. يتم التعامل مع هذا عادةً بواسطة Runner، ولكن يمكن القيام به يدويًا:
use adk_session::Event;
let event = Event::new("invocation_123");
service.append_event(session.id(), event).await?;
4. الإدراج
سرد جميع الجلسات لمستخدم:
use adk_session::ListRequest;
let sessions = service.list(ListRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
}).await?;
for session in sessions {
println!("Session: {} (updated: {})",
session.id(),
session.last_update_time()
);
}
5. الحذف
حذف جلسة عندما لا تكون هناك حاجة إليها:
use adk_session::DeleteRequest;
service.delete(DeleteRequest {
app_name: "my_app".to_string(),
user_id: "user_123".to_string(),
session_id: "session_abc".to_string(),
}).await?;
استخدام الجلسات (Sessions) مع Runner
عادةً ما تتم إدارة Sessions بواسطة Runner عند تنفيذ Agents. يقوم Runner بما يلي:
- ينشئ أو يسترجع session
- يمرر سياق الـsession إلى الـAgent
- يضيف Events مع تقدم المحادثة
- يحدث حالة الـsession بناءً على إجراءات الـAgent
use adk_rust::prelude::*;
use adk_runner::{Runner, RunnerConfig};
use adk_session::InMemorySessionService;
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenvy::dotenv().ok();
let api_key = std::env::var("GOOGLE_API_KEY")?;
let model = Arc::new(GeminiModel::new(&api_key, "gemini-2.0-flash")?);
let agent = LlmAgentBuilder::new("assistant")
.model(model)
.instruction("You are a helpful assistant.")
.build()?;
let session_service = Arc::new(InMemorySessionService::new());
// Create runner with session service
let runner = Runner::new(RunnerConfig {
app_name: "my_app".to_string(),
agent: Arc::new(agent),
session_service,
artifact_service: None,
memory_service: None,
run_config: None,
})?;
// Run with user and session IDs
let user_content = Content::new("user").with_text("Hello!");
let stream = runner.run(
"user_123".to_string(),
"session_abc".to_string(),
user_content,
).await?;
Ok(())
}
الأحداث (Events)
يوفر الـtrait Events إمكانية الوصول إلى سجل المحادثة:
pub trait Events: Send + Sync {
/// Get all events
fn all(&self) -> Vec<Event>;
/// Get number of events
fn len(&self) -> usize;
/// Get event at index
fn at(&self, index: usize) -> Option<&Event>;
/// Check if empty
fn is_empty(&self) -> bool;
}
الوصول إلى Events من session:
let events = session.events();
println!("Total events: {}", events.len());
for event in events.all() {
println!("Event {} by {} at {}",
event.id,
event.author,
event.timestamp
);
}
مثال كامل
use adk_session::{
InMemorySessionService, SessionService,
CreateRequest, GetRequest, ListRequest, DeleteRequest,
Event, KEY_PREFIX_USER,
};
use serde_json::json;
use std::collections::HashMap;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let service = InMemorySessionService::new();
// Create session with initial state
let mut initial_state = HashMap::new();
initial_state.insert(format!("{}name", KEY_PREFIX_USER), json!("Alice"));
initial_state.insert("topic".to_string(), json!("Getting started"));
let session = service.create(CreateRequest {
app_name: "demo".to_string(),
user_id: "alice".to_string(),
session_id: None,
state: initial_state,
}).await?;
println!("Created session: {}", session.id());
// Check state
let state = session.state();
println!("User name: {:?}", state.get("user:name"));
println!("Topic: {:?}", state.get("topic"));
// Append an event
let event = Event::new("inv_001");
service.append_event(session.id(), event).await?;
// Retrieve session with events
let session = service.get(GetRequest {
app_name: "demo".to_string(),
user_id: "alice".to_string(),
session_id: session.id().to_string(),
num_recent_events: None,
after: None,
}).await?;
println!("Events: {}", session.events().len());
// List all sessions
let sessions = service.list(ListRequest {
app_name: "demo".to_string(),
user_id: "alice".to_string(),
}).await?;
println!("Total sessions: {}", sessions.len());
// Delete session
service.delete(DeleteRequest {
app_name: "demo".to_string(),
user_id: "alice".to_string(),
session_id: session.id().to_string(),
}).await?;
println!("Session deleted");
Ok(())
}
ذات صلة
- إدارة الحالة - إدارة حالة الـSession باستخدام البادئات
- الأحداث - تركيبة الـEvent والفعاليات
- Runner - تنفيذ الـAgent مع الـSessions
السابق: ← MCP Tools | التالي: إدارة الحالة →