Sessions
Sessions in adk-rust bieten ein Konversationskontextmanagement, das es Agents ermöglicht, den Zustand über mehrere Interaktionen hinweg aufrechtzuerhalten. Sessions speichern den Konversationsverlauf (events) und beliebige Zustandsdaten, die während einer Konversation bestehen bleiben.
Überblick
Eine Session repräsentiert eine einzelne Konversation zwischen einem Benutzer und einem Agent. Jede Session:
- Hat eine eindeutige Kennung
- Gehört zu einer Anwendung (
app_name) und einem Benutzer (user_id) - Enthält eine Liste von events (Konversationsverlauf)
- Verwaltet Zustandsdaten (Schlüssel-Wert-Paare)
- Verfolgt die letzte Aktualisierungszeit
Session Trait
Das Session trait definiert die Schnittstelle für Session-Objekte:
use adk_session::{Events, State};
use chrono::{DateTime, Utc};
pub trait Session: Send + Sync {
/// Unique session identifier
fn id(&self) -> &str;
/// Application name this session belongs to
fn app_name(&self) -> &str;
/// User identifier
fn user_id(&self) -> &str;
/// Access session state
fn state(&self) -> &dyn State;
/// Access conversation events
fn events(&self) -> &dyn Events;
/// Last time the session was updated
fn last_update_time(&self) -> DateTime<Utc>;
}
SessionService Trait
Das SessionService trait definiert Operationen zur Verwaltung von Sessions:
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 {
/// Create a new session
async fn create(&self, req: CreateRequest) -> Result<Box<dyn Session>>;
/// Retrieve an existing session
async fn get(&self, req: GetRequest) -> Result<Box<dyn Session>>;
/// List all sessions for an app/user
async fn list(&self, req: ListRequest) -> Result<Vec<Box<dyn Session>>>;
/// Delete a session
async fn delete(&self, req: DeleteRequest) -> Result<()>;
/// Append an event to a session
async fn append_event(&self, session_id: &str, event: Event) -> Result<()>;
}
Anfragetypen
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, // Auto-generate UUID if None
state: HashMap::new(), // Initial state
};
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), // Limit events returned
after: None, // Filter events after timestamp
};
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 Implementierungen
ADK-Rust stellt zwei SessionService-Implementierungen bereit:
InMemorySessionService
Speichert Sessions im Arbeitsspeicher. Ideal für Entwicklung, Tests und Single-Instance-Bereitstellungen.
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
Speichert Sessions in einer SQLite-Datenbank. Geeignet für Produktionsbereitstellungen, die Persistenz erfordern.
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(())
}
Hinweis: Der
DatabaseSessionServiceerfordert das Feature-Flagdatabase:adk-session = { version = "0.2", features = ["database"] }
Session-Lebenszyklus
1. Erstellung
Sessions werden mit einem CreateRequest erstellt. Wird keine session_id angegeben, wird automatisch eine UUID generiert.
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. Abruf
Rufen Sie eine Session anhand ihrer Bezeichner ab:
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. Anhängen von Events
Events werden an Sessions angehängt, während die Konversation fortschreitet. Dies wird typischerweise vom Runner gehandhabt, kann aber auch manuell erfolgen:
use adk_session::Event;
let event = Event::new("invocation_123");
service.append_event(session.id(), event).await?;
4. Auflistung
Listen Sie alle Sessions für einen Benutzer auf:
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. Löschung
Löschen Sie eine Session, wenn sie nicht mehr benötigt wird:
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?;
Verwenden von Sessions mit Runner
Sessions werden typischerweise vom Runner verwaltet, wenn Agents ausgeführt werden. Der Runner:
- Erstellt oder ruft eine Session ab
- Übergibt den Session-Kontext an den Agent
- Fügt Ereignisse hinzu, während die Konversation fortschreitet
- Aktualisiert den Session-Status basierend auf Agent-Aktionen
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(())
}
Ereignisse
Das Events-Trait bietet Zugriff auf den Konversationsverlauf:
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;
}
Zugriff auf Ereignisse aus einer 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
);
}
Vollständiges Beispiel
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(())
}
Verwandt
- Zustandsverwaltung - Verwalten des Sitzungszustands mit Präfixen
- Ereignisse - Ereignisstruktur und Aktionen
- Runner - Agenten-Ausführung mit Sitzungen
Zurück: ← MCP Tools | Weiter: Zustandsverwaltung →