MemPalace:本地优先的 AI 记忆系统,96.6% R@5 背后的设计逻辑
posts posts 2026-05-21T12:37:56+08:00MemPalace 把对话原文一字不改存进本地向量库,用语义搜索代替 LLM 抽取,LongMemEval 检索召回 96.6% R@5 全程零 API 调用。本文对照 v3.10.0 解析宫殿式四级索引、时序知识图谱、四层记忆栈与 45 个 MCP 工具,并复盘项目两次公开自我纠错的过程。技术笔记AI Memory, Local-First, MCP, Claude CodeMemPalace:本地优先的 AI 记忆系统,96.6% R@5 背后的设计逻辑
主流 AI 记忆系统的做法是先让 LLM 读对话,抽出"值得记的"再存——按 MemPalace 基准文档的归纳,Mem0 用 LLM 抽事实,Mastra 用 GPT-5-mini 观察会话,Supermemory 跑 agentic 搜索。MemPalace 站在对面:原文一字不改全存进本地向量库,检索时用语义搜索召回。它在 LongMemEval 上拿到 96.6% R@5,全程没有 LLM 参与,也不需要任何 API key。
这个立场有一个不太舒服的推论:抽取式记忆在抽取那一刻就开始丢信息。LLM 抽出"用户偏好 PostgreSQL",丢掉的是为什么换、考虑过哪些备选、讨论过哪些取舍——等哪天需要这些上下文,记忆库里已经没有了。MemPalace 的基准文档把这归结为一句话:这个领域把记忆抽取这一步过度工程化了,“原始文本加好嵌入是很强的基线,只是没人认真量过”。
本文基于 2026-10-01 的仓库读数与 v3.10.0 版本写作。
项目坐标
| 项 | 值 |
|---|---|
| 仓库 | MemPalace/mempalace(默认分支 develop) |
| 协议 / 语言 | MIT / Python(另含 Rust 原生检索引擎) |
| 创建 / 最新版 | 2026-04-05 / v3.10.0(2026-09-16,PyPI 当前版) |
| 读数 | 59,372 star · 7,563 fork(2026-10-01 API) |
| 官网 | mempalaceofficial.com(唯一官方文档站) |
系统地图:一座组织好的宫殿
MemPalace 用记忆宫殿的隐喻组织数据,索引共四级,另有三类横向连接:
| 结构 | 角色 |
|---|---|
| wing | 顶层容器:一个人、一个项目或一个话题 |
| room | wing 内的具体话题,init 时从目录结构自动检测(如 auth-migration、ci-pipeline) |
| closet | 摘要层:指回原文的紧凑笔记;当前实现的主存储仍是 drawer 文本加元数据 |
| drawer | 原文文本块:对话、文件、工具调用的原始内容,搜索和基准测试的主检索层 |
wing 内部用五种 hall 类别标注记忆的性质——hall_facts(决策)、hall_events(会话与里程碑)、hall_discoveries(发现)、hall_preferences(偏好)、hall_advice(建议)。跨 wing 用 tunnel 桥接:同名 room 出现在多个 wing 时(比如三个人都聊过 auth-migration),图遍历可以沿着共享话题跨翼走。hallway 则维护一张实体关联图。
这套结构的官方定位说得很克制:wing 和 room 在查询时就是元数据过滤器,概念文档原话是"这是底层向量库的标准元数据过滤,不是什么新颖检索机制"。它的价值在操作性——人和 agent 都能可预测地应用清晰的作用域规则——而不在检索魔法。这个口径来自一次纠错,后面细说。
查询侧是四层记忆栈,按需加载:
| 层 | 内容 | 体量 | 何时加载 |
|---|---|---|---|
| L0 | 身份(~/.mempalace/identity.txt 里的自我概念) | ~50-100 tokens | 总是 |
| L1 | 核心故事(重要性最高的时刻) | ~500-800 tokens | 总是 |
| L2 | 房间召回(按 wing/room 过滤) | 每次 ~200-500 tokens | 话题出现时 |
| L3 | 全库语义搜索 | 不定 | 显式提问时 |
L1 的生成规则是明确的:取最近归档的 2,000 个 drawer 作候选窗口,按重要性和情绪权重评分(平局按归档时间),取前 15 个时刻按 room 分组,截断在 3,200 字符以内。mempalace wake-up 输出的 L0+L1 上下文约 600-900 tokens——新会话的开场成本可控,替代的是"把历史全塞进 prompt"。
原文存储与可插拔检索
存储默认 ChromaDB,零配置即用。检索层按 RFC 001 定义了正式的后端契约(mempalace/backends/base.py):BaseCollection 与 BaseBackend 接口、类型化的查询结果、跨后端统一的错误类。“记忆怎么组织"和"记忆怎么存"就此分开。当前随库发布的后端:
| 后端 | 模式 | 安装 |
|---|---|---|
chroma(默认) | 本地嵌入 | 内置 |
sqlite_exact | 本地精确检索(NumPy) | 内置 |
rust_exact | 本地原生向量(Rust) | wheel / 编译 |
milvus | 本地 Lite,服务端可选 | mempalace[milvus] |
qdrant | 服务端(REST) | 内置 |
pgvector | 服务端(Postgres) | mempalace[pgvector] |
用 --backend、MEMPALACE_BACKEND 或 config.json 切换。rust_exact 和独立分发的 mempalace-native CLI 直接扫 sqlite_exact 的同一个数据库文件,零迁移;此模式官方未发布基准数字,只提供了在自己数据上测量的 bench 命令。
嵌入模型两档:all-MiniLM-L6-v2(384 维,英文训练,约 30 MB)与 embeddinggemma-300m(100+ 语言,约 300 MB,onboarding 引导时推荐)。也可以把嵌入计算交给任意 OpenAI 兼容的 /v1/embeddings 端点——LM Studio、llama.cpp、vLLM、Ollama 都行,端点在本机或局域网内时内容不出网络;切换嵌入空间后需要 mempalace repair rebuild-index 重建索引。
时序知识图谱:给事实加有效期
向量搜索有个天然盲区:时效。“团队换了鉴权方案"之后,向量库里过去说的话不会自动失效。MemPalace 内置一张时序实体关系图来补这个维度——本地 SQLite 存储(概念文档自比"像 Zep 的 Graphiti,但用 SQLite 而非 Neo4j”),每条事实是一个带有效期的三元组:
Subject → Predicate → Object [valid_from → valid_to]操作有五类:add_triple 写入、query_entity 查询(支持 as_of 做时间点查询)、invalidate 显式失效、supersede 单值事实变更(一个事务里闭合旧值、开启新值,交接点查询只返回后继)、timeline 输出实体的时间线。失效的事实从"当前状态"里消失,但历史查询仍能找到——系统因此能区分"有过这个决定"和"这个决定现在还作不作数”。
一次 Claude Code 会话如何流过系统
把前面的机制串成一条实际工作流:
- 会话进行中:Save Hook 每收到 15 条人类消息触发一次,PreCompact Hook 在上下文压缩前触发。hook 只负责叫停,实际归档由 AI 完成——它知道自己聊了什么,把该记的内容分进对应的 wing、hall、closet。
- 为什么要装 hook:Claude Code 的会话以 JSONL transcript 存在
~/.claude/projects/下,README 顶部有一条 CAUTION——不接 auto-save hooks,这些会话 30 天就过期。hooks 赶在压缩和过期之前把内容写进 palace。 - 第二天开场:
mempalace wake-up载入 L0+L1,约 600-900 tokens,会话有了身份和前情。 - 聊到相关话题:L2 按 wing/room 过滤召回对应 drawer。
- 显式提问:L3 全库语义搜索,返回带相似度分数的 top-5。
- 要更细粒度:
mempalace sweep <transcript-dir>对 transcript 目录逐条处理,每条 user/assistant 消息各建一个 drawer,幂等且可断点续跑。
hooks 目前覆盖 Claude Code、Codex CLI 和 Cursor IDE 三家;Cursor 版额外加会话开始时的召回和压缩前的 transcript 快照。
MCP 与多 agent 协作
MemPalace 暴露 45 个 MCP(Model Context Protocol,模型上下文协议)工具(v3.10.0 口径;develop 分支刚加到 47,尚未发布),覆盖 palace 读写、知识图谱操作、跨 wing 导航、drawer 管理、agent 日记,以及 agent 协作(logstream 事件 + artifact 交接)。接上 MCP 后,模型按需查询记忆,而不是把所有历史拼进 system prompt;每个 specialist agent 在 palace 里有自己的 wing 和日记,运行时用 mempalace_list_agents 发现,系统提示词里不用常驻一堆 agent 描述。
v3.9.0 的 hub 模式把这套东西推向 agent 舰队:一台主机 mempalace serve 拥有 palace,本地或远程的 agent 都通过 MCP 读写同一份记忆。hub 分两层——Memory(drawer、知识图谱、日记,持久知识,走语义搜索)和 Logstream(事件、artifact,agent 之间流动的活跃工作,走结构化过滤和长轮询)。仓库给的经验法则:另一个 agent 要对它采取行动的,是 event;未来会话应该知道它的,是 drawer。
Benchmark 解读:测了什么,不能推出什么
先说测什么。LongMemEval 是 500 题的长对话记忆基准,按仓库 benchmark 文档的描述,考的是"能不能从 53 个会话里找到那条被埋着的事实"——基础检索质量,大海捞针。指标是 R@5:标注的正确会话有没有落进前 5 个召回候选。
README 当前报的公开数字(全部可从仓库复现,逐题结果文件随库提交):
| 配置 | R@5 | LLM |
|---|---|---|
| Raw(纯语义搜索,无启发式,无 LLM) | 96.6% | 无 |
| Hybrid v4,held-out 450 题(50 题 dev 调参,未参与训练) | 98.4% | 无 |
| Hybrid v4 + LLM rerank(全 500 题) | ≥99% | 任一能力足够的模型 |
96.6% 是头牌数字:无 API key、无云、任何阶段无 LLM,独立复现过不止一次(2026 年 4 月,@gizmax 在 M2 Ultra 上 5 分钟内复现;维护者随后在 Linux x86_64 上对 v3.3.0 tag 复现)。hybrid 管线在其上加关键词加权、时间邻近加权和偏好模式抽取。注意 96.6% 不是"上限"——rerank 之后还能到 ≥99%——它是"不加任何技巧的基线水平"。
rerank 的完整故事比数字本身有意思。精确的 100%(Haiku 或 Sonnet 做 reranker,500/500)存在且有结果文件,但 README 只给 ≥99%:从 99.4% 到 100% 的最后一步是盯着 3 个具体错误答案调出来的,BENCHMARKS.md 从 2 月起就自曝这叫 teaching to the test,所以 100% 只留在方法论文档里,不上公开页面。模型无关的复现是 minimax-m2.7(经 Ollama Cloud):99.2% R@5 / 100% R@10。
从这些数字不能推出什么:
- R@5 不等于答对率。 检索召回和端到端 QA 准确率是不同指标——仓库自己举的例子:一个系统可以 100% 检索召回、40% QA 准确率。98.4% 再高,也不说明回答正确。
- 竞品数字不可直接比。 Mem0 不发布 LongMemEval 成绩(其公开指标是 LoCoMo QA 准确率约 66.9%);Mastra 的 94.87% 是 GPT-5-mini 的 QA 准确率;Supermemory ASMR 的约 99% 是多 agent 集成的 QA 准确率,作者自己标注为实验性验证。
- 其他基准要按各自口径看。 LoCoMo R@10 从 60.3%(session top-10,无 rerank)到 88.9%(hybrid v5);ConvoMem 平均召回 92.9%;MemBench(ACL 2025,8,500 条)R@5 80.3%。
两次公开纠错:这个项目的可信度从哪来
MemPalace 2026-04-05 建仓,上线几小时内社区就在 README 里挑出一串问题。4 月 7 日两位维护者发声明逐条认账:AAAK 缩写模式的"30x 无损压缩"言过其实——它是有损缩写系统,实测 84.2% R@5,比 raw 的 96.6% 低 12.4 个点(现在文档标注实验性、非默认存储格式);"+34% palace boost"是把未过滤搜索和 wing+room 元数据过滤做对比——元数据过滤是向量库标准功能,不是护城河,该数字撤回;“矛盾检测"当时并未接入图谱操作(fact_checker.py 是独立工具);“100% with Haiku rerank"有结果文件,但管线不在公开基准脚本里。
4 月 14 日,社区审计(issue #875)把问题再推一层:旧对比表把自家的检索召回和竞品的 QA 准确率放进同一列,是类别错误;两个竞品数字(Mem0 约 85%、Zep 约 85%)查无出处。修复动作包括:96.6% raw 定为全渠道头牌数字;混用指标的对比表从 README 和官网移除(方法论文档里留了历史版本并加了警示);撤回过的 “+34%” 在四个页面里的残留一并清除。
今天 README 里那些看起来像姿态的做法——拒绝对比表、主推 held-out 数字、把 100% 藏进方法论文档——都是这两次纠错的沉淀。评估这个项目时,比 star 数更值得看的是 docs/HISTORY.md:一个把撤回记录写进版本库的项目,和一个只留漂亮数字的项目,是两种风险。
顺带一个实用警告:README 顶部的 CAUTION 写明,官方渠道只有 GitHub 仓库、PyPI 包和 mempalaceofficial.com 三处;其他域名(最常被报告的是 mempalace.tech)是冒充站点,2026 年 4 月曾有多个假站分发恶意软件(HISTORY.md 2026-04-11 记录)。
安装与核心命令
三种进入方式。让 coding agent 代装——先装仓库里的三个 skills(mempalace 引导安装与操作、mempalace-recall 答前先搜、mempalace-task logstream 任务委派),由 agent 完成系统配置并验证连接:
npx skills add MemPalace/mempalace直接装 CLI(推荐 uv,隔离环境避开 PEP 668 限制,也免得 chromadb、numpy 这些依赖污染全局 site-packages):
uv tool install mempalace
mempalace init ~/projects/myapp或者用 Docker(多架构镜像,Apple Silicon 原生跑;palace、配置、嵌入模型全在 /data 卷里):
docker pull ghcr.io/mempalace/mempalace:latest日常高频命令:
mempalace mine ~/projects/myapp # 挖掘项目文件
mempalace mine ~/.claude/projects/ --mode convos # 挖掘 Claude Code 会话(--wing 按项目分翼)
mempalace search "why did we switch to GraphQL" # 语义搜索
mempalace wake-up # 输出 L0+L1 唤醒上下文
mempalace audit # 给 palace 的组织程度打分(只读)挖掘不写源目录,Docker 场景把要挖的目录挂载只读即可。Android/Termux 没有原生支持(ChromaDB、ONNX Runtime 不发布 Android wheel),官方给的是 Debian PRoot 容器方案。
采用建议
顺序上,已经在用 Claude Code 的个人开发者最先受益:装 CLI、接好 hooks、用 mine --mode convos 回填既有 transcript。这一步解决的是"会话 30 天过期"的现实损失,跟基准分数无关。多机多 agent 的团队第二步上 hub 模式,把记忆和任务流收拢到一处。做研究或评测的可以直接跑 benchmarks/ 里的复现脚本,逐题结果都随库提交。
边界同样清楚。MemPalace 不管答案质量,检索召回高不等于回答对;抽取式记忆省存储、摘要直接可读,这些好处它都放弃了——原文全存的代价是存储体积,还有"召回靠搜索而不是靠提炼”。SQLite 图谱和单机 palace 在更大规模下的表现,仓库没有公开数字。仓库简介自称 “The best-benchmarked open-source AI memory system”——这是项目自述,横向对比连他们自己都拒绝做,把它当口号读比当结论读更合适。
96.6% 的价值不在名次。它量出了一个容易被忽略的东西:在设计抽取管线之前,先测一测"什么都不抽、全存原文"的基线——它可能比直觉高得多。
参考资料
- 仓库:MemPalace/mempalace(README、benchmarks/BENCHMARKS.md、docs/HISTORY.md)
- 概念文档源文件(官网 mempalaceofficial.com 同内容,访问请认准此唯一官方域名):the-palace.md、knowledge-graph.md、memory-stack.md
- 官方渠道核验:GitHub 仓库 · PyPI · mempalaceofficial.com(其余域名均为冒充站点)
参与讨论
使用 GitHub 登录。欢迎补充事实、异议与实践。
讨论暂时无法加载。