跳转到主要内容

RAG 之外的 AI 记忆:向量、图谱和 Dense-Mem

RAG 不是魔法记忆。本文用实践视角解释 chunk、embedding、向量搜索、图谱支撑的记忆,以及为什么持久 AI 记忆需要来源证据、冲突处理和检索策略。

9 分钟阅读
分享:
AI 驱动

AI 驱动 · 每小时限 20 次请求

AI 记忆把文档层、向量空间和图谱关系连接到助手核心
AI 记忆不只是 RAG,它是证据、状态、关系和更新策略的组合。

先说结论

都 2026 年了,"AI 记忆"早不是一个单一功能了。大家嘴上说的"记忆",其实往往是下面五层里的某一层。每层都有用,也各有各的坑。

层次干嘛的常见翻车
Prompt 记忆把指令塞进上下文上下文缺东西或者写得含糊,规则就被忽略了
RAG找外部文档,再注入上下文可能捞到过时的、不完整的证据
向量记忆检索语义相近的内容文本相似不代表答案就对
图谱记忆存事实、关系、历史和冲突没有验证关卡的话,错误事实会一直赖在里面
持久记忆把检索、状态、来源、更新策略组合起来缺任何一层,信任就崩了

我自己总结的一条实用原则:检索负责找文本,记忆负责判断什么是当前的、可信的、跟这次任务相关的。这也是为什么 prompt 放在哪里依然很重要;更简单的心智模型可以看 系统 prompt 与用户 prompt

这个区分很关键。如果把检索当记忆,系统能找到旧文本,却不知道哪个事实才是当前事实。如果把 embedding 当"理解",你能做出一个飞快的搜索系统,但它照样会返回错误证据。如果加了图谱却没有清晰关卡,你会把嘈杂的对话变成一套看似自信、其实被污染的记忆。

所以我们把这些部分拆开来看。

Claude Code 的记忆是上下文,不是数据库

Claude Code 自带的记忆挺好用的,但它不是向量数据库,也不是图谱记忆系统。

按现在 Claude Code 的记忆文档,每个 session 都从全新的上下文窗口开始。跨 session 携带知识靠两个机制:你自己写的 CLAUDE.md 文件,以及 Claude 从你的纠正和偏好里自动记下来的笔记。两者都会在对话开始时加载进来。Claude 把它们当上下文,不是强制执行的配置。

最后一句是重点。

CLAUDE.md 里可以写:

markdown
完成代码修改前始终运行 npm test。
优先做小而聚焦的修改。
API 处理器位于 src/api/handlers/。

这能让模型行为更一致,因为指令在上下文里看得见。但它并没有创建一个可搜索的语义记忆系统。它不会给每次历史对话做 embedding,不会维护冲突解决,也不会自动知道某个偏好已经被新偏好取代了——除非新事实同样出现在可见上下文里,而且模型真的遵循了它。

自动记忆也是同理。它是持久上下文,不是知识图谱。文档说自动记忆会加载到每个 session,上限是前 200 行或 25KB。存实用指南足够了,但要撑长期、高容量、带证据追踪的记忆就不够了。

所以我更倾向于把 Claude Code 的记忆看成"启动上下文"。它很适合存指令、约定、踩坑后总结的项目笔记。但它不是 AI 记忆的完整答案。

RAG 不等于"关键词上下文"

很多人脑子里的 RAG 是这样的:"搜个关键词,抓它前后 100 个字符,粘进 prompt。"

这种东西可以有,但它不是 RAG 的定义。

RAG 是检索增强生成(Retrieval-Augmented Generation)。系统先检索外部信息,再把这些信息作为额外上下文交给模型去生成答案。检索部分可以是关键词搜索、向量搜索、混合搜索、图谱遍历、SQL 过滤、rerank,也可以是这些方式的组合。

RAG 流水线:文档被切成片段,片段变成 Embedding,排名靠前的结果被注入提示词
RAG 流水线

一个典型的向量 RAG 搭建流程大概是这样:

  1. 收集源文档。
  2. 把文档切成 chunk。
  3. 把每个 chunk 转成向量。
  4. 把向量加上元数据存进索引。
  5. 查询时,把用户问题也转成向量。
  6. 检索最接近的 chunk。
  7. 把这些 chunk 注入 prompt。

"chunk"本来就不是固定大小的。它可以是 300 个 token、800 个 token、一个段落、一个 Markdown 小节、一个代码符号,或者一个语义段。有些系统会加重叠区。有些系统会在找到第一个结果后,再拉取相邻的 chunk。还有些系统会在 LLM 看到候选内容之前,用 reranker 重新排序。

所以正确的说法不是"RAG 会抽取关键词附近 100 个字符"。

更准确的说法是:RAG 检索的是你配置好的上下文单位;质量高度依赖你怎么切 chunk、做 embedding、建索引、过滤、rerank,以及最后怎么组装上下文。

瓶颈不是 RAG,而是无状态的检索

当答案确实存在于语料里时,RAG 是很强的。

比如我问"这个服务用什么端口?",RAG 可以找到 README、配置文件或部署笔记。我问"用户上个月说过 Neo4j 什么?",RAG 可以检索到那段对话片段。

但记忆要面对更难的问题:

3 月 1 日:"我偏好用 Postgres 做项目记忆。"
4 月 10 日:"其实我想给这个记忆项目用 Neo4j。"
今天:"我的记忆项目应该用什么数据库?"

纯检索系统可能同时找到 3 月和 4 月那两段话。它可以把两段都交给模型,然后指望模型自己推理出正确答案。有时候没问题。但有时候模型会选中已经过时的事实,把两者混在一起,或者过于自信地给出回答。

这不是向量搜索的问题,而是状态管理的问题。

持久记忆需要知道的不只是"什么文本和问题相似"。它还要知道:

  • 说过什么?
  • 谁说的?
  • 什么时候说的?
  • 这是证据、声明,还是已经被接受的事实?
  • 它跟现有事实有没有冲突?
  • 旧事实是不是已经被取代了?
  • 它属于哪个 profile 或项目?
  • 这次任务该不该召回它?
RAG 检索与持久 AI 记忆的对比
RAG 检索与持久记忆的区别

这就是图谱支撑的记忆开始变得重要的地方。不是因为图谱数据库有什么魔法,而是因为记忆本身就是有关系的、有历史的。

Embedding 到底在做什么

Embedding 模型把文本变成数字。

更准确地说:一段输入文本变成一个向量。一批文本变成一个矩阵,因为多个向量堆在一起了。

句子 Embedding 可以表示为向量,也可以堆叠成矩阵
句子 Embedding 是向量,也可以组成矩阵

举个例子:

"用户偏好用 Neo4j 做记忆图谱。"

-> [0.12, -0.44, 0.31, ... , 0.08]

这些数字不是随机 ID,是模型学出来的坐标。Embedding 模型经过训练后,会让意义相关的文本在向量空间里彼此更接近。

但这些维度不是人类预先定义好的分类。

一个 768 维的向量不是说:

维度 1   = 数据库属性
维度 2   = 项目属性
维度 3   = 偏好属性
...
维度 768 = 记忆属性

这种解释很诱人,但太表面了。维度是模型学到的潜在坐标。人类有时候能解读 embedding 空间里的某些方向,但这些坐标并不是一套干净利落的分类体系。

更多维度可以给模型更大的容量来保存信号,但"维度更多"不等于"更准确"。一个弱模型生成的 3,072 维 embedding,可能还不如一个更适配你领域的 768 维 embedding。检索质量取决于 embedding 模型本身、训练数据、语言和领域的适配程度、归一化方式、chunk 质量、元数据过滤,以及评估集。

Embedding 模型之所以重要,是因为它决定了"接近"到底意味着什么。

向量数据库搜索到底在搜什么

搜索向量数据库时,你问的不是:

哪篇文档包含这个精确的词?

你问的是:

哪些已存的向量跟查询向量最接近?
Embedding 空间里的查询点和最近邻居
Embedding 空间与最近邻居

数据库里存的向量大概长这样:

json
{
  "id": "fragment-123",
  "text": "用户偏好用 Neo4j 做记忆图谱。",
  "embedding": [0.12, -0.44, 0.31, "..."],
  "metadata": {
    "profile": "mark",
    "source": "chat",
    "created_at": "2026-05-25"
  }
}

查询时大概是这样:

查询: "Mark 偏好用什么记忆数据库?"
查询 Embedding: [0.10, -0.40, 0.29, ...]

最近的已存向量:
1. "用户偏好用 Neo4j 做记忆图谱。"
2. "记忆服务使用 Neo4j 图谱和向量索引。"
3. "记忆服务器把图谱事实存放在宿主 LLM 外部。"

数学上通常用余弦相似度、点积或欧氏距离,取决于数据库和索引配置。很多系统会对向量做归一化,让方向比大小更重要。大数据库会用近似最近邻(ANN)索引,保证数据量上去之后搜索速度还能跟上。

这就是向量数据库的价值所在:它让语义召回变得实用。而且在数据存取层面它是模型无关的——Go 服务、TypeScript 应用、Python notebook、Claude Code 插件或 MCP 服务器都可以存取同一个记忆服务,只要大家约定好 embedding 模型和向量维度就行。

但向量搜索返回的仍然只是候选结果,它不判断真伪。

为什么还要加图谱数据库

图谱数据库直接存储关系。

对记忆来说,这比把每条记忆都当成一段纯文本 chunk 要合适得多。

(User)-[:PREFERS]->(Neo4j)
(Neo4j)-[:USED_FOR]->(MemoryProject)
(Fact)-[:SUPPORTED_BY]->(Evidence)
(Fact)-[:SUPERSEDES]->(OldFact)
(Claim)-[:CONFLICTS_WITH]->(Fact)

这让你能问一些向量搜索不擅长的问题:

关于这个用户的数据库偏好,当前有哪些活跃事实?
哪条声明取代了更早的 Postgres 偏好?
哪些记忆跟这个项目有关?
哪些事实的证据比较弱?
助手应该主动询问哪些还没解决的矛盾?

微软的 GraphRAG 用图谱解决的是一个相关但不同的问题:通过抽取、网络分析、prompt 编排和总结来理解文本数据集。对个人或项目记忆来说,真正有用的启示不是"用图谱替代向量搜索",而是"当关系和来源成为一等信息时,检索会变得更强"。

向量搜索回答的是:"语义上什么接近?"

图谱搜索回答的是:"什么是相连的、当前的、有证据支撑的,或者存在冲突的?"

更强的记忆架构会同时用上两者。

拿 Dense-Mem 做个小案例

这就是我在 Dense-Mem 里实践的思路。

重点不是具体实现,而是边界划分。我不希望每个宿主都发明自己的记忆格式,也不希望 LLM 仅仅因为看到一句看似重要的话,就悄悄改写长期记忆。

Dense-Mem 记忆流程:对话片段到托管式图谱记忆
Dense-Mem 记忆流程

有用的模式其实很简单:宿主模型负责发现候选记忆,记忆层负责存储、embedding、来源追踪、冲突检查和召回。原始证据不应该直接变成事实。记忆应该先经过关卡;冲突应该触发澄清,而不是被静默覆盖。

这篇文章讲到这里就够了。Dense-Mem 是我目前用来练习这套架构的实验:外部记忆服务、图谱 + 向量召回,以及显式的状态转换。

如果你想跑起来而不只是看概念,可以先看 Dense-Mem 快速上手:让 Claude Code 和 Codex 共享同一份记忆,里面会走一遍本地 Docker 搭建和 MCP 客户端配置。等你准备好公开 HTTPS 端点了,再看 用 Vultr 和 Traefik 安全部署 Dense-Mem

准确率、存储和性能

很容易脱口而出一句"图谱 + 向量记忆比 RAG 更准确、性能更好"。

这样说太笼统了。

诚实一点的说法是这样的:

层次改善什么单独解决不了什么
Chunking检索精度和上下文质量真伪、时效性、冲突处理
Embedding 模型跨语言、跨领域的语义匹配质量来源、事实确认、用户确认
向量数据库快速的最近邻检索关系遍历和当前状态策略
图谱数据库关系、来源、多跳召回、事实取代不配合 embedding 的话,处理不了语义相似度
Reranking更好的最终上下文排序烂的源数据或烂的记忆关卡
澄清流程记忆冲突时提高正确率完全自动且无需用户参与的记忆

图谱数据库如果模型设计得好、索引合理,关系查询可以非常快。向量数据库如果 embedding 一致、索引适配负载,语义搜索也可以非常快。烂的图谱 schema 会慢,烂的向量索引会检索出莫名其妙的结果,塞满检索 chunk 的巨大 prompt 照样会把模型搞糊涂。

没有免费的午餐。这套架构之所以有效,是因为每一层都有自己明确的工作。

我信任的设计原则

做 AI 记忆,我逐渐收敛到这条原则:

保存原始证据。谨慎提升类型化事实。用向量检索。用图谱推理关系。解决冲突前先问用户。

这样得到的是可以跨宿主、跨语言移植的记忆系统。Claude Code、Codex、web 应用或其他 MCP 客户端都可以跟同一个记忆服务器对话。记忆不会因为聊天窗口重置就消失了,也不依赖一个 prompt 文件无限变长。它还能保留自己为什么相信某件事的理由。

RAG 仍然是系统的一部分,它是召回机制。

但记忆比召回更大。

记忆是你选择保留什么、怎么知道它是真的、怎么更新它,以及什么时候决定把它带回来。

许可

Article text © 2026 Mark Huang. Licensed under Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) unless otherwise noted. 文章文本可在非商业场景下分享或翻译,但需标注原文 URL。商业使用需事先取得书面许可,并清楚引用原始来源。

代码片段、截图、第三方素材和网站源码可能适用单独条款。

建议署名: Based on "RAG 之外的 AI 记忆:向量、图谱和 Dense-Mem" by Mark Huang, originally published at https://markhuang.ai/zh/blog/ai-memory-beyond-rag.