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 依赖项。该命令特意不固定版本,因此全新安装时会解析并安装最新可用版本。
uv tool install "mempalace[milvus]"
你还需要安装 Git,以便下载文档语料库。
本教程使用 MemPalace 的本地 MiniLM Embedding 模型,因此不需要外部模型 API key。首次运行挖掘或搜索命令时,可能会下载一个小型 ONNX Embedding 模型。
Configure the workspace
创建一个 workspace,并为文档和 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"
在下面的 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 文档目录:
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 指南和三组密切相关的页面:
milvus-analyzer-docs/
├── analyzer/ # Built-in language analyzers
├── filter/ # Token filters
├── tokenizer/ # Tokenizers
└── *.md # Analyzer overviews and selection guides
确认源页面的数量:
find "$PROJECT_DIR" -type f -name "*.md" | wc -l
参考输出:
31
随着 Milvus 文档分支的更新,确切数量可能会发生变化。
定义 MemPalace 房间
MemPalace 可以在执行 mempalace init 时检测房间,但其初始化流程还会对整个项目执行启发式 Entity 分类,并将接受的结果写入 Entity 注册表。定义本文档语料库不需要此分类步骤,因此我们直接提供精简的分类体系。在挖掘过程中,MemPalace 仍可能附加确定性的启发式 Entity 元数据并构建内部走廊链接;这些关联不会决定文件被分配到哪个房间,也不会改变下文基于房间范围的检索。
创建 $PROJECT_DIR/mempalace.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,以及 wing、room、source_file、chunk_index 和源文件行号等元数据。room 和 drawer 在 MemPalace 的 Milvus Collection 中仍属于逻辑元数据;MemPalace 不会为每个 room 分别创建一个 Milvus Collection。
Mine the documentation into Milvus
使用 Milvus 后端挖掘项目:
mempalace \
--palace "$PALACE_DIR" \
mine "$PROJECT_DIR" \
--backend milvus
以下是基于已验证文档快照的参考输出:
=======================================================
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 数量:
mempalace --palace "$PALACE_DIR" status --backend milvus
参考输出:
=======================================================
MemPalace Status -- 473 drawers
=======================================================
WING: milvus_analyzer_docs
ROOM: analyzer 212 drawers
ROOM: filter 156 drawers
ROOM: tokenizer 105 drawers
=======================================================
当上游文档发生变化时,确切的 drawer 数量也可能变化,因为较长的页面会生成更多分块。
Semantic search
使用 mempalace search 按语义检索文档。以下问题并未指定具体文件,也未明确提及某个 Analyzer 功能:
mempalace \
--palace "$PALACE_DIR" \
search "How should I analyze documents that mix several languages?" \
--backend milvus \
--wing milvus_analyzer_docs \
--results 3
参考输出(分数可能有所不同):
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 中搜索,以找到让等价术语相互匹配的方法:
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
参考输出(分数可能有所不同):
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 搜索模式。
mempalace \
--palace "$PALACE_DIR" \
search "language_identifier tokenizer" \
--backend milvus \
--wing milvus_analyzer_docs \
--room tokenizer \
--results 3
参考输出(分数可能有所不同):
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 数量:
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 相同的可选依赖集运行该脚本:
export MEMPALACE_MILVUS_LITE_PATH="$PALACE_DIR/milvus.db"
uv run --with "mempalace[milvus]" inspect_milvus.py
参考输出:
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:
export MEMPALACE_MILVUS_URI="http://localhost:19530"
export MEMPALACE_MILVUS_DB_NAME="default"
export MEMPALACE_MILVUS_NAMESPACE="team-memory"
对于 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"
本教程中的端到端命令已使用 Milvus Lite 完成验证。上述 server 和 cloud 设置均为可选部署配置,本地验证无需使用这些设置。
Conclusion
MemPalace 为 Agent 提供了一种结构化保存项目知识的方式:wing 用于隔离语料库,room 提供主题级范围,drawer 则保留原始文本。在本例中,31 个密切相关的 Milvus 文档页面被转换为数百个可检索的 drawer,而不是少量手工编写的记录。Milvus 为这一结构提供持久化的向量、稀疏向量、文本和元数据存储。