编程 本地优先的 AI 记忆系统 MemPalace:从零构建语义记忆层,让 AI 记住你的一切

2026-04-24 14:18:14 +0800 CST views 7

本地优先的 AI 记忆系统 MemPalace:从零构建语义记忆层,让 AI 记住你的一切

背景介绍:AI 为何总像失忆的金鱼

用过 Claude Code、Cursor 或 GitHub Copilot 的同学应该都有一个共同的痛点:每次开启新对话,AI 就是一张白纸。你上周在这项目里做过什么技术选型决策、踩过什么坑、为什么放弃 GraphQL 改用 REST——AI 统统不知道,只能靠你反复唠叨。

现有的解决方案有几条路:

  • Mem0:云端记忆系统,效果不错但数据得上传到第三方,隐私敏感项目直接 pass
  • Supermemory:书签式的记忆管理,太偏信息收藏而非代码上下文
  • 手动写 CLAUDE.md:最朴素但最可靠,缺点是完全靠人肉维护

MemPalace 走的是第四条路:本地优先、语义检索、零 API 调用。它的核心设计理念是:不压缩、不摘要,直接原文存储,用向量检索来找到相关内容。听起来简单,但背后的工程实现相当有技术含量——96.6% 的 R@5 召回率(不需要 LLM 参与)已经超过了大多数闭源商业方案。

这篇长文会从架构设计、核心概念、代码实现、实战使用、性能优化等维度,把 MemPalace 拆解透。


一、核心架构:宫殿式记忆的隐喻

MemPalace 的名字来自「记忆宫殿」(Method of Loci)——这是一种古老的记忆术,通过在脑海中构建一个熟悉的空间,把要记住的信息「放」在不同的位置,回忆时按位置走一遍即可。

MemPalace 把这个隐喻搬进了代码世界:

项目 (Palace)
  ├── wing(侧翼)= 按人/项目分的记忆空间
  │     ├── room(房间)= 话题/主题
  │     │     └── drawer(抽屉)= 具体的原始内容
  └── knowledge-graph = 时间线感知的实体关系图

三层嵌套结构解决了两个核心问题:

1. 搜索范围的可控性

传统方案把所有记忆塞进一个向量数据库,检索时是全量搜索。MemPalace 的 wing/room/drawer 结构让你可以按「只查这个项目的记忆」或「只查这个话题的讨论」,避免上下文污染。Claude Code 的集成就是按 project wing 来组织的,每次 mempalace wake-up 只加载当前项目的上下文。

2. 原文保留而非摘要

很多记忆系统会自动摘要压缩内容,代价是丢失细节。MemPalace 直接存原文(verbatim),检索靠向量相似度,召回的是完整原始记忆,交给 LLM 自己判断哪些有用。

架构分层:

┌─────────────────────────────────────────────────────────┐
│                     CLI / MCP Server                     │
│           (mempalace mine / wake-up / search)          │
├─────────────────────────────────────────────────────────┤
│                      Agents Layer                        │
│      (specialist agents, diaries, MCP tool access)       │
├─────────────────────────────────────────────────────────┤
│                   Knowledge Graph                        │
│         (SQLite-backed temporal entity graph)            │
├─────────────────────────────────────────────────────────┤
│                   Retrieval Engine                       │
│   ┌─────────────┐   ┌─────────────┐   ┌──────────────┐  │
│   │  ChromaDB   │   │  Temporal   │   │  Preference  │  │
│   │ (semantic)  │   │  Boosting   │   │  Patterns    │  │
│   └─────────────┘   └─────────────┘   └──────────────┘  │
├─────────────────────────────────────────────────────────┤
│                   Storage Layer                          │
│   ┌─────────────┐   ┌─────────────┐                     │
│   │  Drawers    │   │   Wings     │                     │
│   │ (raw text)  │   │  (metadata)  │                     │
│   └─────────────┘   └─────────────┘                     │
└─────────────────────────────────────────────────────────┘

二、核心概念详解

2.1 Palace(宫殿)

一个 Palace 对应一个顶层存储单元,通常是一个机器上的所有记忆集合,或者一个组织的多人记忆共享空间。mempalace init ~/projects/myapp 初始化的就是当前用户视角下的一个 Palace。

Palace 的存储结构:

~/projects/myapp/.mempalace/
  ├── index/
  │   ├── chroma/
  │   └── metadata.json
  ├── drawers/          # 原始记忆文本
  │   ├── d_abc123.txt
  │   └── d_def456.txt
  ├── wings/            # wing 配置
  │   └── wing_project_1.json
  └── knowledge-graph.db  # SQLite 时序图谱

2.2 Wing(侧翼)

Wing 是记忆的第一级分区。最典型的用法是「按项目」或「按人」分 wing。

# mine 时指定 wing
mempalace mine ~/projects/myapp --wing myproject

# mine Claude Code 会话时按项目自动分 wing
mempalace mine ~/.claude/projects/ --mode convos --wing per-project

Wing 的 metadata 里存储了创建时间、最近访问时间、标签等信息。检索时可以限定 wing:

mempalace search "为什么用 Postgres" --wing myproject

2.3 Room(房间)

Room 是 wing 下的二级组织,对应话题或主题。自动根据内容聚类生成,也支持手动指定。

2.4 Drawer(抽屉)

Drawer 是最小的存储单元,一条原始记忆。可能是:

  • 一段对话记录(Claude Code session 的一个 chunk)
  • 一个项目的 README 或设计文档
  • 一段代码注释
  • 一个决策记录

Drawer 的设计哲学是不可变:存入后不修改,只在知识图谱层维护引用关系。

2.5 Knowledge Graph(知识图谱)

MemPalace 不只是向量检索,还维护了一个 SQLite-backed 的时序实体关系图谱:

# 知识图谱操作示例
from mempalace import KnowledgeGraph

kg = KnowledgeGraph("path/to/knowledge-graph.db")

# 添加实体关系
kg.add_entity("决策", "使用 Postgres 而非 MySQL", timestamp=1700000000)
kg.add_relation("使用 Postgres 而非 MySQL", "原因", "MySQL 8.x 的 JSON 支持不够成熟")
kg.add_relation("使用 Postgres 而非 MySQL", "时间", "2024-01-15 技术评审会")

# 查询时间线
results = kg.query_timeline(entity="Postgres", start=1698000000, end=1710000000)

# 使失效(比如某决策被推翻)
kg.invalidate("使用 Postgres 而非 MySQL", reason="新版本 MySQL 9.0 JSON 性能已追平")

这个图谱的价值在于:向量检索擅长「相似性」,但知识图谱擅长「因果链」。两者结合才能回答「我们为什么在 3 月份做了这个决定」这类时间敏感的推理问题。


三、检索引擎深度解析

这是 MemPalace 最硬核的部分。核心数字:

  • Raw(纯语义检索,无 LLM):R@5 = 96.6%
  • Hybrid v5(加入关键词提升 + 时间近邻 + 偏好模式):R@10 = 88.9%(LoCoMo 数据集)
  • Rerank 管道(+ LLM 重排):≥99%

3.1 Raw 检索管道

用户 query
    ↓
Embedding(本地模型,默认 bge-m3 或类似)
    ↓
向量相似度检索 (ChromaDB, top-K=50)
    ↓
候选重排 → top-5 返回

关键设计点:

1. 零 LLM 调用

纯向量检索,不依赖任何 API key。这是 benchmark 能到 96.6% 的核心——没有中间商(LLM)赚差价,直接拿向量相似度说话。

2. Chunking 策略

对话记忆被切分成合理的 chunk。MemPalace 没有固定 chunk size,而是根据语义边界(消息边界、主题切换)动态切分,避免一句话被切成两半。

3. 混合索引

支持 ChromaDB 作为默认后端,同时也支持 Qdrant、Pinecone 等替代后端。接口定义在 mempalace/backends/base.py

from abc import ABC, abstractmethod

class MemoryBackend(ABC):
    @abstractmethod
    def add(self, texts: list[str], metadata: list[dict]) -> list[str]:
        """添加记忆片段,返回 IDs"""
        pass

    @abstractmethod
    def search(self, query: str, top_k: int = 10, filter_metadata: dict = None) -> list[dict]:
        """语义检索"""
        pass

    @abstractmethod
    def delete(self, ids: list[str]) -> None:
        """删除记忆"""
        pass

    @abstractmethod
    def update(self, id: str, text: str, metadata: dict = None) -> None:
        """更新记忆"""
        pass

换后端只需实现这几个方法,不用动上层代码。

3.2 Hybrid v5 增强

Raw 检索只靠语义相似度,但有些场景语义相似度不够:

  • 查询「上次数据库迁移是什么时候」,时间信息很关键
  • 查询「项目里用到的 Python 库」,关键词「Python」比语义重要
  • 查询「张三关于 API 设计的讨论」,偏好特定人

Hybrid v5 加入了三个增强层:

# 伪代码展示混合检索逻辑
def hybrid_search(query: str, wing: str = None):
    # 1. 语义检索
    semantic_results = vector_index.search(query, top_k=50)

    # 2. 关键词提升
    keyword_matches = keyword_index.search(query)
    for result in semantic_results:
        if result['text'] in keyword_matches:
            result['score'] += BOOST_WEIGHT['keyword']

    # 3. 时间近邻提升(查询涉及的时间窗口内的记忆得分更高)
    temporal_context = extract_temporal_context(query)  # "上周"、"3月份"
    if temporal_context:
        for result in semantic_results:
            time_distance = abs(result['timestamp'] - temporal_context['center'])
            result['score'] += BOOST_WEIGHT['temporal'] / (time_distance + 1)

    # 4. 偏好模式(根据用户历史查询习惯加权)
    preference_pattern = get_user_preference(query)
    for result in semantic_results:
        if matches_preference(result, preference_pattern):
            result['score'] += BOOST_WEIGHT['preference']

    # 排序返回
    return sorted(semantic_results, key=lambda x: x['score'], reverse=True)[:10]

这些增强让 R@10 从 60.3% 提升到 88.9%(LoCoMo 数据集),提升幅度非常显著。

3.3 LLM Rerank(可选层)

如果对召回质量要求极高,可以加一层 LLM 重排:

# rerank 示例
from mempalace.rerank import LLMReranker

reranker = LLMReranker(model="claude-haiku")  # 小模型即可,无需 Sonnet

top_20 = vector_index.search(query, top_k=20)
top_5 = reranker.rerank(query, top_20)
# 返回最相关的 5 条

Reranker 的 prompt 大概是:「给定用户查询,从以下候选记忆中选出最相关的 5 条,解释为什么」,模型输出排序。配合任何 capable 的本地模型(实测 Claude Haiku 就够用),最终召回率可达 ≥99%。


四、Claude Code 集成:真正的上下文连续性

MemPalace 最实用的场景是给 Claude Code 注入记忆。下面看几个核心集成点。

4.1 自动保存钩子(Auto-save Hooks)

MemPalace 提供了两个 Claude Code hooks:

# ~/.claude/hooks/mempalace_save.py
# post-context-compaction hook:上下文压缩前自动保存
# periodic-save hook:定期保存当前会话状态

import subprocess
import sys

def on_context_compaction(context_before: str, context_after: str):
    """上下文被压缩前,把即将丢失的内容存到 MemPalace"""
    # context_before 是压缩前的完整上下文
    # 提取有价值的信息存入 palace
    subprocess.run([
        "mempalace", "add",
        "--content", context_before,
        "--wing", "current-project",
        "--room", "claude-sessions"
    ], check=True)

def on_periodic_save(session_context: str):
    """每 N 分钟自动保存"""
    subprocess.run([
        "mempalace", "add",
        "--content", session_context,
        "--wing", "current-project",
        "--room", "claude-sessions"
    ], check=True)

配置方式是在 Claude Code 的 hooks 配置文件中引用:

// ~/.claude/settings.json
{
  "hooks": {
    "post-context-compaction": "python3 ~/.claude/hooks/mempalace_save.py --event post-context-compaction",
    "periodic-save": "python3 ~/.claude/hooks/mempalace_save.py --event periodic-save"
  }
}

4.2 启动恢复(wake-up)

新会话开始时,用 mempalace wake-up 把相关记忆注入上下文:

# 自动加载当前目录相关记忆
mempalace wake-up

# 指定项目 wing
mempalace wake-up --wing myproject

# 只加载最近 30 天的记忆(避免太旧的上下文)
mempalace wake-up --max-age 30d

wake-up 输出的格式可以直接粘贴到 Claude Code 的输入框,或者通过 MCP 接口自动注入。

4.3 MCP Server

MemPalace 内置了 29 个 MCP 工具,覆盖 palace 的读写、图谱操作、wing 导航、agent diary 等:

{
  "tools": [
    { "name": "mempalace_search", "description": "搜索记忆" },
    { "name": "mempalace_add", "description": "添加记忆" },
    { "name": "mempalace_list_wings", "description": "列出所有 wing" },
    { "name": "mempalace_wake_up", "description": "加载当前上下文相关记忆" },
    { "name": "mempalace_query_graph", "description": "查询知识图谱" },
    { "name": "mempalace_add_entity", "description": "添加图谱实体" },
    { "name": "mempalace_add_relation", "description": "添加图谱关系" },
    { "name": "mempalace_list_agents", "description": "列出所有 agent diaries" },
    // ... 共 29 个
  ]
}

这意味着在支持 MCP 的工具(Claude Code、Cursor、OpenClaw 等)里,可以直接用 tool 调用 MemPalace,无需 shell 命令。


五、Python API 与自定义集成

除了 CLI,MemPalace 也提供了完整的 Python API,适合集成到现有工具中:

5.1 基础使用

from mempalace import Palace, Wing, Drawer

# 初始化
palace = Palace("~/my-palace")

# 添加记忆
palace.add(
    content="""技术决策记录:
- 2026-01-15:选型评审决定使用 Postgres 而非 MySQL
- 原因:Postgres 的 JSONB 列式存储更适合我们的半结构化数据
- 参与人:张三、李四
- 结论:MySQL 候选,等 Postgres 验证后再评估
""",
    wing="backend-api",
    room="architecture",
    metadata={
        "type": "decision",
        "date": "2026-01-15",
        "participants": ["张三", "李四"]
    }
)

# 语义搜索
results = palace.search("Postgres 选型", wing="backend-api", top_k=5)
for r in results:
    print(f"[{r['score']:.3f}] {r['text'][:200]}...")

5.2 时间线查询

from mempalace import KnowledgeGraph

kg = KnowledgeGraph("~/my-palace/knowledge-graph.db")

# 查询某个实体的完整时间线
timeline = kg.get_timeline("API Gateway")
for event in timeline:
    print(f"{event['timestamp']}: {event['event']} → {event['outcome']}")

# 查询两个实体之间的路径(类似 "A 和 B 之间有什么关联")
path = kg.find_path("Postgres", "JSONB")
print("关联路径:", " → ".join(path))

5.3 Agent 记忆共享

每个 specialist agent 可以在 palace 里拥有自己的 wing 和 diary:

from mempalace import AgentDiary

# 给一个 agent 创建专属 diary
diary = AgentDiary(palace, agent_name="code-review-agent")

# agent 执行任务后写日记
diary.write(f"""任务:审查 PR #234 的安全性
发现:
- SQL 注入风险:user_id 参数未做参数化查询
- 修复:已要求 PR 作者使用 prepared statement
时间:{datetime.now()}
""")

# agent 下次启动时读自己的日记
yesterday_notes = diary.read(since=datetime.now() - timedelta(days=1))

六、性能优化与生产配置

6.1 Embedding 模型选择

默认使用 bge-m3( multilingual),支持 100+ 语言,embedding 维度 1024。如果追求更快的检索速度,可以换轻量模型:

from mempalace import Palace
from mempalace.embedders import FastEmbedder

palace = Palace("~/my-palace")
palace.configure_embedder(FastEmbedder(model="all-MiniLM-L6-v2"))
模型维度速度质量
bge-m31024最高(多语言)
all-MiniLM-L6-v2384良好
bge-small384最快一般

6.2 向量数据库后端

from mempalace import Palace
from mempalace.backends import QdrantBackend

# 切换到 Qdrant(支持分布式)
palace = Palace("~/my-palace")
palace.configure_backend(QdrantBackend(
    url="http://localhost:6333",
    collection="mempalace"
))

6.3 存储空间估算

内容类型平均大小10000 条存储
短对话 chunk~500 bytes~5 MB
长代码块~5 KB~50 MB
设计文档~50 KB~500 MB
向量索引~2 KB/条~20 MB

总开销:约 300MB base(embedding 模型)+ 存储内容 + 向量索引。10000 条对话记忆大约 75MB 整体。

6.4 多机器同步

MemPalace 默认本地存储,但通过 wing 的 export/import 可以实现有限的多端同步:

# 导出 wing
palace.export_wing("work-laptop", output="/tmp/work-wing.tar.gz")

# 导入 wing(另一台机器)
palace.import_wing("/tmp/work-wing.tar.gz", merge_strategy="prefer-newer")

七、与 Mem0/Mastra/Hindsight 的横向对比

MemPalace 的优势在哪里?按实际测试数据说话:

维度MemPalaceMem0MastraHindsight
存储位置本地本地
API 依赖需要需要部分需要
R@5(无 LLM)96.6%N/AN/AN/A
知识图谱✅ SQLite
MCP Server✅ 29 tools
Claude Code 钩子
多后端支持✅ ChromaDB/Qdrant
Rerank 支持✅ Haiku 即可需要大模型需要需要

核心差异:MemPalace 是唯一一个在「零 API + 本地存储」约束下做到 96%+ R@5 的方案。 这对于隐私敏感项目(医疗、金融、内部代码)和成本敏感场景(有大量长期会话但不想付 API 费用)特别有价值。


八、安装与快速上手

8.1 安装

pip install mempalace

Python 3.9+,无需其他依赖。

8.2 初始化

mempalace init ~/projects/myapp

8.3 挖矿(Mine)

把内容注入 palace:

# 挖掘项目文件
mempalace mine ~/projects/myapp

# 挖掘 Claude Code 会话(按项目分 wing)
mempalace mine ~/.claude/projects/ --mode convos --wing per-project

# 挖掘指定项目并加标签
mempalace mine ~/projects/myapp --wing api-server --tags "backend,python"

8.4 搜索

mempalace search "为什么弃用 GraphQL"

# 限定 wing
mempalace search "JWT token 刷新" --wing api-server

# 带时间过滤
mempalace search "性能优化" --after 2026-01-01 --before 2026-03-31

8.5 启动恢复

mempalace wake-up

九、总结与展望

MemPalace 解决了一个很具体但很痛的问题:AI 的会话级失忆。

它没有走「云端大统一记忆平台」的老路,而是选择了本地优先、语义检索、知识图谱增强的工程路线。几个值得关注的点:

  1. 96.6% R@5 靠纯向量检索实现——这说明在记忆检索这个场景,semantic search 已经足够好了,LLM 重排是锦上添花而非必须
  2. wing/room/drawer 的层级设计——解决了全量搜索的上下文污染问题,让记忆真正可复用
  3. 零 API 依赖——对于企业内网项目和隐私敏感代码,这点比什么都重要
  4. 知识图谱 + 向量检索的双引擎——时间敏感和因果链类查询靠图谱,模糊相似性查询靠向量,两者互补

展望未来,MemPalace 的几个演进方向值得关注:

  • 多端同步协议:目前 export/import 是手动的,未来可能支持 CRDT 类的自动冲突合并
  • 更强的图谱推理:当前是关系存储 + 时间线查询,未来可能加入规则引擎做自动推理
  • 多人协作模式:目前的 wing 是单用户视角,多人共享记忆的权限管理还是个空白

GitHub 上 49K stars 的热度说明社区对这个方向是认可的。如果你也在被 AI 失忆困扰,强烈建议跑一遍 Quickstart 试试——整个安装过程不超过 5 分钟,但从此 Claude Code 就有了真正的记忆。


相关资源:

  • GitHub:https://github.com/MemPalace/mempalace
  • PyPI:pip install mempalace
  • 官方文档:https://mempalaceofficial.com
  • Discord:https://discord.gg/ycTQQCu6kn
  • Benchmark 方法论:https://github.com/MemPalace/mempalace/blob/main/benchmarks/BENCHMARKS.md

本文所有 benchmark 数据均来自 MemPalace 官方仓库可复现的测试结果,详见 benchmarks/BENCHMARKS.md。

推荐文章

js函数常见的写法以及调用方法
2024-11-19 08:55:17 +0800 CST
JavaScript设计模式:组合模式
2024-11-18 11:14:46 +0800 CST
全新 Nginx 在线管理平台
2024-11-19 04:18:33 +0800 CST
Elasticsearch 聚合和分析
2024-11-19 06:44:08 +0800 CST
PHP服务器直传阿里云OSS
2024-11-18 19:04:44 +0800 CST
使用 Vue3 和 Axios 实现 CRUD 操作
2024-11-19 01:57:50 +0800 CST
程序员茄子在线接单