Sessions
Les Sessions dans adk-rust fournissent une gestion du contexte de conversation, permettant aux Agents de maintenir un état à travers de multiples interactions. Les Sessions stockent l'historique de conversation (événements) et des données d'état arbitraires qui persistent tout au long d'une conversation.
Aperçu
Une session représente une conversation unique entre un utilisateur et un Agent. Chaque session :
- Possède un identifiant unique
- Appartient à une application (
app_name) et un utilisateur (user_id) - Contient une liste d'événements (historique de conversation)
- Maintient des données d'état (paires clé-valeur)
- Enregistre la dernière heure de mise à jour
Trait Session
Le trait Session définit l'interface pour les objets de session :
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>;
}
Trait SessionService
Le trait SessionService définit les opérations pour la gestion des 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<()>;
}
Types de Requêtes
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(),
};
Implémentations de SessionService
ADK-Rust propose deux implémentations de SessionService :
InMemorySessionService
Stocke les sessions en mémoire. Idéal pour le développement, les tests et les déploiements à instance unique.
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
Stocke les sessions dans une base de données SQLite. Convient aux déploiements en production nécessitant de la persistance.
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(())
}
Note: Le
DatabaseSessionServicenécessite la feature flagdatabase:adk-session = { version = "0.2", features = ["database"] }
Cycle de vie d'une Session
1. Création
Les sessions sont créées avec une CreateRequest. Si aucun session_id n'est fourni, un UUID est généré automatiquement.
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. Récupération
Récupérer une session par ses identifiants :
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. Ajout d'Événements
Les événements sont ajoutés aux sessions au fur et à mesure de la conversation. Ceci est généralement géré par le Runner, mais peut être fait manuellement :
use adk_session::Event;
let event = Event::new("invocation_123");
service.append_event(session.id(), event).await?;
4. Liste
Lister toutes les sessions pour un utilisateur :
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. Suppression
Supprimer une session lorsqu'elle n'est plus nécessaire :
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?;
Utiliser les Sessions avec Runner
Les Sessions sont généralement gérées par le Runner lors de l'exécution des agents. Le Runner :
- Crée ou récupère une session
- Transmet le contexte de la session à l'Agent
- Ajoute des événements au fur et à mesure de la conversation
- Met à jour l'état de la session en fonction des actions de l'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(())
}
Événements
Le trait Events donne accès à l'historique de la conversation :
pub trait Events: Send + Sync {
/// Récupère tous les événements
fn all(&self) -> Vec<Event>;
/// Récupère le nombre d'événements
fn len(&self) -> usize;
/// Récupère l'événement à l'index donné
fn at(&self, index: usize) -> Option<&Event>;
/// Vérifie si la collection est vide
fn is_empty(&self) -> bool;
}
Accéder aux événements d'une 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
);
}
Exemple Complet
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();
// Créer une session avec un état initial
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());
// Vérifier l'état
let state = session.state();
println!("User name: {:?}", state.get("user:name"));
println!("Topic: {:?}", state.get("topic"));
// Ajouter un événement
let event = Event::new("inv_001");
service.append_event(session.id(), event).await?;
// Récupérer la session avec les événements
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());
// Lister toutes les sessions
let sessions = service.list(ListRequest {
app_name: "demo".to_string(),
user_id: "alice".to_string(),
}).await?;
println!("Total sessions: {}", sessions.len());
// Supprimer la 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(())
}
Liens associés
- Gestion de l'état - Gestion de l'état de session avec des préfixes
- Événements - Structure et actions des événements
- Runner - Exécution d'agents avec des sessions
Précédent : ← MCP Tools | Suivant : Gestion de l'état →