MemPalace con Milvus

MemPalace es una capa de memoria para agentes de programación y flujos de trabajo de desarrollo de larga duración. Organiza el conocimiento del proyecto en alas, salas y cajones, y permite buscar el contenido original en todas las sesiones.

En este tutorial, utilizaremos la CLI de MemPalace para extraer un subconjunto real de la documentación pública de Milvus y almacenarlo en Milvus. El corpus contiene documentación sobre analizadores, tokenizadores y filtros de tokens. Estas páginas, estrechamente relacionadas entre sí, proporcionan suficientes elementos de distracción para que los ejemplos de recuperación resulten significativos.

El ejemplo utiliza Milvus Lite, por lo que se ejecuta localmente sin necesidad de Docker ni de un servidor de base de datos independiente. La misma configuración de MemPalace también puede apuntar a un servidor de Milvus o a Zilliz Cloud para implementaciones compartidas.

Requisitos previos

Instala MemPalace con sus dependencias opcionales de Milvus desde PyPI. El comando no especifica una versión de forma intencionada, por lo que una nueva instalación obtendrá la última versión disponible.

uv tool install "mempalace[milvus]"

También necesitas Git para descargar el corpus de documentación.

Este tutorial utiliza el modelo de incrustación MiniLM local de MemPalace, por lo que no requiere una clave de API de modelo externo. Es posible que el primer comando de minería o búsqueda descargue un pequeño modelo de incrustación ONNX.

Configurar el espacio de trabajo

Crea un espacio de trabajo con directorios separados para la documentación y MemPalace:

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"

Pasamos --backend milvus a los comandos de MemPalace que se muestran a continuación. Como no hay configurada ninguna URI remota de Milvus, MemPalace crea una base de datos local de Milvus Lite en $PALACE_DIR/milvus.db.

En cuanto al argumento de MilvusClient utilizado por el backend:

  • Establecer uri en una ruta local, como ./milvus.db, es la opción más conveniente. De este modo, se utiliza automáticamente Milvus Lite para almacenar los datos de forma local.
  • Para una implementación a mayor escala, puedes utilizar un servidor Milvus y configurar la URI con su punto de acceso, como http://localhost:19530.
  • Para utilizar Zilliz Cloud, configura la URI y el token con el punto final público y la clave API del clúster.

Descargar el corpus de documentación de Milvus

El repositorio de documentación de Milvus es mucho más extenso de lo que requiere este ejemplo. Utiliza la función «sparse checkout» de Git para descargar únicamente el directorio de documentación de Analyzer desde la rama 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"

En el momento de redactar este documento, este directorio contiene 31 páginas en formato Markdown. Entre ellas se incluyen guías generales de Analyzer y tres grupos de páginas estrechamente relacionadas:

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

Comprueba el número de páginas de origen:

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

Salida de referencia:

31

El recuento exacto puede variar a medida que se actualice la rama de documentación de Milvus.

Definir las salas de MemPalace

MemPalace puede detectar salas durante mempalace init, pero su flujo de inicialización también lleva a cabo una clasificación heurística de entidades en todo el proyecto y escribe los resultados aceptados en un registro de entidades. Ese paso de clasificación no es necesario para definir este corpus de documentación, por lo que proporcionamos directamente la pequeña taxonomía. Durante la extracción de datos, MemPalace puede seguir adjuntando metadatos de entidades heurísticos determinísticos y creando enlaces internos de pasillo; esas asociaciones no determinan qué sala recibe un archivo ni modifican las búsquedas dentro del ámbito de las salas que se indican a continuación.

Crea un archivo « $PROJECT_DIR/mempalace.yaml » con el siguiente contenido:

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: []

La «ala» representa el corpus de documentación completo. Una «habitación» representa un área temática. MemPalace enruta un archivo comprobando primero su directorio, luego su nombre de archivo y, a continuación, las palabras clave de las habitaciones que aparecen en su contenido. Un archivo ubicado en filter/, por ejemplo, va directamente a la habitación « filter ».

A continuación, cada archivo se divide en fragmentos de texto superpuestos. Cada fragmento se convierte en un «cajón» que contiene el código Markdown tal cual y metadatos como wing, room, source_file, chunk_index y los números de línea del código fuente. Las salas y los cajones siguen siendo metadatos lógicos dentro de las colecciones de Milvus de MemPalace; MemPalace no crea una colección de Milvus independiente para cada sala.

Extraer la documentación a Milvus

Extraer el proyecto con el backend de Milvus:

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

Resultado de referencia a partir de la instantánea de documentación validada:

=======================================================
  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 lee el Markdown sin resumirlo ni reescribirlo, calcula las incrustaciones locales y almacena los cajones en Milvus. En la instantánea de documentación probada, 31 archivos generaron 473 cajones.

Comprueba las salas resultantes y el recuento de carpetas:

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

Resultado de referencia:

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

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

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

El recuento exacto de «drawers» puede variar cuando cambia la documentación original, ya que las páginas más largas generan más fragmentos.

Utiliza mempalace search para recuperar documentación por significado. La siguiente pregunta no menciona ningún archivo específico ni ninguna característica de Analyzer:

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

Resultado de referencia (las puntuaciones pueden variar):

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

En la ejecución validada, los tres resultados procedían de « multi-language-analyzers.md », aunque el corpus también contenía páginas sobre analizadores, tokenizadores y filtros de idiomas concretos.

Búsqueda dentro de una sala

Los filtros de sala son útiles cuando aparecen conceptos relacionados a lo largo de todo el corpus. La siguiente consulta busca únicamente en la sala « filter » una forma de hacer coincidir términos equivalentes:

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

Resultado de referencia (las puntuaciones pueden variar):

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

El primer resultado debería proceder de synonym-filter.md. La restricción de sala se aplica a través de los metadatos de los cajones antes de la búsqueda vectorial, por lo que los cajones de tokenizadores y analizadores de lenguaje quedan excluidos de esta búsqueda.

Búsqueda de términos exactos

La CLI de MemPalace combina la similitud semántica con señales BM25 a la hora de clasificar los candidatos de la búsqueda vectorial. Por lo tanto, los nombres exactos de las configuraciones y de las características pueden mejorar la clasificación sin necesidad de cambiar a un modo de búsqueda independiente de la CLI.

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

Salida de referencia (las puntuaciones pueden variar):

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

Los resultados deberían favorecer a language-identifier.md, que documenta el tokenizador language_identifier utilizado para seleccionar analizadores en función del idioma detectado.

Inspecciona las colecciones de Milvus

MemPalace gestiona su esquema de Milvus automáticamente. Para confirmar lo que se ha almacenado, guarda el siguiente script como inspect_milvus.py. Este abre la misma base de datos de Milvus Lite, inspecciona las colecciones y cuenta los cajones por habitación:

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())))

Ejecuta el script con el mismo conjunto de dependencias opcionales que utiliza la CLI:

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

Salida de referencia:

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}

En la instantánea de documentación probada, mempalace_drawers contenía 473 filas y mempalace_closets contenía 74 registros de navegación interna. No es necesario que coincidan los recuentos de armarios y cajones. Los metadatos de los cajones mostraban 212 cajones en analyzer, 156 en filter y 105 en tokenizer.

Esta inspección se ejecuta en un nuevo proceso y vuelve a abrir la base de datos creada por la CLI, lo que también confirma que los datos se conservan entre comandos.

Opcional: utilizar el servidor Milvus o Zilliz Cloud

Para una implementación compartida, configura las variables de entorno de conexión a Milvus antes de ejecutar los mismos comandos de la CLI de MemPalace. Déjalas sin configurar para utilizar la base de datos local de Milvus Lite mostrada anteriormente.

Para el servidor Milvus:

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

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

Los comandos de principio a fin de este tutorial se han validado con Milvus Lite. Los ajustes del servidor y de la nube indicados anteriormente son configuraciones de implementación opcionales y no fueron necesarios para la validación local.

Conclusión

MemPalace ofrece a los agentes una forma estructurada de conservar el conocimiento del proyecto: un «ala» separa el corpus, las «salas» proporcionan un ámbito a nivel de tema y los «cajones» conservan el texto original de la fuente. En este ejemplo, 31 páginas de documentación de Milvus estrechamente relacionadas se convierten en cientos de cajones en los que se pueden realizar búsquedas, en lugar de unos pocos registros escritos a mano. Milvus proporciona almacenamiento persistente de vectores, datos dispersos, texto y metadatos detrás de esa estructura.