Der Wissensgraph

GraphMemoryService ist eine andere Form von Speicher: Anstatt eines Stapels von Texteinträgen speichert es einen Wissensgraphen des Benutzers – Entitäten, die daran angehängten Fakten ("Beobachtungen") und typisierte Beziehungen zwischen ihnen – und es verfolgt all dies bi-temporal. Dies ist das Backend hinter dem Mindfulness-with-Mia Beispiel und der Echtzeit-Speicherseite.

Es implementiert dasselbe MemoryService Trait wie die anderen Backends, sodass es auf die gleiche Weise in einen Agent integriert werden kann – aber es stellt eine reichere Graph-API darüber zur Verfügung.

Das Datenmodell

   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 – eine benannte Sache (eine Person, ein Ort, eine Präferenz, ein Thema) mit einem frei formulierten entity_type.
  • Observation – eine Tatsache, die an eine Entität gebunden ist, mit einem stabilen id und einem valid_from Zeitstempel.
  • Relation – eine typisierte Kante zwischen zwei Entitäten (source ──relation_type──▶ target), z.B. Alice ──works_at──▶ Acme.

Es gibt auch einen episodischen Speicher (kg_episodic), der rohe Interaktionen protokolliert, getrennt vom kuratierten Graphen – so behalten Sie sowohl das Transkript als auch das destillierte Modell.

Warum bi-temporal

Jede Beobachtung und Relation wird entlang zweier Zeitachsen verfolgt:

  • Gültigkeitszeit – wann die Tatsache in der Welt wahr war (valid_fromvalid_to).
  • Erfassungszeit – wann das System sie gelernt hat.

Wenn sich ein Fakt ändert, wird der alte nicht gelöscht – er wird invalidiert (sein valid_to wird gesetzt) und der neue wird hinzugefügt. Das bedeutet, der Graph kann die Frage "Was ist die aktuelle Präferenz des Benutzers?" beantworten, ohne zu verlieren "was sie einmal war." Überholte Fakten bleiben in der Historie, anstatt die Gegenwart zu überschreiben – was genau das ist, was Sie für ein Gedächtnis wollen, dem Sie über Monate vertrauen können.

kg.invalidate_observation(old_id).await?;   // mark a fact no longer valid
kg.invalidate_relation(old_id).await?;      // mark an edge no longer valid

Eine erstellen

graph-memory wird von SQLite unterstützt, daher ist es eine Datei (oder im Arbeitsspeicher für 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);

In den Graphen schreiben

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?;

Das Erstellen einer Entität ist upsert — das erneute Erstellen einer bekannten Entität aktualisiert ihren Typ und Zeitstempel, anstatt sie zu duplizieren.

Zurücklesen

Drei Abruf-Formen, zusätzlich zu den search des Traits:

// 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?;

Die Profilkarte

Das Killer-Feature für Agenten: profile_card erzeugt eine kompakte, aktuelle Zusammenfassung darüber, wer der Benutzer ist — die zuletzt aktualisierten Entitäten und ihre gültigen Beobachtungen — bereit zur Injektion in einen System-Prompt beim Sitzungsstart.

let card = kg.profile_card("coach", "alice").await?;
// → a short text block: "Alice (person): prefers morning sessions; goal: run a 10k…"

Begrenzen Sie seine Größe mit einem Budget, damit der Prompt klein bleibt, während der Graph wächst:

let kg = GraphMemoryService::new(url).await?
    .with_profile_budget(/* entities */ 12, /* observations per entity */ 5);

Dem Agenten die Kuratierung überlassen

Sie rufen selten create_entities manuell in der Produktion auf — Sie geben dem Agenten Werkzeuge, um in den Graphen zu schreiben, während er lernt. Siehe Tools & Agenten für remember und relate, die direkt auf die obigen Aufrufe abbilden und in adk-tool ausgeliefert werden.

Weiter: Tools & Agenten →