Skip to content

frabatx/agentic-memory-system

Repository files navigation

Memory Agent

Un benchmark tool per confrontare 3 paradigmi di memoria a lungo termine per LLM. Chatti con ogni sistema di memoria in tab indipendenti, poi analizzi le performance su una dashboard comparativa con metriche, grafici e replay side-by-side.


Struttura del Progetto

memory-agent/
├── src/                          # Backend Python
│   ├── cli/                      # CLI (Typer) — chat, compare, memory, serve
│   ├── agents/                   # Chat agent con tool calling
│   ├── tools/                    # Tools disponibili per l'agente (store_memory)
│   ├── config/
│   │   ├── settings.py           # Configurazione da .env
│   │   ├── taxonomy.yaml         # Tassonomia entita/relazioni/categorie
│   │   └── prompts/              # Prompt templates per entity extraction
│   ├── services/
│   │   ├── memory/
│   │   │   ├── amem/             # A-MEM — Knowledge Graph
│   │   │   │   ├── service.py    # Orchestratore store/retrieve
│   │   │   │   ├── inductor.py   # Estrazione entita, relazioni, keywords (LLM)
│   │   │   │   ├── linker.py     # Collegamento semantico tra note (LLM)
│   │   │   │   ├── evolver.py    # Evoluzione contesto/tags dei vicini (LLM)
│   │   │   │   └── note.py       # Modello nota strutturata
│   │   │   ├── linear/           # Linear RAG — ChromaDB + time decay
│   │   │   ├── context/          # Context Window — in-memory deque
│   │   │   ├── base.py           # Interfaccia comune MemoryServiceBase
│   │   │   └── models.py         # Modelli condivisi (Conversation, MemoryResult)
│   │   ├── database.py           # Connessione MongoDB (motor async)
│   │   ├── session.py            # CRUD sessioni
│   │   ├── conversation.py       # CRUD conversation turns + debug info
│   │   ├── embedding.py          # Servizio embedding OpenAI
│   │   ├── llm.py                # Servizio LLM OpenAI
│   │   ├── health.py             # Health check (Qdrant, ChromaDB, OpenAI)
│   │   └── obsidian.py           # Export/import Obsidian vault
│   └── webserver/
│       ├── app.py                # FastAPI app factory
│       ├── routers/              # Endpoint API (chat, session, conversation, memory, analytics, compare)
│       ├── dto/                  # Request/Response models (Pydantic)
│       └── services/             # Factory per memory services
├── frontend/                     # Frontend React + TypeScript
│   ├── src/
│   │   ├── pages/                # ChatPage, DashboardPage
│   │   ├── components/
│   │   │   ├── chat/             # Sidebar, MessageInput, MessageList, MemoryTypeSelector
│   │   │   ├── dashboard/        # MetricsCards, PerformanceChart, RelevanceDistribution, ChatReplay
│   │   │   ├── debug/            # DebugPanel (memorie recuperate, pipeline, entities)
│   │   │   └── layout/           # NavBar
│   │   └── hooks/                # useSession, useChat, useAnalytics, useReplay, useTheme...
│   └── vite.config.ts            # Vite config con proxy API -> :8000
├── docker/
│   └── docker-compose.yaml       # Qdrant (:6333), ChromaDB (:8100), MongoDB (:27017)
├── scripts/
│   ├── replay_interactions.py    # Replay programmatico dell'esperimento via API
│   └── test_chat.ps1             # Utility PowerShell per test rapido API
├── tests/
│   ├── conftest.py               # Fixture condivise (mock OpenAI, settings, user)
│   ├── e2e/                      # Test E2E con FastAPI TestClient
│   └── test_*.py                 # Test integrazione (Qdrant, ChromaDB, OpenAI)
├── docs/                         # Documentazione
│   ├── experiment-guide.md       # Come replicare l'esperimento di confronto
│   ├── architecture.md           # Architettura del sistema
│   ├── api-reference.md          # Riferimento API
│   ├── memory-systems.md         # Dettagli sui 3 sistemi di memoria
│   ├── amem-theory.md            # Paper A-MEM e teoria
│   ├── testing.md                # Guida ai test automatici
│   └── ...
├── .env.example                  # Template variabili d'ambiente
├── pyproject.toml                # Dipendenze Python (uv)
└── CLAUDE.md                     # Istruzioni per Claude Code

Quick Start

Prerequisiti

  • Python 3.11+ e uv
  • Docker (Qdrant, ChromaDB, MongoDB)
  • Node.js 18+ e npm (frontend React)
  • OpenAI API Key

Setup

git clone <repo-url> && cd memory-agent
cp .env.example .env          # aggiungi OPENAI_API_KEY
cd docker && docker compose up -d && cd ..
uv sync --extra dev            # backend
cd frontend && npm install && cd ..

Vedi docs/configuration.md per il riferimento completo alla configurazione (config.yaml, .env, override via variabili d'ambiente).

Avvio

# Produzione (consigliata)
cd frontend && npm run build && cd ..
uv run memory-agent serve

# Sviluppo (2 terminali)
uv run memory-agent serve              # Terminal 1 — backend :8000
cd frontend && npm run dev             # Terminal 2 — Vite :3000 (proxy -> :8000)

Apri http://localhost:8000 (produzione) o http://localhost:3000 (sviluppo).

CLI

uv run memory-agent chat -m amem       # A-MEM (knowledge graph)
uv run memory-agent chat -m amem -d    # con debug panel
uv run memory-agent chat -m linear     # Linear RAG (vector + time decay)
uv run memory-agent chat -m context    # Context Window (ultimi N messaggi)
uv run memory-agent compare "domanda"  # confronto parallelo dei 3 sistemi
uv run memory-agent memory list --type amem
uv run memory-agent memory clear --type all   # full reset

Architettura

Data Stores

Store Porta Contenuto
Qdrant 6333 A-MEM notes + entities (vector)
ChromaDB 8100 Linear RAG vectors (Docker debug only; app usa PersistentClient locale ./data/chromadb)
MongoDB 27017 Sessioni, conversation turns (con memory_type, metriche, debug info)

MongoDB Collections

sessions_id, user_id, memory_type, created_at, last_active

conversation_turns — ogni turno include:

  • session_id, user_id, memory_type (denormalizzato per aggregazioni veloci)
  • user_message, assistant_response, timestamp
  • response_time_ms, token_count, memories_retrieved_count
  • debug_info embedded (pre-retrieve, store pipeline, usage)

Indici: (user_id, memory_type) su sessions, (user_id, memory_type, timestamp) su turns.


API Endpoints

Chat & Comparison

Metodo Endpoint Descrizione
POST /api/chat/{memory_type} Chat con un sistema di memoria. Cattura response_time_ms, token_count, memories_retrieved_count
POST /api/compare Confronto parallelo dei 3 sistemi

Sessions (per-type)

Metodo Endpoint Descrizione
POST /api/session/create?user_id=X&memory_type=Y Crea sessione per tipo specifico
GET /api/session/user/{user_id}?memory_type=amem Lista sessioni (filtro opzionale per tipo)
GET /api/session/{session_id} Dettaglio sessione

Conversations

Metodo Endpoint Descrizione
GET /api/conversation/{session_id} Storico conversazione
GET /api/conversation/{session_id}/turns/{turn_id}/debug Debug info di un turno passato
GET /api/conversation/replay/{user_id}?limit=50 Turni raggruppati per memory_type (replay comparativo)
DELETE /api/conversation/{session_id} Cancella storico

Analytics

Metodo Endpoint Descrizione
GET /api/analytics/{user_id} Metriche aggregate, time series, distribuzione relevance

Response:

{
  "user_id": "frabatx",
  "metrics": [{
    "memory_type": "amem",
    "turn_count": 42,
    "avg_response_time_ms": 1234.5,
    "total_tokens": 50000,
    "avg_tokens_per_turn": 1190.5,
    "avg_memories_retrieved": 3.2,
    "memory_store_count": 38
  }],
  "time_series": [{
    "memory_type": "amem",
    "points": [{ "date": "2026-02-08", "avg_response_time_ms": 1100, "avg_tokens": 1200, "turn_count": 5 }]
  }],
  "relevance_distributions": [{
    "memory_type": "amem",
    "buckets": [{ "range_label": "0.8-1.0", "count": 15 }]
  }]
}

Memory & Health

Metodo Endpoint Descrizione
GET /api/memory/{memory_type} Lista memorie
DELETE /api/memory/{memory_type} Cancella memorie
GET /health Health check

Frontend

Chat Page — 3 Tab Indipendenti

Ogni tab (A-MEM, Linear, Context) mantiene sessioni e storico separati. La prima volta che scrivi in un tab, viene creata automaticamente una sessione con il memory_type corretto. La sidebar mostra solo le sessioni del tab attivo.

Dashboard — Analytics Comparativa

Layout:

  1. User Selector + Refresh
  2. Metrics Cards — 3 card color-coded (amem=viola, linear=cyan, context=ambra) con turn count, avg response time, total tokens, avg memories retrieved, store count
  3. Performance Chart (Recharts LineChart) — trend temporale di response time per tipo
  4. Relevance Distribution (Recharts BarChart) — distribuzione score di relevance in 5 bucket per tipo
  5. Chat Replay — 3 colonne scrollabili con le conversazioni di ogni sistema, per confronto qualitativo

Sistemi di Memoria

1. A-MEM (amem) — Knowledge Graph

Costruisce un grafo personale dalle conversazioni. Ogni messaggio produce entita, relazioni, categorie e una nota strutturata, collegati tra loro e persistiti come vettori in Qdrant.

Store Pipeline (9 step, 3 chiamate LLM):

User Message
  → [0] Retrieve context precedente (top-5 note simili + entita)
  → [1] Inductor (LLM #1): estrae entita, relazioni, categoria, summary, keywords
  → [2-4] Entity dedup, save relations, save category
  → [5-6] Linker (LLM #2): collega note semanticamente + link sequenziale
  → [7-8] Save nota in Qdrant + link bidirezionali
  → [9] Evolver (LLM #3, ogni N note): evolve context/tags dei vicini

Retrieve Pipeline — Graph RAG (3 canali):

Canale Strategia Score
1. Vector Search Cosine similarity su amem_notes Score reale (0.0–1.0)
2. Entity Graph Entity search → attributi + relation traversal (1-hop) Score entita × hop_decay (0.7)
3. Link Hop Segui link bidirezionali dalle note del Canale 1 0.5

Il contesto viene formattato in due sezioni nel system prompt:

  • Fatti noti — attributi e relazioni delle entita matchate (es. Marco.cognome = Fumagalli)
  • Conversazioni rilevanti — ranked per score con contesto

Knowledge Graph — 4 tipi di nodo:

Nodo Storage Esempio
Conversation Qdrant amem_notes nota strutturata con summary, keywords, tags, links
Entity Qdrant amem_entities person:Federico Brnotto con attributi e mentioned_in
Relation In-memory user --collega_di--> Giorgio
Category In-memory lavoro, famiglia, sogno

Tassonomia (tipi entita, relazioni, categorie): src/config/taxonomy.yaml

2. Linear RAG (linear) — Vector Search + Time Decay

  • Storage: ChromaDB
  • Retrieve: top-k per cosine similarity, poi score = similarity × exp(-age_days / 7.0)
  • Store: salva embedding della conversazione con timestamp

3. Context Window (context) — Ultimi N Messaggi

  • Storage: in-memory deque (volatile, non persiste tra restart)
  • Retrieve: ignora la query, restituisce gli ultimi N messaggi (default 10)

Dual Memory Mechanism

Ogni sistema di memoria ha due binari paralleli:

  1. Memoria Automatica — salva ogni coppia user/assistant automaticamente (_chat_loop in main.py)
  2. Memoria Esplicita — l'agente chiama il tool store_memory per fatti importanti (chat_agent.py)

Obsidian Integration

Le note A-MEM vengono esportate come Markdown in un vault Obsidian navigabile con Graph View.

# .env
OBSIDIAN_VAULT_PATH=.        # root del progetto come vault
EVOLUTION_THRESHOLD=2         # evolver ogni N note

Struttura: memories/{conversations,entities,categories}/ — file con YAML frontmatter e wikilinks.


User Stories

Il progetto e stato sviluppato in 7 fasi, per un totale di 84 user stories. Vedi l'elenco completo in docs/user-stories.md.

Fase US Contenuto
1. Core Backend US-001 → US-020 Servizi memoria (A-MEM, Linear, Context), Obsidian, embedding, LLM
2. API e CLI US-021 → US-033 FastAPI endpoints, Typer CLI, chat agent
3. Multi-User US-034 → US-043 Sessioni, scoping per utente, MongoDB
4. Frontend React US-044 → US-057 Chat page, dashboard, sidebar, routing
5. Documentazione US-059 → US-066 Guide in docs/
6. Testing e CI US-067 → US-082 pytest, E2E, CI GitHub Actions
7. Analytics e Debug US-102 → US-104 Debug panel, scaffolding Vite

Replicare l'Esperimento

Vuoi testare i 3 sistemi di memoria con la stessa conversazione e confrontare i risultati sulla dashboard? Leggi la Guida all'Esperimento — spiega passo passo come:

  1. Chattare con tutti e 3 i sistemi usando gli stessi messaggi
  2. Analizzare metriche, grafici e replay sulla dashboard comparativa
  3. Testare recall, persistenza e comportamento su conversazioni lunghe

Comandi Utili

uv run pytest                            # test (54 test)
uv run mypy src --ignore-missing-imports # type checking
uv run memory-agent memory clear --type all  # full reset (Qdrant + ChromaDB + MongoDB + Obsidian + Context)

Miglioramenti Futuri

Graph Retrieval

  • Multi-hop traversal (2+ hop, attualmente 1-hop)
  • KNN su grafo con networkx (BFS/DFS)
  • PageRank scoring per nodi centrali
  • Hybrid scoring: vector_similarity × 0.6 + graph_centrality × 0.4

Memory Evolver

  • Adaptive threshold (trigger piu frequente con grafi piccoli)
  • Global evolution pass (consolidamento periodico)
  • Decay/Pruning di link deboli
  • Clustering automatico di temi

Storage & Performance

  • Persistent graph cache su disco
  • Batch embedding
  • Incremental Qdrant sync

Advanced Features

  • Temporal reasoning ("cosa mi hai detto la settimana scorsa?")
  • Contradiction detection
  • Importance scoring
  • Forgetting curve (decay basato su frequenza di richiamo)
  • Memory consolidation (merge di note simili)

Evaluation & Benchmarking

  • A/B comparison dashboard — metriche, grafici, replay side-by-side
  • Latency trackingresponse_time_ms per ogni turno
  • Token trackingtoken_count per ogni turno
  • Relevance distribution — distribuzione score di retrieval per tipo
  • Memory accuracy tests — dataset di domande per misurare recall
  • Cost tracking granulare (token per induzione/linking/evolution separati)

About

A-MEM paper implementation: an agentic memory system that self-organizes conversations into structured, semantically-linked notes. Compare with Linear RAG and Context Window baselines via a web dashboard. Obsidian-compatible export.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors