跳到主要内容
版本:v3.0.x

MemPalace with Milvus

MemPalace 是面向编程 Agent 和长期开发工作流的记忆层。它将项目知识组织到 wing、room 和 drawer 中,并支持跨会话检索原始内容。

在本教程中,我们将使用 MemPalace CLI,从公开的 Milvus 文档 中挖掘一个真实的文档子集,并将其存储到 Milvus 中。该语料库包含有关 Analyzer、Tokenizer 和 Token Filter 的文档。这些内容密切相关的页面提供了足够多的干扰项,使检索示例更具实际意义。

本示例使用 Milvus Lite,因此可以在本地运行,无需 Docker 或单独的数据库服务器。同一套 MemPalace 配置也可以连接到 Milvus Server 或 Zilliz Cloud,以支持共享部署。

Prerequisites

从 PyPI 安装 MemPalace 及其可选的 Milvus 依赖项。该命令特意不固定版本,因此全新安装时会解析并安装最新可用版本。

Shell
uv tool install "mempalace[milvus]"

你还需要安装 Git,以便下载文档语料库。

本教程使用 MemPalace 的本地 MiniLM Embedding 模型,因此不需要外部模型 API key。首次运行挖掘或搜索命令时,可能会下载一个小型 ONNX Embedding 模型。

Configure the workspace

创建一个 workspace,并为文档和 palace 分别设置目录:

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

在下面的 MemPalace 命令中,我们会传入 --backend milvus。由于未配置远程 Milvus URI,MemPalace 会在 $PALACE_DIR/milvus.db 创建本地 Milvus Lite Database。

对于后端使用的 MilvusClient 参数:

  • uri 设置为本地路径(例如 ./milvus.db)是最便捷的选择。这会自动使用 Milvus Lite 在本地存储数据。
  • 对于较大规模的部署,你可以使用 Milvus server,并将 URI 设置为其 endpoint,例如 http://localhost:19530
  • 如需使用 Zilliz Cloud,请将 URI 和 token 设置为集群的 Public Endpoint 和 API key

下载 Milvus 文档语料库

Milvus 文档仓库的规模远超本示例所需。使用 Git 稀疏检出,仅下载 v3.0.x 分支中的 Analyzer 文档目录:

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

撰写本文时,此目录包含 31 个 Markdown 页面,其中包括通用 Analyzer 指南和三组密切相关的页面:

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

确认源页面的数量:

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

参考输出:

Text
31

随着 Milvus 文档分支的更新,确切数量可能会发生变化。

定义 MemPalace 房间

MemPalace 可以在执行 mempalace init 时检测房间,但其初始化流程还会对整个项目执行启发式 Entity 分类,并将接受的结果写入 Entity 注册表。定义本文档语料库不需要此分类步骤,因此我们直接提供精简的分类体系。在挖掘过程中,MemPalace 仍可能附加确定性的启发式 Entity 元数据并构建内部走廊链接;这些关联不会决定文件被分配到哪个房间,也不会改变下文基于房间范围的检索。

创建 $PROJECT_DIR/mempalace.yaml,内容如下:

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

wing 表示整个文档语料库,room 表示一个主题领域。MemPalace 路由文件时,依次检查文件所在目录、文件名以及文件内容中的 room 关键词。例如,filter/ 目录下的文件会直接路由到 filter room。

随后,每个文件会被拆分为相互重叠的文本块。每个文本块都会成为一个 drawer,其中包含原始 Markdown,以及 wingroomsource_filechunk_index 和源文件行号等元数据。room 和 drawer 在 MemPalace 的 Milvus Collection 中仍属于逻辑元数据;MemPalace 不会为每个 room 分别创建一个 Milvus Collection。

Mine the documentation into Milvus

使用 Milvus 后端挖掘项目:

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

以下是基于已验证文档快照的参考输出:

Text
=======================================================
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 直接读取 Markdown,不进行摘要或改写,然后计算本地 Embedding,并将 drawers 存储到 Milvus。在测试使用的文档快照中,31 个文件生成了 473 个 drawers。

检查生成的 rooms 和 drawer 数量:

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

参考输出:

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

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

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

当上游文档发生变化时,确切的 drawer 数量也可能变化,因为较长的页面会生成更多分块。

使用 mempalace search 按语义检索文档。以下问题并未指定具体文件,也未明确提及某个 Analyzer 功能:

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

参考输出(分数可能有所不同):

Text
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

在经过验证的运行中,三个结果均来自 multi-language-analyzers.md,尽管语料库中还包含介绍各语言 Analyzer、Tokenizer 和 Filter 的页面。

在 Room 内搜索

当相关概念分散在整个语料库中时,Room Filter 非常实用。以下查询仅在 filter Room 中搜索,以找到让等价术语相互匹配的方法:

Shell
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

参考输出(分数可能有所不同):

Text
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

排名第一的结果应来自 synonym-filter.md。在向量搜索之前,系统会通过 drawer metadata 应用 Room 约束,因此本次搜索会排除 tokenizer 和 language-analyzer drawer。

搜索精确术语

MemPalace CLI 在对向量检索候选结果进行排序时,会结合语义相似度与 BM25 信号。因此,使用准确的配置名称和功能名称即可提升排序效果,无需切换到单独的 CLI 搜索模式。

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

参考输出(分数可能有所不同):

Text
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

结果应优先显示 language-identifier.md。该文档介绍了 language_identifier Tokenizer,它用于根据检测到的语言选择 Analyzer。

Inspect the Milvus Collection

MemPalace 会自动管理其 Milvus Schema。要确认存储的内容,请将以下脚本保存为 inspect_milvus.py。该脚本会打开同一个 Milvus Lite 数据库,检查其中的 Collection,并按 room 统计 drawer 数量:

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

使用与 CLI 相同的可选依赖集运行该脚本:

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

参考输出:

Text
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}

在文档测试时使用的 Snapshot 中,mempalace_drawers 包含 473 行数据,mempalace_closets 包含 74 条内部导航记录。closet 与 drawer 的数量无需一致。drawer 元数据显示,analyzer 中有 212 个 drawer,filter 中有 156 个,tokenizer 中有 105 个。

此检查会在新进程中运行,并重新打开 CLI 创建的数据库,因此也能确认数据可跨命令持久保存。

可选:使用 Milvus server 或 Zilliz Cloud

对于共享部署,请先设置 Milvus 连接环境变量,再运行相同的 MemPalace CLI 命令。如果不设置这些变量,则使用上文所示的本地 Milvus Lite 数据库。

对于 Milvus server:

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

对于 Zilliz Cloud:

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

本教程中的端到端命令已使用 Milvus Lite 完成验证。上述 server 和 cloud 设置均为可选部署配置,本地验证无需使用这些设置。

Conclusion

MemPalace 为 Agent 提供了一种结构化保存项目知识的方式:wing 用于隔离语料库,room 提供主题级范围,drawer 则保留原始文本。在本例中,31 个密切相关的 Milvus 文档页面被转换为数百个可检索的 drawer,而不是少量手工编写的记录。Milvus 为这一结构提供持久化的向量、稀疏向量、文本和元数据存储。