MemPalace con Milvus

MemPalace è un livello di memoria per agenti di codifica e flussi di lavoro di sviluppo di lunga durata. Organizza le conoscenze relative al progetto in ali, stanze e cassetti, rendendo poi i contenuti originali ricercabili tra una sessione e l'altra.

In questo tutorial, utilizzeremo la CLI di MemPalace per estrarre un sottoinsieme reale della documentazione pubblica di Milvus e memorizzarlo in Milvus. Il corpus contiene documentazione su analizzatori, tokenizzatori e filtri di token. Queste pagine strettamente correlate forniscono elementi di distrazione sufficienti a rendere significativi gli esempi di recupero.

L’esempio utilizza Milvus Lite, quindi viene eseguito localmente senza Docker né un server di database separato. La stessa configurazione di MemPalace può anche puntare a un server Milvus o a Zilliz Cloud per distribuzioni condivise.

Prerequisiti

Installare MemPalace con le sue dipendenze Milvus opzionali da PyPI. Il comando non specifica intenzionalmente una versione, quindi una nuova installazione utilizzerà l’ultima versione disponibile.

uv tool install "mempalace[milvus]"

È inoltre necessario Git per scaricare il corpus della documentazione.

Questo tutorial utilizza il modello di embedding MiniLM locale di MemPalace, quindi non richiede una chiave API per un modello esterno. Il primo comando di estrazione o ricerca potrebbe scaricare un piccolo modello di embedding ONNX.

Configurare l’area di lavoro

Creare un'area di lavoro con directory separate per la documentazione e il palace:

mkdir -p mempalace-milvus-demo
cd mempalace-milvus-demo

export PALACE_DIR="$PWD/palace"
export DOCS_REPO="$PWD/milvus-docs"
export PROJECT_DIR="$PWD/milvus-analyzer-docs"
export MEMPALACE_EMBEDDING_MODEL="minilm"
export MEMPALACE_EMBEDDING_DEVICE="cpu"
export MEMPALACE_EMBEDDING_THREADS="2"

Passiamo --backend milvus ai comandi MemPalace riportati di seguito. Poiché non è configurato alcun URI Milvus remoto, MemPalace crea un database Milvus Lite locale all’indirizzo $PALACE_DIR/milvus.db.

Per quanto riguarda l’argomento MilvusClient utilizzato dal backend:

  • Impostare uri su un percorso locale, come ./milvus.db, è l’opzione più comoda. In questo modo utilizza automaticamente Milvus Lite per archiviare i dati localmente.
  • Per un'implementazione su scala più ampia, è possibile utilizzare un server Milvus e impostare l'URI sul suo endpoint, ad esempio http://localhost:19530.
  • Per utilizzare Zilliz Cloud, impostare l’URI e il token sull’endpoint pubblico e sulla chiave API del cluster.

Scaricare il corpus della documentazione di Milvus

Il repository della documentazione di Milvus è molto più ampio di quanto richiesto da questo esempio. Utilizzare il checkout sparso di Git per scaricare solo la directory della documentazione di Analyzer dal ramo v3.0.x:

git clone \
  --depth 1 \
  --filter=blob:none \
  --sparse \
  --branch v3.0.x \
  https://github.com/milvus-io/milvus-docs.git \
  "$DOCS_REPO"

git -C "$DOCS_REPO" sparse-checkout set \
  site/en/userGuide/schema/analyzer

cp -R \
  "$DOCS_REPO/site/en/userGuide/schema/analyzer" \
  "$PROJECT_DIR"

Al momento della stesura di questo documento, questa directory contiene 31 pagine Markdown. Esse includono guide generali su Analyzer e tre gruppi di pagine strettamente correlate:

milvus-analyzer-docs/
├── analyzer/       # Built-in language analyzers
├── filter/         # Token filters
├── tokenizer/      # Tokenizers
└── *.md            # Analyzer overviews and selection guides

Verifica il numero di pagine sorgente:

find "$PROJECT_DIR" -type f -name "*.md" | wc -l

Output di riferimento:

31

Il conteggio esatto potrebbe variare man mano che il ramo della documentazione di Milvus viene aggiornato.

Definizione delle stanze di MemPalace

MemPalace è in grado di rilevare le stanze durante l'mempalace init, ma il suo flusso di inizializzazione esegue anche una classificazione euristica delle entità a livello di progetto e scrive i risultati accettati in un registro delle entità. Tale fase di classificazione non è necessaria per definire questo corpus di documentazione, pertanto forniamo direttamente una piccola tassonomia. Durante l'estrazione, MemPalace potrebbe comunque associare metadati euristici deterministici alle entità e creare collegamenti interni; tali associazioni non determinano quale stanza riceva un file né modificano le ricerche a livello di stanza descritte di seguito.

Creare un file ` $PROJECT_DIR/mempalace.yaml ` con il seguente contenuto:

wing: milvus_analyzer_docs
rooms:
  - name: analyzer
    description: Built-in language analyzers and analyzer selection guides
    keywords:
      - analyzer
  - name: filter
    description: Token filters used in analyzer pipelines
    keywords:
      - filter
  - name: tokenizer
    description: Tokenizers and language identification
    keywords:
      - tokenizer
  - name: general
    description: Analyzer documentation that does not fit another room
    keywords: []

L’ala rappresenta l’intero corpus di documentazione. Una stanza rappresenta un’area tematica. MemPalace indirizza un file controllando prima la sua directory, poi il nome del file e infine le parole chiave relative alle stanze presenti nel suo contenuto. Un file che si trova in filter/, ad esempio, va direttamente nella stanza filter.

Ogni file viene quindi suddiviso in blocchi di testo sovrapposti. Ogni blocco diventa un cassetto contenente il Markdown testuale e metadati quali wing, room, source_file, chunk_index e i numeri di riga della fonte. Le stanze e i cassetti rimangono metadati logici all’interno delle collezioni Milvus di MemPalace; MemPalace non crea una collezione Milvus separata per ogni stanza.

Estrai la documentazione in Milvus

Estrarre i dati del progetto con il backend Milvus:

mempalace \
  --palace "$PALACE_DIR" \
  mine "$PROJECT_DIR" \
  --backend milvus

Riferimento all’output dall’istantanea della documentazione convalidata:

=======================================================
  Done.
  Files processed: 31
  Files skipped (already filed or other): 0
  Drawers filed: 473

  By room:
    filter               16 files
    analyzer              8 files
    tokenizer             7 files
=======================================================

MemPalace legge il Markdown senza riassumerlo né riscriverlo, calcola gli embedding locali e memorizza i cassetti in Milvus. Nello snapshot della documentazione testato, 31 file hanno prodotto 473 cassetti.

Verifica le stanze risultanti e il numero di cassetti:

mempalace --palace "$PALACE_DIR" status --backend milvus

Output di riferimento:

=======================================================
  MemPalace Status -- 473 drawers
=======================================================

  WING: milvus_analyzer_docs
    ROOM: analyzer               212 drawers
    ROOM: filter                 156 drawers
    ROOM: tokenizer              105 drawers

=======================================================

Il numero esatto di "drawer" può variare quando la documentazione a monte cambia, poiché le pagine più lunghe producono un numero maggiore di segmenti.

Utilizza mempalace search per recuperare la documentazione in base al significato. La seguente domanda non menziona un file specifico né una funzionalità di Analyzer:

mempalace \
  --palace "$PALACE_DIR" \
  search "How should I analyze documents that mix several languages?" \
  --backend milvus \
  --wing milvus_analyzer_docs \
  --results 3

Risultato di riferimento (i punteggi possono variare):

Results for: "How should I analyze documents that mix several languages?"
Wing: milvus_analyzer_docs

[1] milvus_analyzer_docs / analyzer
    Source: multi-language-analyzers.md
    Match: cosine_sim=0.334 bm25=2.469
[2] milvus_analyzer_docs / analyzer
    Source: multi-language-analyzers.md
[3] milvus_analyzer_docs / analyzer
    Source: multi-language-analyzers.md

Nell'esecuzione convalidata, tutti e tre i risultati provenivano da multi-language-analyzers.md, anche se il corpus conteneva anche pagine relative a singoli analizzatori linguistici, tokenizzatori e filtri.

Ricerca all’interno di una stanza

I filtri delle stanze sono utili quando concetti correlati compaiono in tutto il corpus. La seguente query cerca solo nella stanza filter un modo per far corrispondere termini equivalenti:

mempalace \
  --palace "$PALACE_DIR" \
  search "How can equivalent terms such as USA and United States match one another?" \
  --backend milvus \
  --wing milvus_analyzer_docs \
  --room filter \
  --results 3

Risultato di riferimento (i punteggi possono variare):

Results for: "How can equivalent terms such as USA and United States match one another?"
Wing: milvus_analyzer_docs
Room: filter

[1] milvus_analyzer_docs / filter
    Source: synonym-filter.md
    Match: cosine_sim=0.765 bm25=2.573
[2] milvus_analyzer_docs / filter
    Source: stemmer-filter.md
[3] milvus_analyzer_docs / filter
    Source: stop-filter.md

Il primo risultato dovrebbe provenire da synonym-filter.md. Il vincolo della stanza viene applicato tramite i metadati dei cassetti prima della ricerca vettoriale, pertanto i cassetti dei tokenizzatori e degli analizzatori linguistici sono esclusi da questa ricerca.

Ricerca di termini esatti

La CLI di MemPalace combina la somiglianza semantica con i segnali BM25 nel classificare i candidati della ricerca vettoriale. I nomi esatti delle configurazioni e delle funzionalità possono quindi migliorare il posizionamento senza dover passare a una modalità di ricerca separata della CLI.

mempalace \
  --palace "$PALACE_DIR" \
  search "language_identifier tokenizer" \
  --backend milvus \
  --wing milvus_analyzer_docs \
  --room tokenizer \
  --results 3

Output di riferimento (i punteggi possono variare):

Results for: "language_identifier tokenizer"
Wing: milvus_analyzer_docs
Room: tokenizer

[1] milvus_analyzer_docs / tokenizer
    Source: language-identifier.md
    Match: cosine_sim=0.420 bm25=0.969
[2] milvus_analyzer_docs / tokenizer
    Source: language-identifier.md
[3] milvus_analyzer_docs / tokenizer
    Source: lindera-tokenizer.md

I risultati dovrebbero privilegiare language-identifier.md, che documenta il tokenizer language_identifier utilizzato per selezionare gli analizzatori in base alla lingua rilevata.

Ispezionare le raccolte Milvus

MemPalace gestisce automaticamente il proprio schema Milvus. Per verificare cosa è stato memorizzato, salvare il seguente script come inspect_milvus.py. Esso apre lo stesso database Milvus Lite, esamina le collezioni e conta i cassetti per stanza:

import os
from collections import Counter

from pymilvus import MilvusClient


client = MilvusClient(uri=os.environ["MEMPALACE_MILVUS_LITE_PATH"])

for collection_name in sorted(client.list_collections()):
    stats = client.get_collection_stats(collection_name)
    schema = client.describe_collection(collection_name)
    fields = [field["name"] for field in schema["fields"]]
    print(f"{collection_name}: rows={stats['row_count']}, fields={fields}")

client.load_collection("mempalace_drawers")
rows = client.query(
    collection_name="mempalace_drawers",
    filter='metadata["wing"] == "milvus_analyzer_docs"',
    limit=2000,
    output_fields=["metadata"],
)
room_counts = Counter(row["metadata"]["room"] for row in rows)
print("Drawers by room:", dict(sorted(room_counts.items())))

Esegui lo script con lo stesso set di dipendenze opzionali utilizzato dalla CLI:

export MEMPALACE_MILVUS_LITE_PATH="$PALACE_DIR/milvus.db"
uv run --with "mempalace[milvus]" inspect_milvus.py

Output di riferimento:

mempalace_closets: rows=74, fields=['id', 'document', 'metadata', 'vector', 'sparse']
mempalace_drawers: rows=473, fields=['id', 'document', 'metadata', 'vector', 'sparse']
Drawers by room: {'analyzer': 212, 'filter': 156, 'tokenizer': 105}

Per l’istantanea della documentazione testata, mempalace_drawers conteneva 473 righe e mempalace_closets conteneva 74 record di navigazione interna. Il numero di armadi e cassetti non deve necessariamente corrispondere. I metadati dei cassetti mostravano 212 cassetti in analyzer, 156 in filter e 105 in tokenizer.

Questa ispezione viene eseguita in un nuovo processo e riapre il database creato dalla CLI, il che conferma anche che i dati permangono tra un comando e l’altro.

Opzionale: utilizzare il server Milvus o Zilliz Cloud

Per una distribuzione condivisa, impostare le variabili d’ambiente di connessione a Milvus prima di eseguire gli stessi comandi della CLI di MemPalace. Lasciarle disimpostate per utilizzare il database locale di Milvus Lite mostrato sopra.

Per il server Milvus:

export MEMPALACE_MILVUS_URI="http://localhost:19530"
export MEMPALACE_MILVUS_DB_NAME="default"
export MEMPALACE_MILVUS_NAMESPACE="team-memory"

Per Zilliz Cloud:

export MEMPALACE_MILVUS_URI="https://your-cluster.api.region.zillizcloud.com"
export MEMPALACE_MILVUS_TOKEN="your-api-key"
export MEMPALACE_MILVUS_DB_NAME="default"
export MEMPALACE_MILVUS_NAMESPACE="team-memory"

I comandi end-to-end in questo tutorial sono stati convalidati con Milvus Lite. Le impostazioni relative al server e al cloud sopra indicate sono configurazioni di distribuzione opzionali e non erano necessarie per la convalida locale.

Conclusione

MemPalace offre agli agenti un modo strutturato per conservare le conoscenze relative al progetto: un'ala separa il corpus, le stanze forniscono un ambito a livello di argomento e i cassetti conservano il testo originale di origine. In questo esempio, 31 pagine di documentazione Milvus strettamente correlate diventano centinaia di cassetti ricercabili anziché pochi record scritti a mano. Milvus fornisce un'archiviazione persistente di vettori, dati sparsi, testo e metadati alla base di tale struttura.