Le Graphe de Connaissances
GraphMemoryService est une forme de mémoire différente : au lieu d'une pile d'entrées de texte, il stocke un graphe de connaissances de l'utilisateur — entités, faits ("observations") qui leur sont attachés, et relations typées entre eux — et il suit tout cela bi-temporellement. C'est le backend qui se trouve derrière l'exemple Mindfulness-with-Mia et la page de mémoire en temps réel.
Il implémente le même trait MemoryService que les autres backends, de sorte qu'il s'intègre à un agent de la même manière — mais il expose une API de graphe plus riche en plus.
Le modèle de données
Entity "Alice" (type: person)
├─ observation: "prefers email over phone" valid_from 2026-06-01
├─ observation: "timezone is CET" valid_from 2026-06-10
└─ relation: Alice ──works_at──▶ "Acme"
Entity— une chose nommée (une personne, un lieu, une préférence, un sujet) avec uneentity_typede forme libre.Observation— un fait attaché à une entité, avec unidstable et un horodatagevalid_from.Relation— une arête typée entre deux entités (source ──relation_type──▶ target), par exempleAlice ──works_at──▶ Acme.
Il existe également un stockage épisodique (kg_episodic) qui enregistre les tours bruts, séparément du graphe organisé — vous conservez donc à la fois la transcription et le modèle distillé.
Pourquoi bi-temporel
Chaque observation et relation est suivie le long de deux axes temporels :
- temps de validité — quand le fait était vrai dans le monde (
valid_from→valid_to). - temps d'ingestion — quand le système l'a appris.
Lorsqu'un fait change, l'ancien n'est pas supprimé — il est invalidé (son
valid_to est défini) et le nouveau est ajouté. Cela signifie que le graphe peut répondre
"quelle est la préférence actuelle de l'utilisateur ?" sans perdre "ce qu'elle était auparavant."
Les faits remplacés restent dans l'historique au lieu de réécrire le présent — ce qui est
exactement ce que l'on attend d'une mémoire fiable sur plusieurs mois.
kg.invalidate_observation(old_id).await?; // mark a fact no longer valid
kg.invalidate_relation(old_id).await?; // mark an edge no longer valid
Créer une
graph-memory est basé sur SQLite, il s'agit donc d'un fichier (ou en mémoire pour les tests) :
use adk_memory::GraphMemoryService;
use std::sync::Arc;
let kg = GraphMemoryService::new("sqlite://mia-memory.db").await?;
kg.migrate().await?; // idempotent schema setup
let kg = Arc::new(kg);
Écrire dans le graphe
use adk_memory::{CreateEntityInput, CreateRelationInput};
kg.create_entities("coach", "alice", vec![CreateEntityInput {
name: "Alice".into(),
entity_type: "person".into(),
observations: vec!["prefers morning sessions".into(), "goal: run a 10k".into()],
}]).await?;
kg.create_relations("coach", "alice", vec![CreateRelationInput {
source: "Alice".into(), relation_type: "training_for".into(), target: "10k race".into(),
}]).await?;
// add facts to an existing entity later
kg.add_observations("coach", "alice", /* entity */ "Alice", vec!["timezone is CET".into()]).await?;
La création d'une entité est un upsert — recréer une entité connue met à jour son type et son horodatage au lieu de la dupliquer.
Le relire
Trois formes de rappel, en plus du search du trait :
// 1. Token-scored relevance search → entities + their relations + a score
let hits = kg.search_nodes("coach", "alice", "what is she training for?", 5).await?;
// 2. Fetch specific entities by name
let nodes = kg.open_nodes("coach", "alice", &["Alice".into()]).await?;
// 3. The whole graph (small graphs / debugging)
let graph = kg.read_graph("coach", "alice").await?;
La carte de profil
La fonctionnalité clé pour les agents : profile_card génère un résumé compact et actuel
de l'identité de l'utilisateur — les entités les plus récemment mises à jour et leurs observations valides —
prêt à être injecté dans un prompt système au début de la session.
let card = kg.profile_card("coach", "alice").await?;
// → a short text block: "Alice (person): prefers morning sessions; goal: run a 10k…"
Limitez sa taille avec un budget afin que le prompt reste petit à mesure que le graphe grandit :
let kg = GraphMemoryService::new(url).await?
.with_profile_budget(/* entities */ 12, /* observations per entity */ 5);
Laisser l'agent le gérer
Vous appelez rarement create_entities manuellement en production — vous donnez à l'agent
des outils pour écrire dans le graphe à mesure qu'il apprend. Voir
Outils & agents pour remember et
relate, qui se mappent directement sur les appels ci-dessus et sont livrés dans adk-tool.
Suivant : Outils & agents →