Speicher

Semantischer Langzeitspeicher fÃŒr AI-Agenten mit adk-memory.

Überblick

Das Speichersystem bietet persistenten, durchsuchbaren Speicher fÌr Agenten-Konversationen. Im Gegensatz zum Session-Status (der temporÀr ist) bleiben Erinnerungen Ìber Sessions hinweg bestehen und ermöglichen es Agenten, relevante Kontexte aus vergangenen Interaktionen abzurufen.

Installation

[dependencies]
adk-memory = "0.2.0"

Kernkonzepte

MemoryEntry

Ein einzelner Speicherdatensatz mit content, author und timestamp:

use adk_memory::MemoryEntry;
use adk_core::Content;
use chrono::Utc;

let entry = MemoryEntry {
    content: Content::new("user").with_text("I prefer dark mode"),
    author: "user".to_string(),
    timestamp: Utc::now(),
};

MemoryService Trait

Das Kern-Trait fÃŒr Speicher-Backends:

#[async_trait]
pub trait MemoryService: Send + Sync {
    /// Store session memories for a user
    async fn add_session(
        &self,
        app_name: &str,
        user_id: &str,
        session_id: &str,
        entries: Vec<MemoryEntry>,
    ) -> Result<()>;

    /// Search memories by query
    async fn search(&self, req: SearchRequest) -> Result<SearchResponse>;
}

SearchRequest

Query-Parameter fÃŒr die Speichersuche:

use adk_memory::SearchRequest;

let request = SearchRequest {
    query: "user preferences".to_string(),
    user_id: "user-123".to_string(),
    app_name: "my_app".to_string(),
};

InMemoryMemoryService

Einfache In-Memory-Implementierung fÃŒr Entwicklung und Tests:

use adk_memory::{InMemoryMemoryService, MemoryService, MemoryEntry, SearchRequest};
use adk_core::Content;
use chrono::Utc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let memory = InMemoryMemoryService::new();

    // Store memories from a session
    let entries = vec![
        MemoryEntry {
            content: Content::new("user").with_text("I like Rust programming"),
            author: "user".to_string(),
            timestamp: Utc::now(),
        },
        MemoryEntry {
            content: Content::new("assistant").with_text("Rust is great for systems programming"),
            author: "assistant".to_string(),
            timestamp: Utc::now(),
        },
    ];

    memory.add_session("my_app", "user-123", "session-1", entries).await?;

    // Search memories
    let request = SearchRequest {
        query: "Rust".to_string(),
        user_id: "user-123".to_string(),
        app_name: "my_app".to_string(),
    };

    let response = memory.search(request).await?;
    println!("Found {} memories", response.memories.len());

    Ok(())
}

Speicherisolation

Erinnerungen werden isoliert durch:

  • app_name: Verschiedene Anwendungen haben separate Speicherbereiche
  • user_id: Die Erinnerungen jedes Benutzers sind privat
// User A's memories
memory.add_session("app", "user-a", "sess-1", entries_a).await?;

// User B's memories (separate)
memory.add_session("app", "user-b", "sess-1", entries_b).await?;

// Search only returns user-a's memories
let request = SearchRequest {
    query: "topic".to_string(),
    user_id: "user-a".to_string(),
    app_name: "app".to_string(),
};

Suchverhalten

Der InMemoryMemoryService verwendet wortbasierte Übereinstimmungen:

  1. Query wird in Wörter (Kleinbuchstaben) tokenisiert
  2. Der content jeder Erinnerung wird tokenisiert
  3. Erinnerungen mit Ìbereinstimmenden Wörtern werden zurÌckgegeben
// Query: "rust programming"
// Entspricht Erinnerungen, die "rust" ODER "programming" enthalten

Benutzerdefiniertes Memory Backend

Implementieren Sie MemoryService fÃŒr benutzerdefinierten Speicher (z.B. Vektordatenbank):

use adk_memory::{MemoryService, MemoryEntry, SearchRequest, SearchResponse};
use adk_core::Result;
use async_trait::async_trait;

pub struct VectorMemoryService {
    // Ihr Vektor-DB-Client
}

#[async_trait]
impl MemoryService for VectorMemoryService {
    async fn add_session(
        &self,
        app_name: &str,
        user_id: &str,
        session_id: &str,
        entries: Vec<MemoryEntry>,
    ) -> Result<()> {
        // 1. Embeddings fÃŒr jeden Eintrag generieren
        // 2. In Vektordatenbank mit Metadaten speichern
        Ok(())
    }

    async fn search(&self, req: SearchRequest) -> Result<SearchResponse> {
        // 1. Embedding fÃŒr Abfrage generieren
        // 2. Ähnlichkeitssuche durchfÃŒhren
        // 3. Top-k-Ergebnisse zurÃŒckgeben
        Ok(SearchResponse { memories: vec![] })
    }
}

Integration mit Agents

Memory wird mit LlmAgentBuilder integriert:

use adk_agent::LlmAgentBuilder;
use adk_memory::InMemoryMemoryService;
use std::sync::Arc;

let memory = Arc::new(InMemoryMemoryService::new());

let agent = LlmAgentBuilder::new("assistant")
    .model(model)
    .instruction("You are a helpful assistant with memory.")
    .memory(memory)
    .build()?;

Wenn Memory konfiguriert ist:

  1. Vor jeder Runde werden relevante Memories gesucht
  2. Passende Memories werden in den Kontext injiziert
  3. Nach jeder Session wird die Konversation als Memories gespeichert

Architektur

┌─────────────────────────────────────────────────────────────┐
│                      Agent Request                          │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▌
┌─────────────────────────────────────────────────────────────┐
│                    Memory Search                            │
│                                                             │
│   SearchRequest { query, user_id, app_name }               │
│                         │                                   │
│                         â–Œ                                   │
│   ┌─────────────────────────────────────────────────────┐  │
│   │              MemoryService                          │  │
│   │  ┌─────────────┐  ┌─────────────┐  ┌────────────┐  │  │
│   │  │ InMemory    │  │ Vector DB   │  │ Custom     │  │  │
│   │  │ (dev/test)  │  │ (Qdrant)    │  │ Backend    │  │  │
│   │  └─────────────┘  └─────────────┘  └────────────┘  │  │
│   └─────────────────────────────────────────────────────┘  │
│                         │                                   │
│                         â–Œ                                   │
│   SearchResponse { memories: Vec<MemoryEntry> }            │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▌
┌─────────────────────────────────────────────────────────────┐
│              Context Injection                              │
│                                                             │
│   Relevant memories added to agent context                 │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▌
┌─────────────────────────────────────────────────────────────┐
│                    Agent Execution                          │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▌
┌─────────────────────────────────────────────────────────────┐
│                   Memory Storage                            │
│                                                             │
│   Session conversation stored for future recall            │
└─────────────────────────────────────────────────────────────┘

Best Practices

VorgehensweiseBeschreibung
Nutzen Sie eine Vektordatenbank in der ProduktionIn-Memory ist nur fÃŒr Entwicklung/Tests gedacht
Umfang nach Benutzer festlegenFÃŒgen Sie immer die user_id fÃŒr den Datenschutz hinzu
Ergebnisse begrenzenBegrenzen Sie die zurÃŒckgegebenen Erinnerungen, um einen KontextÃŒberlauf zu vermeiden
Alte Erinnerungen bereinigenImplementieren Sie TTL oder Archivierung fÃŒr veraltete Daten
Strategisch einbettenSpeichern Sie Zusammenfassungen, nicht rohe Konversationen

Vergleich mit Sessions

FeatureSession-StatusSpeicher
PersistenzLebensdauer der SessionPermanent
UmfangEinzelne SessionSession-ÃŒbergreifend
SucheSchlÃŒssel-Wert-SucheSemantische Suche
AnwendungsfallAktueller KontextLangzeitgedÀchtnis

ZurÃŒck: ← Guardrails | Weiter: Studio →