Creare una memoria semantica del progetto con Basic Memory e Milvus

Basic Memory conserva le conoscenze relative al progetto in normali file Markdown e le rende disponibili tramite una CLI e un server MCP. Ciò offre a un agente di programmazione uno spazio permanente in cui memorizzare decisioni, runbook e lezioni che dovrebbero sopravvivere oltre una singola conversazione.

In questo tutorial, creeremo un piccolo progetto di memoria per un team di sviluppo applicativo. Registreremo note relative a caching, autenticazione, distribuzioni e backup, per poi recuperare la nota corretta tramite la ricerca semantica e ibrida.

Milvus memorizzerà i vettori ed eseguirà la ricerca per similarità. Basic Memory continuerà a gestire le note Markdown, i metadati del progetto, la ricerca full-text e il manifesto dei vettori in PostgreSQL.

Markdown notes
      |
      v
Basic Memory CLI / MCP
      |-- PostgreSQL: projects, metadata, full-text search, vector manifest
      |-- OpenAI: embeddings
      `-- Milvus: vector persistence and similarity search

Questo tutorial utilizza Milvus Lite, che viene eseguito localmente in un percorso sul proprio computer. La stessa configurazione di Basic Memory potrà in seguito puntare a Milvus Standalone, Milvus Distributed o Zilliz Cloud.

Prerequisiti

È necessario:

  • Python 3.12 o versioni successive
  • uv
  • Un database PostgreSQL e il relativo URL di connessione postgresql+asyncpg://...
  • Una chiave API OpenAI

Installare Basic Memory con le sue dipendenze opzionali Milvus da PyPI:

uv tool install --python 3.12 "basic-memory[milvus]"

Configurare Basic Memory

Creare un'area di lavoro per il tutorial. Mantenere qui la configurazione di Basic Memory e i dati di Milvus Lite rende l'esempio facile da esaminare e rimuovere in seguito.

mkdir -p basic-memory-milvus-demo/notes
cd basic-memory-milvus-demo

export BASIC_MEMORY_CONFIG_DIR="$PWD/.basic-memory"

Configurare PostgreSQL come database principale, OpenAI come provider di embedding e Milvus come indice vettoriale:

export BASIC_MEMORY_DATABASE_BACKEND=postgres
export BASIC_MEMORY_DATABASE_URL="postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE"

export BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED=true
export BASIC_MEMORY_SEMANTIC_VECTOR_INDEX=milvus
export BASIC_MEMORY_MILVUS_URI="$PWD/basic-memory-vectors.db"

export BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER=openai
export BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL=text-embedding-3-small
export OPENAI_API_KEY="sk-***********"

In questo caso, BASIC_MEMORY_MILVUS_URI è un percorso locale, quindi PyMilvus avvia automaticamente Milvus Lite. Non è necessario un server Milvus separato.

Milvus è opzionale in Basic Memory nel suo complesso, ma in questo tutorial è il backend vettoriale selezionato. Attualmente la selezione si applica solo quando il backend del database principale è PostgreSQL. I progetti Basic Memory basati su SQLite utilizzano invece sqlite-vec.

Creare un progetto in memoria

Un progetto Basic Memory associa un nome a una directory contenente note in formato Markdown. Aggiungi la directory del tutorial come progetto e impostala come predefinita:

bm project add app-memory "$PWD/notes" --default

Il team dell’applicazione dispone ora di uno spazio di memoria persistente. Riempiamolo con un piccolo catalogo misto. Alcune note saranno rilevanti per le nostre domande successive, mentre altre fungeranno da distrattori realistici.

Registrare le memorie del progetto

Inizia con la decisione relativa alla cache dell’applicazione:

bm tool write-note \
  --title "Caching Strategy" \
  --folder "engineering" \
  --project app-memory <<'EOF'
# Caching Strategy

The application caches read-heavy product responses in Redis for five minutes. This avoids repeated database queries and makes repeated requests faster. Cache entries are invalidated immediately after a write.
EOF

Registra come vengono gestiti i token di autenticazione:

bm tool write-note \
  --title "Authentication Tokens" \
  --folder "engineering" \
  --project app-memory <<'EOF'
# Authentication Tokens

JWT access tokens expire after fifteen minutes. Refresh tokens rotate on every use. After suspicious activity, revoke the entire token family and require the user to sign in again.
EOF

Aggiungi due runbook operativi:

bm tool write-note \
  --title "Deployment Reliability" \
  --folder "operations" \
  --project app-memory <<'EOF'
# Deployment Reliability

Production releases use a canary deployment. Readiness probes must pass before traffic shifts, and the rollout automatically stops when the error rate crosses the agreed threshold.
EOF

bm tool write-note \
  --title "Database Backups" \
  --folder "operations" \
  --project app-memory <<'EOF'
# Database Backups

PostgreSQL uses daily snapshots and continuous write-ahead log archiving. The team runs a restore drill every month and records the recovery point and recovery time.
EOF

Infine, aggiungi due note sul prodotto non correlate. Queste rendono l’esercizio di ricerca più rappresentativo rispetto a un catalogo in cui ogni documento è rilevante:

bm tool write-note \
  --title "UI Accessibility" \
  --folder "product" \
  --project app-memory <<'EOF'
# UI Accessibility

The settings screen must support keyboard navigation, visible focus states, sufficient color contrast, and descriptive labels for screen readers.
EOF

bm tool write-note \
  --title "Content Planning" \
  --folder "product" \
  --project app-memory <<'EOF'
# Content Planning

The content calendar tracks blog drafts, launch screenshots, reviewers, and publication dates for the next product release.
EOF

Ogni nota rimane un normale file Markdown in notes/. Basic Memory aggiunge la struttura ricercabile senza sottrarre il controllo al filesystem.

Crea gli indici di ricerca

Eseguire una reindicizzazione completa dopo aver aggiunto o modificato in modo sostanziale un gruppo di note:

bm reindex --full --project app-memory

Durante questa fase, Basic Memory:

  1. Legge e suddivide in blocchi le note Markdown.
  2. Crea l’indice full-text in PostgreSQL.
  3. Invia i segmenti al modello di embedding OpenAI configurato.
  4. Memorizza i vettori risultanti nella collezione Milvus specifica del progetto.
  5. Contrassegna i blocchi archiviati con successo come pronti nel proprio manifesto dei vettori PostgreSQL.

Basic Memory utilizza una collezione Milvus deterministica per ogni progetto. Non è necessario creare o denominare la collezione autonomamente.

Recupera una memoria in base al significato

Supponiamo che un nuovo ingegnere ricordi che l’applicazione dispone di un’ottimizzazione per le richieste ripetute, ma non ricordi che il team l’ha definita “strategia di caching”.

Utilizza la ricerca vettoriale per porre la domanda in linguaggio naturale:

bm tool search-notes \
  "How does the application make repeated requests faster?" \
  --vector \
  --project app-memory \
  --page-size 3 \
  --plain

Caching Strategy dovrebbe essere il risultato principale anche se la query non deve necessariamente ripetere il titolo della nota. La ricerca vettoriale incorpora la domanda e chiede a Milvus i blocchi memorizzati più vicini.

I punteggi esatti e i risultati con un posizionamento inferiore possono variare a seconda del modello di embedding e dei contenuti del progetto.

Combina segnali semantici e basati su parole chiave

Ora immagina di dover rispondere a un incidente di sicurezza. La query contiene termini esatti come « JWT », ma vogliamo anche un linguaggio concettualmente correlato alla revoca dei token e al nuovo accesso.

Utilizzate la ricerca ibrida:

bm tool search-notes \
  "JWT rotation after suspicious activity" \
  --hybrid \
  --project app-memory \
  --page-size 3 \
  --plain

Authentication Tokens dovrebbe essere il risultato principale. Basic Memory combina il recupero full-text di PostgreSQL con il recupero vettoriale di Milvus, privilegiando i contenuti che si distinguono in uno dei due percorsi e, in particolare, quelli individuati da entrambi.

Le tre modalità di ricerca presentano diversi punti di forza:

ModalitàFlag di comandoUso ottimale
Testo completoNessun flag di modalitàTermini esatti, frasi e query con parole chiave booleane
Vettoriale--vectorParafrasi, concetti e domande esplorative
Ibrido--hybridRicerca generica che utilizza sia segnali basati su parole chiave che segnali semantici

Utilizza un'altra installazione di Milvus

Il codice dell'applicazione e i comandi di Basic Memory non cambiano quando si supera la capacità di Milvus Lite. Modificare l'URI e, se necessario, fornire un token.

Per un server Milvus:

export BASIC_MEMORY_MILVUS_URI="http://localhost:19530"
export BASIC_MEMORY_MILVUS_TOKEN="root:Milvus"

Per Zilliz Cloud:

export BASIC_MEMORY_MILVUS_URI="https://YOUR_CLUSTER_ENDPOINT"
export BASIC_MEMORY_MILVUS_TOKEN="YOUR_API_KEY"

Creare una nuova raccolta di destinazione o seguire la procedura di migrazione dell’archivio vettoriale di Basic Memory prima di passare da un backend vettoriale a un altro in un progetto esistente. Quindi ricompilare i vettori:

bm reindex --full --project app-memory

Utilizza la stessa memoria tramite MCP

La CLI è utile per la configurazione, la manutenzione, la creazione di script e la comprensione del flusso di dati. Nel lavoro quotidiano, un client MCP può avviare lo stesso servizio Basic Memory e richiamare direttamente strumenti quali write_note, search_notes e build_context.

Ad esempio, una configurazione MCP di Codex può eseguire il comando installato da uv tool:

[mcp_servers.basic-memory]
command = "basic-memory"
args = ["mcp"]

[mcp_servers.basic-memory.env]
BASIC_MEMORY_CONFIG_DIR = "/absolute/path/to/basic-memory-milvus-demo/.basic-memory"
BASIC_MEMORY_DATABASE_BACKEND = "postgres"
BASIC_MEMORY_DATABASE_URL = "postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE"
BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED = "true"
BASIC_MEMORY_SEMANTIC_VECTOR_INDEX = "milvus"
BASIC_MEMORY_MILVUS_URI = "/absolute/path/to/basic-memory-milvus-demo/basic-memory-vectors.db"
BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER = "openai"
BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL = "text-embedding-3-small"
OPENAI_API_KEY = "sk-***********"

Altri client MCP utilizzano lo stesso eseguibile e gli stessi argomenti in formato JSON:

{
  "mcpServers": {
    "basic-memory": {
      "command": "basic-memory",
      "args": ["mcp"],
      "env": {
        "BASIC_MEMORY_CONFIG_DIR": "/absolute/path/to/basic-memory-milvus-demo/.basic-memory",
        "BASIC_MEMORY_DATABASE_BACKEND": "postgres",
        "BASIC_MEMORY_DATABASE_URL": "postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE",
        "BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED": "true",
        "BASIC_MEMORY_SEMANTIC_VECTOR_INDEX": "milvus",
        "BASIC_MEMORY_MILVUS_URI": "/absolute/path/to/basic-memory-milvus-demo/basic-memory-vectors.db",
        "BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER": "openai",
        "BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL": "text-embedding-3-small",
        "OPENAI_API_KEY": "sk-***********"
      }
    }
  }
}

Se possibile, conservare le password del database e le chiavi API nella gestione dei segreti del proprio client o nell’ambiente di avvio. Il requisito fondamentale è che il processo MCP riceva la stessa configurazione Basic Memory utilizzata dalla CLI.

Cosa appartiene a ciascun livello di archiviazione

Al termine del tutorial, le responsabilità sono state volutamente separate:

  • La directory del progetto contiene le note Markdown originali.
  • PostgreSQL gestisce i progetti, le entità, i metadati, l’indice full-text e il manifesto vettoriale autorevole di Basic Memory.
  • OpenAI trasforma i blocchi di note e le domande di ricerca in embedding.
  • Milvus gestisce la persistenza dei vettori e il recupero del vicino più prossimo.
  • Basic Memory coordina i livelli e fornisce un'unica interfaccia CLI e MCP.

Milvus, quindi, non sostituisce PostgreSQL in questa integrazione. Sostituisce il percorso pgvector di PostgreSQL per l’archiviazione dei vettori e la ricerca per similarità, mentre il resto delle funzionalità relazionali e full-text di Basic Memory rimangono in PostgreSQL.