🧠 Memory System
一个面向长期对话、长期成长、长期项目协作的本地化六层记忆系统。
它不是“给大模型加一个向量库”这么简单,而是把人的长期上下文拆成 6 类不同性质的记忆,并为不同问题走不同检索路径,再把结果汇总给生成层。这也是它和很多只有 3 层、甚至只有“短期上下文 + 向量检索”方案最大的差别。
本仓库是可公开分享的脱敏版本:
- ✅ 保留完整的核心代码、接口设计、路由机制与 Open WebUI 集成方式
- 🛡️ 删除真实私有数据、真实密钥、真实向量库与图谱库内容
- 📦 适合作为 GitHub 展示、架构参考、二次开发模板
详细脱敏清单见 PUBLIC_SANITIZATION.md。
📖 目录
- ✨ 这个项目为什么值得看
- 🏗️ 六层架构设计
- 🚀 为什么 6 层比常见 3 层更强
- 🛣️ 路由机制:不仅是存储,更是策略
- 🛠️ 技术栈
- 🔌 主要接口能力
- ⚡ 快速开始
- 💬 Open WebUI 集成
- 🤖 OpenClaw Skill
- 🔒 为什么公开版必须脱敏
- 📂 项目结构
- 💡 给使用者的建议
- 📜 License
✨ 这个项目为什么值得看
很多记忆系统只做到下面其中一部分:
- 把聊天内容向量化后做语义召回
- 存一个“用户画像”JSON
- 做一个简单的自动摘要
这个项目进一步把长期记忆拆成 6 层,并配合路由分类器、并行检索、证据回传和综合执行器,让系统不只是“记住”,而是能按问题类型调用最合适的记忆结构。
核心优势:
- 🎯 六层分治,不把所有信息混成一个向量池:身份、知识、事件、关系、反思、目标分别建模
- 🚦 自动路由,而不是所有问题都全库搜索:减少噪音,提高召回精度和响应效率
- 🕸️ 关系层单独建图,而不是把“人物关系”硬塞进向量库:适合协作链路、影响路径、关键人物节点分析
- 🧠 反思层单独沉淀:不是只记事实,还沉淀“对事实的理解”
- 🏹 目标层单独建模:让系统能回答“接下来该做什么”,不止回答“过去发生了什么”
- 🧩 统一综合入口:
/synthesize/copilot会根据任务把不同层的证据拼起来生成结构化输出 - 🔍 检索带证据和置信度:不仅给结论,还能追溯到记忆来源
- 🛡️ 支持会话级隔离:Open WebUI 里通过
chat::<scope_id>防止新旧窗口串记忆
如果用一句话概括:
这不是“单层向量记忆 + 大模型总结”,而是“分层记忆建模 + 路由检索 + 证据合成”的长期记忆操作系统。
🏗️ 六层架构设计
👤 L0: Profile / Identity
用于存储稳定、低频变化、应该始终可见的基础画像。
适合承载:
- 身份信息
- 职业角色
- 沟通风格
- AI 指令偏好
为什么要独立成层:
- 这类信息不是“检索出来再看”,而是很多时候应当直接作为全局上下文使用
- 如果把它混入普通向量记忆,容易被噪声覆盖
当前实现:
- YAML 文件存储
- 在检索和综合输出时可按需注入
profile
📚 L1: Semantic / Knowledge
用于存储长期稳定的知识、能力、方法论、项目经验抽象。
适合承载:
- 技能
- 经验总结
- 方法论
- 项目共性认知
为什么要独立成层:
- 这类信息强调“长期有效”和“抽象能力”
- 它和事件日志不同,不应该被时间线噪声淹没
当前实现:
- Qdrant 向量检索
- 支持
tags/sources等过滤
📅 L2: Episodic / Timeline
用于存储具体事件和时间线,是“你做过什么”的事实层。
适合承载:
- 工作日报
- 学习记录
- 项目进展
- 带日期的具体行为和结果
为什么要独立成层:
- 这类信息高频、时序强、细节多
- 回答“最近进展”“什么时候做过这件事”时,L2 比 L1 更关键
当前实现:
- Qdrant 向量检索
- 支持
date_from、date_to、project等过滤
🕸️ L3: Relational / Graph
用于存储人物、团队、职责、合作链路、影响关系,是协作认知层。
适合承载:
- 谁和谁协作
- 谁影响了哪个项目
- 哪个角色是关键节点
- 团队与项目的映射关系
为什么要独立成层:
- 关系问题本质上不是“语义最相似的一段话”
- 关系推断需要图结构、节点和边,而不是纯文本向量
当前实现:
- Neo4j 图数据库
- 关系查询由 L3 单独承担
💡 L4: Reflective / Reflection
用于存储系统对历史经历的二次理解,是“反思后的记忆”。
适合承载:
- 周报 / 月报式反思
- 盲区发现
- 能力总结
- 成长判断
为什么要独立成层:
- 事实和解释不应该混在一起
- 同一段经历在不同阶段会产生不同反思,L4 需要被单独追踪
当前实现:
- Qdrant + 反思日志
- 支持自我画像等反思型输出
🎯 L5: Aspiration / Goals
用于存储目标、计划、优先级、成长方向,是“未来导向”的层。
适合承载:
- 长期目标
- 学习计划
- 项目优先级
- 路线图和里程碑
为什么要独立成层:
- 很多记忆系统只能回答“你以前做过什么”
- L5 让系统能回答“你接下来应该做什么”
当前实现:
- YAML + 向量混合
- 支持目标查询和未来导向综合输出
🚀 为什么 6 层比常见 3 层更强
常见 3 层方案通常会把问题粗分成:
- 用户画像
- 长期记忆
- 短期上下文
这种方式能跑,但在复杂场景下会遇到几个问题:
1. 关系问题容易失真
当“谁和谁合作最紧密”“谁是影响项目推进的关键节点”这类问题出现时,单纯向量检索往往只能召回提到这些人的文本片段,但无法天然表达“节点-关系-影响路径”。
L3 单独建图,就是为了处理这类问题。
2. 事实和反思会混淆
“这周做了什么”和“这周最重要的成长是什么”不是同一种信息。
如果都塞进一个向量集合:
- 事实容易淹没反思
- 反思容易污染事实检索
L2 与 L4 分离,就是为了把“发生过什么”和“如何理解这些经历”拆开。
3. 过去与未来目标会混淆
很多系统擅长回忆,但不擅长规划。
L5 单独建模之后,系统不仅能回答:
- 你做过什么
还可以回答:
- 你下一步该优先做什么
- 你的学习路径是否和长期目标一致
4. 所有问题全库搜索会带来噪音
如果每次都把所有记忆混在一起查:
- 成本更高
- 噪音更大
- 命中更随机
分层 + 路由的价值就在于:
- 📝 简历问题优先看 L1/L2/L3/L5
- ⏱️ 近期进展优先看 L2
- 🖼️ 自我画像优先看 L0/L1/L4
- ⚠️ 项目风险优先看 L2/L5
- 🤝 人际协作问题优先看 L3
也就是说,不是记忆越多越好,而是结构越清晰越强。
🛣️ 路由机制:不仅是存储,更是策略
这个项目的核心不只是存储,而是“按问题类型选择检索策略”。
1. /remember 不是机械落库
写入时支持:
layer_hint=auto- 分类器自动判断应写入哪一层
- 分类日志留痕
- 分类规则可持续积累
这意味着系统不是把每条输入都当成同一种记忆处理。
2. /recall 支持自动路由
在 layers=auto 时:
- 系统先对 query 做分类
- 决定查哪些层
- 并行检索
- 如果首轮结果为空,再自动扩层补搜一次
也就是说,它不是单次检索,而是带“回退策略”的检索流程。
3. 综合能力不是靠 prompt 硬写,而是靠专门任务路由
/synthesize/copilot 会把任务分流到专门的能力:
resumework_statuslearning_engineself_profileproject_radardecision_copilotcareer_assets
每个任务都会按不同层去抓证据,再合成输出。
例如简历生成时,系统会组合:
- L1 能力与方法论
- L2 项目和事件成果
- L3 协作与影响力
- L5 目标与成长方向
这比“把最近几条聊天记录丢给模型写简历”要强得多,因为它是多层证据融合,不是单源猜测。
4. Open WebUI 入口已经做了意图识别
在 integrations/openwebui/memory_inlet_filter.py 里:
- 简历类问题会走
resume - 最近进展类问题会走
work_status - 自我画像类问题会走
self_profile - 风险阻塞类问题会走
project_radar - 决策类问题会走
decision_copilot - 学习规划类问题会走
learning_engine - 普通问题走默认
/recall
这意味着前端接入不是“加了个工具”,而是已经有一套完整的记忆调用策略。
5. 会话隔离避免串记忆
Open WebUI Inlet/Outlet 使用:
chat::<scope_id>作为会话来源
这样做的价值是:
- 一个新会话不会莫名混入另一个会话的临时聊天记忆
- 但你又可以通过全局白名单源保留长期导入数据
这在真实使用里非常重要,否则长期记忆系统很容易“越用越脏”。
🛠️ 技术栈
| 组件 | 技术 | 作用 |
|---|---|---|
| API 层 | FastAPI | 提供 /remember /recall /reflect /synthesize/* 等接口 |
| 向量层 | Qdrant | L1 / L2 / L4 / L5 的向量检索 |
| 图谱层 | Neo4j | L3 关系图谱与关系查询 |
| 嵌入模型 | Ollama + nomic-embed-text | 文本向量化 |
| 生成模型 | Ollama + qwen3 系列 | 分类、总结、合成输出 |
| 编排 | Docker Compose | 本地一键启动全部服务 |
| 对话入口 | Open WebUI | Tool / Inlet Filter / Outlet Filter 集成 |
技术选型的核心思路不是“堆技术”,而是让每一类记忆结构使用最适合的数据结构:
- 文本知识和事件适合向量检索
- 关系适合图检索
- 稳定画像和目标适合结构化文件 + 检索混合
🔌 主要接口能力
基础能力:
POST /rememberPOST /recallPOST /reflectPOST /ingest/worklog
综合能力:
POST /synthesize/resumePOST /synthesize/work_statusPOST /synthesize/self_profilePOST /synthesize/project_radarPOST /synthesize/decision_copilotPOST /synthesize/career_assetsPOST /synthesize/learning_enginePOST /synthesize/copilot
辅助治理:
GET /profile/snapshotsGET /profile/conflictsPOST /profile/conflicts/resolveGET /classifier/debug/lastGET /classifier/rulesPOST /classifier/feedbackGET /classifier/settings
OpenAPI 文档地址:
http://localhost:8000/openapi.json⚡ 快速开始
1. 准备环境变量
cp .env.example .env然后修改 .env:
NEO4J_AUTHNEO4J_PASSWORDMEMORY_API_KEY- 模型相关配置
2. 启动服务
cd config
docker compose up -d --build3. 健康检查
curl http://localhost:8000/health4. 查看 OpenAPI
open http://localhost:8000/openapi.json💬 Open WebUI 集成
目录:integrations/openwebui/
包含:
memory_tools.py:手动工具调用memory_inlet_filter.py:提问前自动注入记忆memory_outlet_filter.py:回答后自动保存用户输入README.md:接入说明
这部分的亮点不是“能连 Open WebUI”,而是已经把以下能力做好了:
- ✅ 自动意图判断
- ✅ 自动调用
/synthesize/copilot或/recall - ✅ 会话级来源隔离
- ✅ 全局导入源白名单
- ✅ 关系问题特殊处理
也就是说,接入后不是“记忆系统作为被动 API”,而是“前端对话入口已经具备记忆策略”。
🤖 OpenClaw Skill
为了方便别人把这个项目直接接到 Agent 框架里,仓库里额外提供了一个放在本仓库内的 skill 包:
openclaw-skill/memory-system-copilot/它的作用不是替代后端,而是告诉 Agent:
- 什么问题该走
/recall - 什么问题该走
/synthesize/copilot - 什么情况下优先查 L3 关系层
- 什么情况下应该把内容写回
/remember - 回答时如何处理
evidence和confidence
也就是说,这个 skill 把“六层记忆系统的调用策略”从代码层进一步抽象成了“Agent 可消费的操作规范”。
如果你的 OpenClaw 支持目录式 skill,可以直接迁移这个目录;如果只支持粘贴式技能,也可以直接复制 SKILL.md 的内容使用。
🔒 为什么公开版必须脱敏
你看到仓库里有些内容被删掉,不是因为这些内容不重要,而是因为它们太重要了,不能公开。
公开版删除的对象主要有 5 类:
1. 真实 .env
- 原因:包含 API Key、数据库密码、服务地址,一旦泄露就是直接安全风险
- 保留方式:提供
.env.example,让使用者自己填入本地配置
2. 真实 profile.yaml
- 原因:这里存的是用户画像、身份、风格偏好、AI 指令等,对个人记忆系统来说,这就是最核心的私密资产之一
- 保留方式:公开版只保留匿名模板
3. 真实 goals.yaml
- 原因:这里体现真实长期目标、计划、优先级,属于高度个人化的长期策略信息
- 保留方式:公开版替换成示例目标模板
4. 真实日志与分类学习结果
包括 classification_log.jsonl、reflection_quality_log.jsonl、classification_rules.json 等。
- 原因:这些文件会暴露真实问题、真实项目、真实工作轨迹,还会暴露系统是如何从个人历史中学习出来的规则
- 保留方式:保留文件结构,清空或重置为默认值
5. 向量库与图数据库实际数据
包括 data/qdrant 和 data/neo4j。
- 原因:即使你看不到明文文本,底层索引也依然代表真实私有记忆。一旦公开,别人可能通过数据还原、结构分析、日志对照推断出个人信息
- 保留方式:只保留目录和
.gitkeep,不保留真实运行数据
换句话说:
公开版保留的是“系统能力和结构”,删除的是“真实个人记忆资产”。
这不是削弱项目,而是把“可展示的工程能力”和“不可公开的个人资产”边界划清楚。
📂 项目结构
.
├── config/ # Docker Compose 配置
├── data/ # 脱敏后的模板数据目录
├── integrations/openwebui/ # Open WebUI 工具与过滤器
├── openclaw-skill/ # 可直接迁移到 OpenClaw 的 skill 包
├── scripts/ # 项目脚本
├── src/ # FastAPI 与六层记忆核心实现
├── PUBLIC_SANITIZATION.md # 脱敏说明
└── README.md💡 给使用者的建议
如果你想把这个项目真正跑起来,而不是只看代码,推荐按下面顺序:
- 先启动
Qdrant + Neo4j + FastAPI - 配好
.env - 先直接测
/remember和/recall - 再接 Open WebUI Tool / Filter
- 最后再根据自己的数据源接入导入脚本和反思流程
📜 License
本项目遵循 MIT License。