AI 记忆系统:让 AI 拥有长期记忆
你有没有遇到过这种情况:跟 AI 说了"我喜欢简洁的回答",下一轮对话它又给了你一大段废话。或者你告诉它"这个项目用 pnpm 不用 npm",过了一会儿它又建议你跑 npm install。
这不是 AI 在偷懒,而是它真的没有记忆。
大模型本身是无状态的——每次 API 请求都是独立的,不记得上一次聊了什么。这个特性在聊天场景下问题不大,但在开发助手、项目管理、长期协作等场景下,简直是致命的。
这篇文章要聊的就是:怎么让 AI 拥有长期记忆?
一、为什么 AI 需要记忆系统
先区分两种"记忆":
上下文记忆——当前对话中提到的内容,AI 能记住。这是大模型窗口内的短期记忆,对话结束就没了。
长期记忆——跨会话、跨天、跨项目仍然有效的信息。比如用户的偏好、项目的背景、团队的决定、之前踩过的坑。
没有长期记忆的 AI,每次对话都是从零开始。你告诉它你的技术栈,它记不住。你纠正过它的错误,它还会犯。你解释过项目背景,它又得再问一遍。
我自己用 AI 辅助开发时,最头疼的就是这个。明明三天前刚跟它解释过的架构决策,今天它又给出了完全相反的建议。不是它不懂,是它不记得。
记忆系统解决的核心问题是:让 AI 在跨会话场景下保持对用户和项目的持续理解。
这不是简单的"把对话存到文件里"。一个真正好用的记忆系统,需要解决四个问题:
- 存什么——哪些信息值得记住,哪些不需要
- 怎么存——用什么结构存储,才能高效检索
- 怎么找——用户问一个问题,怎么快速找到相关记忆
- 怎么更新——记忆会过时,怎么自动整理和淘汰
接下来,我们一个一个拆解。
二、存什么:四种精确的记忆类型
记忆系统做的第一件事,不是设计存储结构,而是定义边界——什么该存,什么不该存。
这个边界非常重要。什么都存,记忆系统会变成垃圾堆,检索效率低下,还可能把 AI 带偏。什么都不存,那还要记忆系统干什么。
Claude Code 的记忆系统定义了四种精确的记忆类型,每种都有明确的保存规则和使用方式。这个分类基于一个核心原则:只保存不可从当前项目状态推导的信息。
代码模式、架构、Git 历史、文件结构——这些可以通过读取文件或 git log 获得,不需要记忆。记忆系统保存的是无法从代码中直接读取的信息。
2.1 user(用户记忆)
记录用户是谁。
name: 用户角色
description: 用户是一名数据科学家,专注可观测性和日志分析
type: user
source: ccb
- 内容:用户的角色、目标、职责、知识水平
- 保存时机:了解到用户的任何细节时
- 使用方式:根据用户背景调整回答的深度和风格
- 示例:
- "用户是数据科学家,专注可观测性"
- "用户有 10 年 Go 经验,第一次接触 React"
用户记忆的价值在于:它决定了 AI 跟你对话的方式。面对一个资深工程师和面对一个刚入门的新手,解释的深度、术语的使用、示例的复杂度都应该不同。
2.2 feedback(反馈记忆)
记录用户说过什么——包括纠正和确认。
name: 测试规范
description: 集成测试必须使用真实数据库,不要 mock
type: feedback
source: ccb
---
集成测试必须使用真实数据库,不要 mock。
**Why:** 上个季度 mock 测试通过了,但生产环境迁移失败,因为 mock 掩盖了真实的迁移问题。
**How to apply:** 所有涉及数据库的集成测试,一律使用真实数据库。
- 内容:用户给出的指导和反馈
- 保存时机:用户说"不要这样做"或"这样做很好"时
- 使用方式:确保同样的指导不需要重复给出
反馈记忆有一个特殊要求:必须记录 Why(原因)和 How to apply(如何应用)。Why 很重要——没有原因的规则是死记硬背,有了原因才能在边缘情况下做出正确判断。
还有一个容易忽略的点:同时记录成功和失败。如果只记录纠正,AI 会变得过度谨慎,什么都不敢做;如果只记录确认,它会重复犯错。
2.3 project(项目记忆)
记录项目正在发生什么。
name: 合并冻结
description: 2026-03-05 起开始合并冻结,为移动端发布做准备
type: project
source: ccb
---
从 2026-03-05 起开始合并冻结,为移动端发布做准备。
**Why:** 移动端团队正在切发布分支,需要稳定的 main 分支。
**How to apply:** 标记所有 2026-03-05 之后的非关键 PR 工作。
- 内容:项目上下文、目标、截止日期、决策原因
- 保存时机:了解到"谁在做什么、为什么、什么时候"时
- 使用方式:理解用户请求背后的背景和动机
项目记忆有一个容易踩坑的地方:相对日期必须转换为绝对日期。"周四"、"下周"、"下个月"——这些相对时间过了就不知道是什么时候了。"周四"→"2026-03-05",才能长期有效。
2.4 reference(参考记忆)
记录外部资源在哪里。
name: 流水线 bug 追踪
description: 所有流水线 bug 在 Linear 项目 "INGEST" 中追踪
type: reference
source: ccb
- 内容:外部资源的指针(Linear 项目、Slack 频道、Grafana 仪表盘等)
- 保存时机:了解到外部资源的位置和用途时
- 使用方式:用户引用外部系统时快速定位
参考记忆不存内容,只存指针。内容在外部系统里,记忆系统只记住"去哪里找"。
2.5 不应保存的内容
系统明确定义了不应保存的内容:
- 代码模式、约定、架构、文件路径——可以从项目状态推导
- Git 历史、最近变更——
git log/git blame更权威 - 调试解决方案——修复在代码里,commit message 有上下文
- 已在项目文档中的内容
- 临时任务细节:进行中的工作、临时状态、当前对话上下文
即使用户明确要求保存这些内容,系统也会询问"有什么特别或非显而易见的值得保留?"
这个设计思路很聪明:记忆系统存的是"不可推导的信息",而不是"所有信息"。 这保证了记忆系统始终是增量知识,而不是项目知识的副本。
三、怎么存:双引擎架构
定义好了存什么,接下来是怎么存。
记忆系统有两个互补的引擎,各有侧重:CCB(Claude Code Base) 和 MAGMA。
3.1 CCB——基于文件的结构化存储
CCB 是基于 Markdown 文件的结构化记忆系统。每个记忆是一个独立的 .md 文件,有 YAML frontmatter 定义元数据。
~/.claude/projects/<project-slug>/memory/
├── MEMORY.md ← 索引文件(自动生成)
├── user_role.md ← 用户记忆
├── user_preferences.md ← 用户记忆
├── feedback_testing.md ← 反馈记忆
├── feedback_naming.md ← 反馈记忆
├── project_merge-freeze.md ← 项目记忆
├── reference_linear.md ← 参考记忆
└── ...
每个记忆文件的结构是固定的:YAML frontmatter(类型、描述、来源)+ Markdown 正文。
MEMORY.md 索引格式:
# Memory Index
## User Memories
- [用户角色](user_role.md) — 数据科学家,专注可观测性
- [偏好](user_preferences.md) — 喜欢简洁回答,用 pnpm
## Feedback Memories
- [测试规范](feedback_testing.md) — 集成测试用真实数据库
- [命名风格](feedback_naming.md) — 函数名用动词开头
## Project Memories
- [合并冻结](project_merge-freeze.md) — 2026-03-05 起
## Reference Memories
- [Linear 项目](reference_linear.md) — INGEST 项目追踪流水线 bug
CCB 有几个有意思的设计细节:
MEMORY.md 有硬上限:200 行 / 25KB。超出会截断并警告。这个限制防止索引文件膨胀失控。
索引是自动生成的:不是手动维护的,而是通过 Dream 机制自动生成。这避免了"忘了更新索引"的问题。
记忆按语义主题组织,不按时间顺序。这跟人的记忆一样——你不会按时间顺序回忆,而是按主题联想。
3.2 MAGMA——基于向量的非结构化存储
MAGMA 是基于 LanceDB + Obsidian 的非结构化知识引擎。
如果说 CCB 像文件夹——精确、结构化、可编辑;那 MAGMA 像大脑——模糊、语义化、能联想。
MAGMA 采用五层记忆架构:
| 层 | 名称 | 存储 | 用途 |
|---|---|---|---|
| L1 | 瞬时记忆 | 内存 | 当前会话上下文 |
| L2 | 项目记忆 | LanceDB | 项目相关知识和上下文 |
| L3 | 用户记忆 | LanceDB | 用户偏好和习惯 |
| L4 | 反馈记忆 | LanceDB | 用户反馈和指导 |
| L5 | 参考记忆 | LanceDB + Obsidian | 外部资源引用 |
L1 是纯内存的,速度最快但容量最小。L2-L5 存储在向量数据库中,容量大但检索需要计算。
MAGMA 的核心能力是语义向量搜索。你不需要记住精确的关键词,只要意思接近就能找到。比如你搜"代码风格偏好",它能找到"函数名用动词开头"这条记忆——即使两个表述完全不同。
3.3 为什么需要两个引擎
CCB 和 MAGMA 解决的是不同问题:
| 维度 | CCB | MAGMA |
|---|---|---|
| 数据类型 | 结构化记忆 | 非结构化知识 |
| 存储方式 | Markdown 文件 | 向量数据库 + 笔记 |
| 检索方式 | 关键词匹配 | 语义向量搜索 |
| 优势 | 精确、可解释、易编辑 | 语义理解、模糊匹配 |
| 劣势 | 不支持语义搜索 | 需要额外基础设施 |
| 典型场景 | "用户偏好用 pnpm" | "这个项目的架构是怎样的" |
CCB 适合精确的事实——"用户叫 Alice"、"项目用 pnpm"。MAGMA 适合模糊的概念——"这个项目的整体架构"、"用户的工作风格"。
两个引擎互补,缺一不可。只有 CCB,AI 只能做精确匹配,找不到语义相关但表述不同的记忆。只有 MAGMA,AI 的记忆会失去精确性和可编辑性,而且需要额外的向量数据库基础设施。
四、记忆的生命周期
记忆不是存进去就完事了。一个完整的记忆系统,需要管理记忆的完整生命周期:
创建 → 用户说了一句话,系统判断"这值得记吗?" → 值得 → 按四种类型之一保存
检索 → 用户问了一个问题,系统分析意图 → 在 CCB 和/或 MAGMA 中搜索 → 返回相关记忆
整理 → Dream 机制定期运行,合并重复记忆、去重、更新索引
淘汰 → 过时的记忆被清理,有效的记忆被保留
这四个环节环环相扣,任何一个环节掉链子,记忆系统就会出问题。存了找不到,等于白存。存了不整理,记忆会膨胀失控。
五、设计哲学
回顾整个记忆系统,有几个设计哲学值得单独拎出来说:
1. 只存不可推导的信息。 这是整个系统的基石。能从代码、文档、Git 历史中获得的信息,不需要记忆。记忆系统只存增量知识。
2. 精确分类,而非一锅炖。 四种记忆类型各有明确的规则。这不是过度设计,而是为了避免模糊——模糊的分类导致模糊的使用。
3. 双引擎互补。 结构化 + 非结构化,精确 + 语义,文件 + 向量。没有银弹,只有合适的工具组合。
4. 自动整理。 Dream 机制让记忆系统不需要人工维护。就像人的睡眠——白天积累,晚上整理,第二天醒来记忆更清晰。
5. 有硬约束。 MEMORY.md 200 行上限、Token 预算控制、锁机制防并发。好的系统不是靠自觉,而是靠工程约束。
这期聊了记忆系统的"为什么"和"存什么"。下一期深入双引擎的内部实现——CCB 的读取器和整理器怎么工作,MAGMA 的向量搜索和知识图谱怎么构建,以及它们之间怎么协同。
系列: