Créer une mémoire sémantique de projet avec Basic Memory et Milvus

Basic Memory stocke les connaissances relatives à un projet dans de simples fichiers Markdown et les rend accessibles via une interface en ligne de commande (CLI) et un serveur MCP. Cela offre à un développeur un espace durable où consigner les décisions, les guides d’intervention et les enseignements qui doivent être conservés au-delà d’une simple conversation.

Dans ce tutoriel, nous allons créer un petit projet de mémoire pour une équipe d'application. Nous enregistrerons des notes concernant la mise en cache, l'authentification, les déploiements et les sauvegardes, puis nous récupérerons la note appropriée grâce à une recherche sémantique et hybride.

Milvus stockera les vecteurs et effectuera une recherche par similarité. Basic Memory continuera à gérer les notes Markdown, les métadonnées du projet, la recherche en texte intégral et le manifeste de vecteurs dans PostgreSQL.

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

Ce tutoriel utilise Milvus Lite, qui s’exécute localement sur votre machine à un chemin d’accès donné. La même configuration de Basic Memory pourra par la suite pointer vers Milvus Standalone, Milvus Distributed ou Zilliz Cloud.

Prérequis

Vous devez disposer de :

  • Python 3.12 ou une version ultérieure
  • uv
  • Une base de données PostgreSQL et son URL de connexion postgresql+asyncpg://...
  • Une clé API OpenAI

Installez Basic Memory avec ses dépendances optionnelles Milvus depuis PyPI :

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

Configurez Basic Memory

Créez un espace de travail pour le tutoriel. En conservant ici la configuration de Basic Memory et les données Milvus Lite, vous pourrez facilement examiner l’exemple et le supprimer ultérieurement.

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

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

Configurez PostgreSQL comme base de données principale, OpenAI comme fournisseur d’embeddings et Milvus comme index vectoriel :

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-***********"

Ici, BASIC_MEMORY_MILVUS_URI est un chemin d'accès local ; PyMilvus lance donc automatiquement Milvus Lite. Aucun serveur Milvus distinct n'est nécessaire.

Milvus est facultatif dans la mémoire de base dans son ensemble, mais c’est le backend vectoriel sélectionné dans ce tutoriel. Cette sélection ne s’applique actuellement que lorsque le backend de base de données principal est PostgreSQL. Les projets de mémoire de base basés sur SQLite utilisent à la place sqlite-vec.

Créer un projet « memory »

Un projet Basic Memory associe un nom à un répertoire de notes Markdown. Ajoutez le répertoire du tutoriel en tant que projet et définissez-le comme projet par défaut :

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

L’équipe chargée de l’application dispose désormais d’un espace mémoire durable. Remplissons-le avec un petit catalogue hétérogène. Certaines notes seront pertinentes pour nos questions ultérieures, tandis que d’autres serviront de distracteurs réalistes.

Enregistrer les mémoires du projet

Commencez par la décision de mise en cache de l’application :

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

Enregistrez la manière dont les jetons d’authentification sont gérés :

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

Ajoutez deux guides d’exploitation :

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

Enfin, ajoutez deux notes produit sans rapport entre elles. Celles-ci rendent l’exercice de recherche plus représentatif qu’un catalogue dans lequel tous les documents sont pertinents :

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

Chaque note reste un simple fichier Markdown situé dans notes/. Basic Memory ajoute la structure permettant la recherche sans priver le système de fichiers de la propriété des fichiers.

Créez les index de recherche

Lancez une réindexation complète après avoir ajouté ou modifié de manière substantielle un groupe de notes :

bm reindex --full --project app-memory

Au cours de cette étape, Basic Memory :

  1. Lit et découpe les notes Markdown en segments.
  2. Construit l’index plein texte PostgreSQL.
  3. Envoie les segments au modèle d'embedding OpenAI configuré.
  4. Stocke les vecteurs résultants dans la collection Milvus spécifique au projet.
  5. Marque les segments stockés avec succès comme « prêts » dans son manifeste de vecteurs PostgreSQL.

Basic Memory utilise une collection Milvus déterministe pour chaque projet. Vous n'avez pas besoin de créer ni de nommer la collection vous-même.

Récupérer un souvenir par son sens

Supposons qu’un nouvel ingénieur se souvienne que l’application dispose d’une optimisation pour les requêtes répétées, mais qu’il ne se souvienne pas que l’équipe l’appelait une « stratégie de mise en cache ».

Utilisez la recherche vectorielle pour poser la question en langage naturel :

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

Caching Strategy devrait être le premier résultat, même si la requête n’a pas besoin de reprendre le titre de la note. La recherche vectorielle intègre la question et demande à Milvus les chunks stockés les plus proches.

Les scores exacts et les résultats moins bien classés peuvent varier en fonction du modèle d’encodage et du contenu du projet.

Combiner les signaux sémantiques et les mots-clés

Imaginons maintenant qu’il faille réagir à un incident de sécurité. La requête contient des termes exacts tels que « JWT », mais nous souhaitons également des expressions conceptuellement liées à la révocation de jetons et à la reconnexion.

Utilisez la recherche hybride :

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

Authentication Tokens devrait être le premier résultat. Basic Memory combine la recherche en texte intégral de PostgreSQL avec la recherche vectorielle de Milvus, en privilégiant les contenus performants dans l’une ou l’autre de ces voies, et en particulier ceux trouvés par les deux.

Les trois modes de recherche présentent des atouts différents :

ModeIndicateur de commandeUtilisation optimale
Texte intégralPas d'indicateur de modeTermes exacts, expressions et requêtes avec mots-clés booléens
Vecteur--vectorParaphrases, concepts et questions exploratoires
Hybride--hybridRecherche polyvalente utilisant à la fois des mots-clés et des signaux sémantiques

Utiliser un autre déploiement Milvus

Le code de l'application et les commandes Basic Memory restent inchangés lorsque vous dépassez les limites de Milvus Lite. Modifiez l'URI et, si nécessaire, fournissez un jeton.

Pour un serveur Milvus :

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

Pour Zilliz Cloud :

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

Créez une nouvelle collection cible ou suivez la procédure de migration du magasin de vecteurs de Basic Memory avant de basculer un projet existant entre deux backends vectoriels. Reconstruisez ensuite les vecteurs :

bm reindex --full --project app-memory

Utilisez la même mémoire via MCP

L'interface CLI est utile pour la configuration, la maintenance, la création de scripts et la compréhension du flux de données. Au quotidien, un client MCP peut démarrer le même service Basic Memory et appeler directement des outils tels que write_note, search_notes et build_context.

Par exemple, une configuration Codex MCP peut exécuter la commande installée par 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-***********"

D’autres clients MCP utilisent le même exécutable et les mêmes arguments au format 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-***********"
      }
    }
  }
}

Conservez les mots de passe de base de données et les clés API dans l’environnement de gestion des secrets ou de lancement de votre client lorsque cela est possible. Il est essentiel que le processus MCP reçoive la même configuration de mémoire de base que celle utilisée par l’interface en ligne de commande (CLI).

Ce que chaque couche de stockage gère

À la fin du tutoriel, les responsabilités sont délibérément séparées :

  • Le répertoire du projet gère les notes Markdown d’origine.
  • PostgreSQL gère les projets, les entités, les métadonnées, l'index plein texte et le manifeste vectoriel de référence de Basic Memory.
  • OpenAI transforme les extraits de notes et les requêtes de recherche en représentations vectorielles.
  • Milvus gère la persistance des vecteurs et la recherche du plus proche voisin.
  • Basic Memory coordonne ces couches et offre une expérience unifiée via une interface CLI et MCP.

Milvus ne remplace donc pas PostgreSQL dans cette intégration. Il remplace le chemin d'pgvector ation PostgreSQL pour le stockage des vecteurs et la recherche par similarité, tandis que le reste des fonctionnalités relationnelles et de recherche en texte intégral de Basic Memory reste dans PostgreSQL.