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 une entity_type de forme libre.
  • Observation — un fait attachĂ© Ă  une entitĂ©, avec un id stable et un horodatage valid_from.
  • Relation — une arĂȘte typĂ©e entre deux entitĂ©s (source ──relation_type──▶ target), par exemple Alice ──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 →

Le Graphe de Connaissances - Documentation ADK-Rust | ADK-Rust