【MemPalace】本地优先 AI 记忆系统:宫殿式存储架构与混合检索原理深度解析
【MemPalace】本地优先 AI 记忆系统:宫殿式存储架构与混合检索原理深度解析
引子:当 AI 遗忘成为瓶颈
大模型(LLM)的上下文窗口越来越大,从 4K token 扩展到 200K、1M——但现实是,任何有意义的长期项目,记忆量都远超上下文容量。当 AI Agent 需要跨月甚至跨年记住”我们为什么把数据库从 PostgreSQL 换成了 MongoDB”、”张三维这个项目成员负责哪块”,靠提示词工程已经难以为继。
市面上的 AI 记忆方案,要么是付费云服务(Zep $25/月、Memories),要么是总结式的信息丢失方案(Mem0 的语义摘要),要么是依赖 API Key 的闭源系统。
MemPalace 试图解决一个核心问题:在完全本地、零 API 依赖的前提下,如何构建一个高精度、可检索、层次化的 AI 记忆系统?
一、项目定位与核心价值
MemPalace 是一个本地优先(Local-First)的 AI 记忆系统,定位介于”向量数据库”和”知识图谱”之间。
它解决了什么问题?
| 痛点 | MemPalace 的答案 |
|---|---|
| 云服务有隐私风险 | 数据完全本地,不上传任何内容 |
| 总结式记忆丢失细节 | 逐字存储(verbatim),不摘要、不改写 |
| 记忆碎片化、无法关联 | 宫殿分层结构(Wing → Room → Drawer)+ 知识图谱 |
| 语义检索精度不足 | 混合检索(向量 + BM25)+ LLM 重排(可选) |
| API Key 依赖 | 核心路径零 LLM 调用,R@5 达 96.6% |
关键数据
- LongMemEval benchmark:R@5 = 96.6%(纯语义搜索,无 LLM、无 API Key)
- LoCoMo benchmark(对话记忆):R@10 = 88.9%(hybrid v5)
- 2026-04-05 创建,仅 20 天获得 49K GitHub Stars
- 支持 Claude Code、Gemini CLI、OpenClaw、任何 MCP 兼容工具
二、核心概念:宫殿式记忆结构
MemPalace 引入了一套源自”记忆宫殿”(Method of Loci)的隐喻体系,将数字记忆映射为物理空间的层次结构:
graph TB
subgraph Palace["🏛️ MemPalace 记忆宫殿"]
subgraph Wing1["🌿 Wing(项目/领域)"]
subgraph Room1["🚪 Room(主题)"]
D1["📦 Drawer 1<br/>800 chars 原文片段"]
D2["📦 Drawer 2<br/>800 chars 原文片段"]
D3["📦 Drawer N..."]
end
subgraph Room2["🚪 Room(另一个主题)"]
D4["📦 Drawer"]
D5["📦 Drawer"]
end
end
subgraph Wing2["🌿 Wing(另一个项目)"]
R3["🚪 Room"]
end
subgraph Layer0["📌 Layer 0: Identity"]
ID["身份层<br/>~100 tokens<br/>Who am I?"]
end
subgraph Layer1["📌 Layer 1: Essential Story"]
ES["精华故事层<br/>~500-800 tokens<br/>最高权重记忆"]
end
end
subgraph External["🔌 外部系统"]
MCP["MCP Server<br/>Claude Code / Gemini CLI"]
CLI["CLI 工具<br/>mempalace search/mine"]
KG["Knowledge Graph<br/>时间性实体关系图<br/>SQLite"]
endDrawer(抽屉)—— 最底层存储单元
每个文件或对话历史被切分为 800 字符的原文片段(Drawer),逐字存储,不做任何摘要或改写。这意味着检索回来的内容是原始的、完整的、可引用的事实本身,而非经过二次加工的”记忆”。
Drawer 的元数据包含:
source_file:来源文件路径room:所属房间wing:所属 wingimportance:重要性权重timestamp:归档时间
Closet(衣柜)—— 索引加速层
Closet 是一个小型摘要文档(每个 ~1500 chars),通过正则表达式从原始 Drawer 中提取主题词 + 实体 + 指向原始 Drawer 的指针(→drawer_id)。
1 | topic:数据库迁移, mongodb | entities:张三, 李四 | →drawer_001, drawer_002 |
这种设计让向量检索不必每次都扫描所有 Drawer——Closet 先预过滤一遍,Closet 命中的时候才去找对应的 Drawer。同时 Closet 也作为 BM25 关键词检索的载体。
Wing(侧翼)与 Room(房间)
- Wing:项目或领域的划分(如”博客项目”、”汽车项目”)
- Room:Wing 内部的主题划分(如”数据库迁移”、”API 设计”)
两者都支持通过 mempalace.yaml 配置文件或 AI 自动推断进行路由。
三、四层唤醒架构(Layered Memory Stack)
MemPalace 提出了一个分层唤醒模型,每次启动 AI 对话时不需要加载全部记忆,而是按需逐层加载:
graph LR
A["🤖 AI Session Start"] --> B["L0: Identity<br/>~100 tokens"]
B --> C["L1: Essential Story<br/>~500-800 tokens"]
C --> D["L2: On-Demand<br/>按 wing/room 加载<br/>~200-500 tokens/个"]
D --> E["L3: Deep Search<br/>全量 ChromaDB 检索<br/>无上限"]
E --> F["✅ 上下文准备完毕"]
style A fill:#f9d71c,color:#000
style F fill:#57d652,color:#000
style B fill:#ffb3ff,color:#000
style C fill:#b3d9ff,color:#000
style D fill:#b3ffb3,color:#000
style E fill:#ffd9b3,color:#000Layer 0 — Identity(身份层)
- Token 预算:~100 tokens
- 内容:
~/.mempalace/identity.txt纯文本文件,由用户手动编写 - 示例:
1
2
3
4
5## L0 — IDENTITY
我是 Atlas,一个帮助 Alice 工作的个人 AI 助手。
特点:温暖、直接、记住所有细节。
人物:Alice(创造者)、Bob(Alice 的伴侣)。
项目:正在开发一个帮助人们处理情绪的日记应用。 - 特点:始终加载,永不遗忘
Layer 1 — Essential Story(精华故事层)
- Token 预算:~500-800 tokens
- 生成方式:自动从 palace 中提取最重要 + 最新的 15 个 Drawer,按 room 分组
- 打分逻辑:每个 Drawer 有
importance权重字段,优先选取高权重 + 最近归档的内容 - 特点:每次对话开始时自动生成,提供”故事主线”
Layer 2 — On-Demand(按需加载)
- 加载条件:当对话涉及特定 wing 或 room 时触发
- 来源:从 ChromaDB 中检索对应 wing/room 的 Drawer
- 预算:~200-500 tokens/个,精确可控
Layer 3 — Deep Search(深度搜索)
- 触发条件:L0+L1+L2 无法回答时,AI 主动调用搜索
- 范围:全量 ChromaDB 向量检索 + 全文 BM25
- 无上限:可遍历整个 palace
唤醒成本
L0 + L1 总计 ~600-900 tokens,释放 95%+ 的上下文空间,同时保留完整记忆访问能力。
四、混合检索架构(Hybrid Search)
MemPalace 的检索层是整个系统最核心的技术创新,结合了语义向量检索与 BM25 关键词检索,再通过可选的 LLM 重排层提升精度。
4.1 架构图
sequenceDiagram
participant User as 用户查询
participant Vec as 向量检索<br/>ChromaDB
participant BM25 as BM25 检索<br/>Drawer 层
participant Closet as Closet 层<br/>预过滤
participant Hybrid as 混合评分<br/>融合层
participant Rerank as LLM 重排<br/>(可选)
User->>Vec: 语义查询
Vec-->>Hybrid: Top-K 向量相似结果
User->>Closet: 关键词预过滤
Closet->>BM25: 缩小范围
BM25-->>Hybrid: BM25 命中的 Drawer
Hybrid->>Hybrid: vector_weight × vector_sim<br/>+ bm25_weight × bm25_score
Hybrid-->>User: 混合排序结果
alt 开启 LLM 重排
Hybrid->>Rerank: Top-20 候选
Rerank-->>User: LLM 评估后 Top-5
end4.2 向量检索(Semantic Search)
默认使用 ChromaDB 作为向量数据库,嵌入模型本地运行(~300MB),无需 API Key。
1 | # 实际调用示例(来自 mempalace/searcher.py) |
4.3 BM25 关键词检索
BM25(Okapi BM25)是 Lucene/Elasticsearch 使用的经典关键词排序算法,对精确术语匹配比向量检索更可靠:
1 | # 来自 searcher.py 的 BM25 实现 |
4.4 混合评分融合
1 | def _hybrid_rank(results, query, vector_weight=0.6, bm25_weight=0.4): |
4.5 可选 LLM 重排
使用任意 LLM(测试过 Claude Haiku、Claude Sonnet、minimax-m2.7)作为重排阅读器:
1 | # 将 Top-20 候选 + 问题发给 LLM,让它判断哪个最相关 |
4.6 Benchmark 结果
| Benchmark | Metric | Score | Notes |
|---|---|---|---|
| LongMemEval R@5(纯语义,无 LLM) | R@5 | 96.6% | 无 API Key,无 LLM 调用 |
| LongMemEval Hybrid v5(held-out) | R@5 | 98.4% | 在 50 题上 tune,450 题 held-out |
| LongMemEval + LLM 重排 | R@5 | ≥99% | 任意 capable LLM |
| LoCoMo R@10(hybrid v5) | R@10 | 88.9% | 1,986 真实问题 |
| ConvoMem(平均 recall) | Avg recall | 92.9% | 5 类 × 50 题 |
| MemBench(ACL 2025) | R@5 | 80.3% | 8,500 条目标 |
五、知识图谱:时间性实体关系
MemPalace 不只是向量检索,还包含一个基于 SQLite 的时序知识图谱:
graph TB
subgraph KG["🗄️ Knowledge Graph (SQLite)"]
E1["👤 Entity: 张三<br/>type: person"]
E2["💻 Entity: 博客项目<br/>type: project"]
E3["🛠️ Entity: 数据库迁移<br/>type: task"]
E1 -.->|"works_on"| E2
E1 -.->|"does"| E3
E3 -.->|"valid_from: 2025-01"| T1["时间窗口"]
E3 -.->|"valid_to: 2025-03"| T1
end
subgraph Storage["📦 Drawer / Closet"]
D1["Drawer: 张三讨论了迁移计划..."]
D1 -.->|"source_drawer_id"| E1
end核心 API
1 | from mempalace.knowledge_graph import KnowledgeGraph |
SQLite Schema
1 | CREATE TABLE entities ( |
六、MCP Server:无缝集成 AI 工具
MemPalace 提供了一个 MCP(Model Context Protocol)服务器,将记忆访问封装为标准 MCP 工具:
1 | # 安装(Claude Code 示例) |
可用 MCP 工具(29 个)
读取类:
mempalace_status— 记忆统计(抽屉总数、wing/room 分布)mempalace_search— 语义搜索,支持 wing/room 过滤mempalace_list_wings— 列出所有 wingmempalace_get_taxonomy— 完整树状结构
写入类:
mempalace_add_drawer— 添加记忆抽屉mempalace_delete_drawer— 删除记忆
维护类:
mempalace_reconnect— 强制刷新缓存
Claude Code 自动保存 Hook
1 | # 在 ~/.claude/settings.local.json 中配置 |
该 Hook 的工作流程:
sequenceDiagram
participant CC as Claude Code
participant Hook as Save Hook
participant MP as MemPalace
CC->>CC: AI 生成回复
CC->>Hook: Stop 触发(每次回复后)
Hook->>Hook: 计数:距离上次保存过了 N 条消息?
alt ≥ SAVE_INTERVAL(默认 15 条)
Hook->>CC: 阻塞,发送"保存指令"
CC->>CC: AI 主动保存记忆到 MemPalace
CC->>CC: 再次触发 Stop
Hook->>Hook: stop_hook_active=true,检测到已在保存中
Hook->>CC: 放行(不阻塞)
else < SAVE_INTERVAL
Hook->>CC: 直接放行
end七、完整使用示例
7.1 安装
1 | pip install mempalace |
7.2 导入对话历史(Claude Code sessions)
1 | mempalace mine ~/.claude/projects/ --mode convos --wing 博客项目 |
7.3 导入项目文件
1 | mempalace mine ~/projects/blog --wing 博客项目 --room 架构设计 |
7.4 搜索记忆
1 | $ mempalace search "为什么从 PostgreSQL 切换 MongoDB" |
7.5 启动对话时唤醒记忆
1 | mempalace wake-up |
7.6 Python API
1 | from mempalace import Palace |
八、与同类项目对比
| 维度 | MemPalace | Mem0 | Letta | Zep |
|---|---|---|---|---|
| 存储方式 | 逐字原文 | 语义摘要 | 摘要 + 向量 | 摘要 + 向量 |
| 本地优先 | ✅ 完全本地 | ❌ 云服务 | ❌ 云服务 | ❌ 云服务 ($25/月) |
| 零 API Key | ✅ 核心路径零依赖 | ❌ 需要 | ❌ 需要 | ❌ 需要 |
| 知识图谱 | ✅ SQLite 时序图谱 | ❌ | ✅ Neo4j | ✅ 时序图谱 |
| MCP 支持 | ✅ 29 工具 | ✅ | ✅ | ✅ |
| 检索架构 | 向量+BM25+LLM重排 | 语义向量 | 语义向量 | 语义 + 关键词 |
| LongMemEval R@5 | 96.6% | 未公开 | 未公开 | 未公开 |
| 分层唤醒 | ✅ L0/L1/L2/L3 | ❌ | ❌ | ❌ |
| Benchmark 可复现 | ✅ 公开脚本 | ❌ | ❌ | ❌ |
核心设计差异
1. 逐字 vs 摘要
MemPalace 坚持”不摘要”原则——记忆以原始文本存储,检索返回的是真实发生过的事情,而非被模型”润色”过的二手记忆。这对需要精确引用的场景(代码决策、法律文档、技术调研)至关重要。
Mem0/Letta/Zep 的摘要方案优点是节省 token,但每次摘要都丢失信息,且无法精确回溯原文。
2. 混合检索 vs 纯向量
纯向量检索对”语义相似但用词不同”的查询效果好,但对精确术语(如函数名、版本号、人名)效果差。BM25 弥补了这一缺陷,两者结合的混合检索在 R@5 上比纯向量高 1.8 个百分点(98.4% vs 96.6%)。
3. SQLite 知识图谱 vs Neo4j
Letta 和 Zep 使用 Neo4j 作为知识图谱后端(需要额外安装和配置),而 MemPalace 用 SQLite——Python 内置,无需任何依赖。SQLite 的 WAL 模式也支持高并发写入。
4. 分层唤醒 vs 全量加载
大多数记忆系统每次都加载全量记忆(受限于上下文长度),而 MemPalace 的分层唤醒机制让 AI 每次只花 600-900 tokens 就获得”故事主线”,按需扩展到全量检索。
九、优缺点总结
✅ 优点
| 维度 | 说明 |
|---|---|
| 隐私完全本地 | 数据不离开本地机器,无云依赖 |
| 零 API Key | 核心检索路径完全离线可用 |
| 逐字存储 | 保留原始信息,支持精确引用 |
| 高精度检索 | 混合检索 R@5=96.6%,可复现 benchmark |
| 架构清晰 | 4 层唤醒 + Wing/Room/Drawer 层次分明 |
| 可插拔后端 | 基于 RFC 001 接口规范,可替换 ChromaDB |
| 知识图谱 | 时序三元组,SQLite 实现,零依赖 |
| MCP 生态 | 29 个 MCP 工具,深度集成 Claude Code |
| Benchmark 透明 | 所有结果可本地复现,方法论公开 |
❌ 缺点
| 维度 | 说明 |
|---|---|
| 单用户设计 | Palace 以目录为单位,不支持多租户/多用户共享 |
| ChromaDB 依赖 | 默认后端是 ChromaDB,其 HNSW 实现有已知的崩溃问题(项目中已有 quarantine 逻辑作为 workaround) |
| 无内置 LLM 重排 | 99% 的精度需要额外调用 LLM API |
| Drawer 粒度固定 | 800 char 固定切分,对极短或极长的记忆可能不够灵活 |
| 身份层需手动维护 | Layer 0 的 identity.txt 需要用户手动更新,暂无自动化方案 |
十、架构亮点:RFC 001 后端接口规范
MemPalace 最有前瞻性的设计之一是后端接口规范(RFC 001):
1 | # mempalace/backends/base.py — 所有存储后端必须实现的接口 |
当前唯一实现是 ChromaBackend,但理论上可以替换为 Qdrant、Milvus、Faiss 或任何兼容接口。这为未来性能优化和多后端支持留下了空间。
项目还通过 project.entry-points."mempalace.backends" 暴露插件注册机制,第三方可以发布自己的后端包(如 pip install mempalace-backend-qdrant)。
十一、总结与趋势
MemPalace 代表了 AI 记忆系统的一个新方向:完全本地、零摘要、层次化、高精度检索。它不试图成为”更智能的记忆”,而是成为”更忠实的记忆”——逐字保留原始内容,让 AI 在需要时精确回溯。
几个值得关注的趋势:
- Local-First AI 基础设施:随着隐私法规收紧和本地模型能力提升,完全本地化的 AI 工具链(Ollama + MemPalace + OpenWebUI)正在从极客圈向主流渗透
- 可复现 Benchmark 的重要性:MemPalace 公开所有 benchmark 脚本和数据,让用户自己跑,这比”宣称 99% 精度”更有说服力
- MCP 生态扩展:MCP 作为 AI Agent 的”USB 接口”标准正在被广泛采纳,MemPalace 的 29 个 MCP 工具覆盖了大部分使用场景
项目信息:
- GitHub:MemPalace/mempalace
- Stars:49,261(2026-04-24)
- License:MIT
- Python:3.9+
- 依赖:
chromadb>=1.5.4,<2,pyyaml>=6.0,<7
本文基于 MemPalace v3.3.2 源码分析编写,所有代码示例均来自项目实际代码,非伪代码。