Mémoire dans les sessions Realtime

Une voix qui vous oublie entre deux appels donne l’impression d’un kiosque. ADK-Rust permet à un agent realtime de se souvenir — de se rappeler ce qu’il a appris sur un utilisateur avant de parler, et de sélectionner de nouveaux faits en cours de conversation — en branchant un MemoryService dans le IntegratedRealtimeRunner.

Il existe deux mécanismes coopératifs :

  1. Injection automatique du contexte + stockage des tours — la couche d’intégration le fait pour vous.
  2. Mémoire curée par l’agent via des outils — l’agent décide ce qui mérite d’être conservé, à l’aide d’outils de graphe de connaissances reliés.

1. Injection et stockage automatiques

Attachez un MemoryService et le runner gère l’aller-retour :

let runner = IntegratedRealtimeRunner::builder()
    .model(model)
    .config(config)
    .identity("support", &user_id, &session_id)
    .session_service(sessions)
    .memory_service(memory.clone())
    .integration_config(IntegrationConfig {
        inject_memory_context: true,   // query memory at connect
        max_memory_injection: 10,      // cap injected items
        store_to_memory: true,         // write each completed turn back
        persist_transcripts: true,
    })
    .build()?;
  • À la connexion, la mémoire est interrogée pour l’utilisateur et les résultats sont intégrés au contexte de la session, de sorte que l’agent le salue en connaissant déjà l’historique pertinent.
  • À chaque tour, les échanges terminés sont réécrits dans la mémoire (lorsque store_to_memory), afin que la session suivante s’appuie sur celle-ci.

N’importe quel MemoryService fonctionne — celui en mémoire pour le développement, ou le backend de graphe de connaissances ci-dessous.

2. Le backend de graphe de connaissances

adk-memory's GraphMemoryService stocke la mémoire comme un graphe de connaissances bi-temporel : des entités et des relations, chacune suivie selon le temps d’événement (quand c’était vrai) et le temps d’ingestion (quand le système l’a appris). Cela signifie que l’agent peut répondre à « quel est le plan actuel de l’utilisateur ? » sans buter sur le fait qu’il a pu être autrefois différent — les faits remplacés restent dans l’historique au lieu d’écraser le présent.

use adk_memory::GraphMemoryService;
use std::sync::Arc;

let kg = Arc::new(GraphMemoryService::new(/* backing store */));

Passez cela comme le memory_service et l’injection automatique ci-dessus s’appuie désormais sur le graphe.

3. Laisser l’agent organiser la mémoire

Le schéma le plus puissant : donner à l’agent des outils pour écrire directement dans le graphe, afin qu’il se souvienne de manière délibérée plutôt que de tout vider dans la transcription. adk-tool (fonctionnalité graph-memory-tools) en fournit deux qui se branchent directement dans une session realtime :

OutilCe que l’agent en fait
RememberTool (remember)Stocker un fait saillant (« préfère l’e-mail au téléphone »).
RelateTool (relate)Relier deux entités (« Order A-10293 → belongs-to → cet utilisateur »).

Reliez-les avec .adk_tool(...) (voir Tools) :

use adk_tool::{RememberTool, RelateTool};

let runner = IntegratedRealtimeRunner::builder()
    .model(model).config(config)
    .identity("support", &user_id, &session_id)
    .memory_service(kg.clone())
    .adk_tool(Arc::new(RememberTool::new(kg.clone())))
    .adk_tool(Arc::new(RelateTool::new(kg)))
    .build()?;

Puis demandez à l'agent de les utiliser :

When you learn a durable fact about the customer (a preference, an account
detail, a decision), call `remember` to store it. Use `relate` to link orders
or items to the customer. Recall naturally — don't announce that you're saving.

La remémoration est basée sur les jetons : le graphe renvoie les entités/relations les plus pertinentes pour la conversation, bornées par max_memory_injection, afin que le contexte reste petit même lorsque le graphe grandit.

Choisir une profondeur

  • Démo sans état → pas de memory_service. Chaque session repart de zéro.
  • Continuité entre les sessions → en mémoire ou GraphMemoryService avec injection/stockage automatiques. Aucun effort de la part de l'agent.
  • Un agent d'apprentissageGraphMemoryService + outils remember/relate, afin que l'agent construise un modèle propre et interrogeable de l'utilisateur plutôt qu'une pile de transcription.

L'exemple de coaching MIA utilise le graphe + les outils afin que le coach se souvienne des objectifs et des préférences de l'utilisateur entre les sessions ; voir Examples.

Suivant : Building web apps →

Ce qui est repris dans une session reprise

IntegratedRealtimeRunner::connect construit un bloc de contexte et le préfixe à l'instruction système avant la création de la session du fournisseur :

SectionSourceLimite
Earlier in this conversation:Les événements de la session précédenteIntegrationConfig::max_history_injection (par défaut 20 tours)
Relevant recalled context:MemoryService::searchIntegrationConfig::max_memory_injection (par défaut 10 entrées)

Les deux sont bornés, car l’instruction est envoyée une fois à la création de la session et compte dans le contexte du modèle. Chaque tour est rendu comme role: text, tronqué à 400 caractères, et les tours sans texte sont supprimés. Définir une borne à zéro désactive cette section.

IntegratedRealtimeRunner::instruction() renvoie ce avec quoi la session a été créée, de sorte que le contexte transmis puisse être affirmé plutôt qu’inféré :

runner.connect().await?;
let instruction = runner.instruction().await.unwrap_or_default();
assert!(instruction.contains("Relevant recalled context"));

Important : ce contexte avait déjà été chargé puis supprimé — la session précédente avait été récupérée dans _session puis supprimée, et la branche mémoire a journalisé « injecting memory entries into session context » à côté d’un commentaire indiquant que l’injection était une amélioration future. Une session reprise ne commençait avec ni l’un ni l’autre, alors que les journaux disaient le contraire.