Ch06: Memory vs RAG——经验和知识不是一回事
Part 2: 记忆基础概念 前置章节:Ch05: Profile vs User Memory——写给 Agent 的 vs Agent 自己学的 后续章节:Ch07: 记忆系统的设计约束——存什么、怎么存、何时忘
1. 从”老员工的经验”和”公司知识库”说起
想象你刚入职一家公司。你有两个获取信息的渠道。
第一个渠道是坐在你旁边的老员工老王。你在开发中遇到一个问题,转头问他:”咱们项目的数据库用的什么?”老王说:”PostgreSQL,9.6 版本,主从架构,写操作走主库。”你又问:”之前有没有人踩过连接池耗尽的坑?”老王说:”有,去年张工遇到一次,最后发现是没配 pgbouncer,后来加上了。”老王给你的不是书本上的通用知识,而是这家公司、这个项目、这个团队的具体经验。你下次问老王同样的问题,他会说”上次不是跟你说过吗”,然后把同样的答案再说一遍——但如果你换了项目,老王的答案就变了。
第二个渠道是公司的内部知识库(Confluence / Wiki)。你在知识库里搜索”PostgreSQL 连接池配置”,出来一篇详细的运维手册,里面有最佳实践、配置模板、常见问题排查步骤。这篇文章是 DBA 小李去年写的,经过三人 review,被标记为”权威文档”。但知识库不会告诉你”张工去年踩过这个坑”——它只告诉你通用知识,不告诉你具体谁、在什么时候、遇到过什么。
老王就是 Memory,公司知识库就是 RAG。
两者都在帮你获取信息,但来源不同、粒度不同、更新方式不同、时效性不同。更重要的是,它们不能互相替代——你不能因为有了知识库就开除老王,也不能因为老王经验丰富就不维护知识库。
这一章要做的就是把这层区别讲透:Memory 和 RAG 各自解决什么问题、在哪些地方容易混淆、为什么两者必须互补而不是二选一。
2. Memory 的定义:从交互中自动学到的个性化信息
先说结论:Memory 是 Agent 从与用户的交互中自动提取并持久化存储的个性化信息,用于在后续交互中提供更精准、更贴合用户需求的服务。
拆开来看,Memory 有五个关键特征。
特征一:来源是对话。Memory 的原始素材是 Agent 和用户之间的对话。用户在聊天中说”我主要用 Python 写后端”,这句话就成了 Memory 的候选来源。Memory 不来自人工上传的文档、不来自预先准备的知识库——它来自活生生的、正在发生的交互。
这一点和 RAG 形成鲜明对比。RAG 的来源是文档——有人写好了,有人上传了,有人索引了。文档是”死的”,在它被创建的那一刻就固定了。对话是”活的”,每一轮都在产生新的信息。
特征二:粒度是 per-user。Memory 最核心的属性是”属于某个特定用户”。用户 A 说”我用 PostgreSQL”,用户 B 说”我用 MySQL”——这两个记忆不会冲突,因为它们分别绑定在不同的用户 ID 上。当 Agent 为用户 A 服务时,只检索用户 A 的记忆;为用户 B 服务时,只检索用户 B 的记忆。
这个粒度选择不是偶然的。用户的偏好、习惯、项目上下文天然就是 per-user 的——你用 PostgreSQL 不代表别人也用 PostgreSQL。如果所有用户的记忆混在一起,Agent 就无法区分”这个偏好属于谁”。
特征三:写入是自动触发。用户不需要显式地”告诉 Agent 记住这个”。当对话中出现值得记住的信息时,系统(或 Agent 本身)会自动提取并写入。在 mem0 中,这是一个后台 LLM 调用——每次对话结束后,LLM 扫描整个对话,提取独立事实条目。在 Claude Code 中,是 extractMemories 后台 agent 在每一轮对话后 fire-and-forget 地运行。在 Letta 中,是 Agent 自己通过 tool call(core_memory_append)主动写入。
无论哪种实现,核心都是”不需要用户手动触发”——Agent 或系统自己判断”这条信息值得记住,我来存”。
特征四:更新是实时。当用户在对话中说”我换工作了,现在用 Rust 而不是 Python”,Memory 系统应该能在当前或下一次交互中反映这个变化。这不是”分钟级延迟后才能搜到”,而是”下一次对话就已经生效”。
实时的代价是:每轮对话后都需要一次提取操作(一次 LLM 调用或一次 tool call),这增加了延迟和成本。但好处是信息不会丢失——你今天说的偏好,明天就生效,不需要等”系统下次同步”。
特征五:内容是主观的、情境的。Memory 存的不是客观真理,而是关于某个特定用户的偏好、历史和上下文。”用户喜欢深色主题”是一条 Memory,但它只对这个用户成立,换一个用户可能完全相反。Memory 的价值恰恰在于它的主观性——它让 Agent 能够”懂”你,而不只是”知道”客观事实。
把这五个特征合在一起,Memory 可以精确定义为:
Memory:Agent 在与特定用户的交互过程中,自动提取并持久化存储的个性化信息集合,包括用户偏好、历史事件、项目上下文等,用于在后续交互中提供更贴合用户需求的服务。
3. RAG 的定义:从外部文档中检索的权威知识
再说 RAG。先说结论:RAG(Retrieval-Augmented Generation,检索增强生成)是 Agent 从预先构建的外部文档库或知识库中检索相关信息,用于增强回答的准确性和权威性。
同样拆开来看。
特征一:来源是人工上传的文档。RAG 的原始素材不是对话,而是文档——技术手册、API 文档、产品规范、最佳实践指南、内部 Wiki 页面。这些文档是有人专门写的、有人专门上传的、有人专门维护的。
文档的特点是”经过加工”。一篇好的技术文档不是随口说的,它通常经过了审查(review)、标注了版本号、有明确的作者和更新日期。这意味着 RAG 检索到的信息有一个隐含的”权威性”——它不是某个人的随口一说,而是被认可的正式内容。
特征二:粒度是共享知识库。RAG 的文档不属于某个特定用户——它属于知识库,对所有人可见。PostgreSQL 的官方文档对所有查询它的人返回相同的内容。公司内部的 API 规范文档对所有开发者一视同仁。
这意味着 RAG 天然是”共享的”而非”个性化的”。它提供的是通用知识,不是针对你个人的定制信息。这一点和 Memory 的 per-user 粒度形成本质区别。
特征三:写入需要人工上传和索引。RAG 不会自动从对话中提取知识——你需要有人写好文档、上传到知识库、运行索引管线(通常是分块 + 向量化),然后才能被检索到。
索引管线是一个不可忽略的步骤。一个典型的 RAG 管线包含:
- 文档分块(chunking):把长文档切成 512-1024 token 的片段
- 向量化(embedding):用文本嵌入模型把每个片段变成向量
- 存储(indexing):把向量存入向量数据库(如 Qdrant、Pinecone、Weaviate)
- 检索(retrieval):用户提问时,把问题向量化,在向量数据库中做近似最近邻搜索
这整个管线从文档上传到可检索,通常有分钟级的延迟。而且每一步都可能出错——分块边界切断了关键信息、嵌入模型不能完美捕捉语义、向量搜索可能返回语义相似但实际不相关的片段。
特征四:更新有分钟级索引延迟。当文档内容发生变化(比如 API 接口更新),RAG 系统需要重新索引才能让变化生效。这个索引过程不是即时的——取决于文档量和索引策略,可能从几秒到几小时不等。
这是 RAG 和 Memory 在时效性上的关键差异。Memory 追求实时——你刚才说的话下次就能用到。RAG 接受延迟——你刚更新的文档可能几分钟内搜不到最新版。
特征五:内容是客观的、通用的。RAG 检索到的是”PostgreSQL 16 支持 JSON 路径表达式”这样的客观事实,对所有用户都成立。它不关心你个人用不用 PostgreSQL,它只关心”PostgreSQL 16 确实有这个特性”。
客观性的好处是可靠性——文档经过了审查,信息有据可查。但缺点是缺乏个性化——RAG 不会告诉你”你上次查过这个 API,当时返回了 404 错误”,因为这些是特定用户的经历,不是文档里的通用知识。
把这五个特征合在一起:
RAG(检索增强生成):Agent 从预先构建的外部文档库中,通过向量检索等方式获取与当前查询相关的权威知识片段,用于增强生成回答的准确性和可靠性。文档需要人工上传和索引,更新存在分钟级延迟,内容对所有用户共享。
4. 三个核心区别
理解了各自的定义,现在来看 Memory 和 RAG 之间最核心的三个区别。这三个区别决定了它们在实际系统中不能互相替代。
4.1 个性化粒度不同:per-user vs 共享知识库
这是最本质的区别。
Memory 是 per-user 的。每条记忆都绑定一个 user_id,检索时只搜索该用户的记忆空间。用户 A 说”我喜欢深色主题”和用户 B 说”我喜欢浅色主题”互不冲突——它们存在于各自的记忆空间中。
RAG 是共享知识库的。所有用户检索同一个文档库,得到相同的结果。PostgreSQL 的官方文档不会因为查询者不同而改变内容。
这意味着什么?如果你只用 RAG,你的 Agent 永远只能提供通用答案——它知道 PostgreSQL 16 的所有特性,但不知道你用的是 9.6,不知道你上周遇到过连接池耗尽的问题,不知道你对 ORM 有偏见喜欢写原生 SQL。通用答案在大多数场景下是”够用”的,但在个性化需求强的场景下(代码助手、学习伴侣、个人助理)远远不够。
反过来,如果你只用 Memory,你的 Agent 只知道你这个用户的信息,但它不知道 PostgreSQL 16 支持什么特性——这些通用知识不在你的对话历史中,而在外部文档中。一个只会”记住你说过的”但不会”查阅参考资料”的 Agent,就像一个只凭经验办事的老员工,遇到新问题时一问三不知。
错误认知:有了 RAG 就不需要 Memory,因为 RAG 能检索到所有信息。正确理解:RAG 检索到的是通用知识,不是你的个性化信息。两者解决的是不同的问题。
错误认知:有了 Memory 就不需要 RAG,因为 Agent 可以记住所有东西。正确理解:Memory 只能记住用户说过的,不能记住用户没说过但需要查阅的权威知识。
4.2 写入触发机制不同:自动提取 vs 人工上传
Memory 的写入是自动触发的。用户在对话中提到”我最近在学 Rust”,系统(或 Agent)自动提取这个事实并存储。用户不需要说”请记住我在学 Rust”——提取发生在幕后。
RAG 的写入是人工触发的。有人写好文档、上传到知识库、运行索引管线,然后才能被检索。这个过程涉及多个步骤和多个人——作者、审核者、运维人员。
这个区别带来两个重要影响。
影响一:Memory 的覆盖率取决于提取算法,RAG 的覆盖率取决于文档质量。 Memory 能记住什么,取决于提取算法能从对话中识别什么。如果用户说”我最近在用 Docker”,但提取算法没把这个信息识别为值得记住的事实,这条信息就丢了。RAG 能检索到什么,取决于文档库里有什么——如果没有人写过”Docker 网络配置最佳实践”这篇文档,你就检索不到。
影响二:Memory 的写入是持续的、低成本增量的,RAG 的写入是阶段性的、高成本批量的。 每次对话都可能产生新的 Memory——这是一种持续的、零成本的积累。而 RAG 的文档更新是项目级别的——写一篇高质量的技术文档可能需要几天甚至几周,还要经过 review 和索引。所以 Memory 天然更”新鲜”,RAG 天然更”稳定”。
这里有一个容易被忽略的陷阱:低质量文档会严重损害 RAG 的效果。如果知识库里充斥着过时的、不准确的、结构混乱的文档,检索出来的结果可能比不检索还差。这就是所谓的”garbage in, garbage out”。Memory 虽然也可能存入不准确的信息,但由于来源是对话(用户亲口说的),天然有用户的”担保”——用户自己说的偏好,至少在说出口的那一刻是准确的。
4.3 时效性要求不同:实时 vs 分钟级延迟
Memory 需要实时。用户在对话中说”我换工作了”,下一次对话中 Agent 就应该知道这个变化。如果 Memory 有分钟级甚至小时级的延迟,用户体验会严重受损——你刚告诉 Agent 你的新情况,它转头就忘了,这比”从来没有记忆”更让人沮丧。
RAG 接受分钟级延迟。一篇技术文档从更新到可检索,即使延迟几分钟甚至几小时,对大多数使用场景影响不大——因为技术文档的变更频率低(可能几天甚至几周才更新一次),而且用户通常不会在文档更新后几秒内就去查。
这种时效性要求的差异,直接影响了两个系统的架构选择。
Memory 因为需要实时,倾向于:
- 同步写入或 fire-and-forget 写入(不等索引完成就继续对话)
- 内存或低延迟存储(本地文件、SQLite、内存数据库)
- 简单的写入路径(减少管线步骤,降低出错和延迟)
RAG 因为可以接受延迟,倾向于:
- 异步批量索引(攒一批文档统一处理)
- 分布式向量数据库(支持大规模存储和复杂查询)
- 复杂的检索管线(多路召回 + 重排序 + 去重)
这又是一个”两种需求决定两种架构”的例子。如果你试图用 RAG 的架构来做 Memory,你会发现实时性不够;如果你试图用 Memory 的架构来做 RAG,你会发现检索能力和规模不够。
5. 三个重叠区域——两者容易混淆的地方
上面三个区别看起来很清晰,但在实际系统中,Memory 和 RAG 之间存在三个灰色地带,这两个概念在这里容易混淆。理解这些重叠区域,对设计系统时做出正确选择至关重要。
5.1 提炼后的事实
这是最容易引起困惑的重叠区域。
场景:Agent 在和用户的对话中,提取出一条事实——”用户使用 PostgreSQL 9.6,主从架构,写操作走主库。”这是一条 Memory,因为它来自对话、绑定特定用户。
但这条事实的本质是什么?它是一段关于 PostgreSQL 架构配置的描述性知识。如果你把 user_id 去掉,它就是一段可以放进知识库的技术信息——”某项目的数据库配置是 PostgreSQL 9.6,主从架构,写操作走主库。”这样它就变成了一条 RAG 可以检索的知识。
问题出在哪里?Memory 提取出的”事实”和 RAG 索引的”知识”在内容层面没有本质区别。区别只在于”这条信息属于谁”——如果绑定了 user_id,它是 Memory;如果放进了共享知识库,它是 RAG 知识。
这导致了一个实际问题:当 Agent 从对话中学到的事实具有通用价值时(比如”pgbouncer 可以解决 PostgreSQL 连接池耗尽问题”),应该把它存为 Memory 还是存入知识库?
- 存为 Memory:只有这个用户能看到,其他遇到同样问题的人无法受益
- 存入知识库:所有人都能检索到,但需要额外的审核和索引流程
在实践中,大多数系统选择”先存为 Memory,不主动推到知识库”——因为自动将对话内容提升为知识库条目,风险太高(可能包含错误信息、敏感信息、上下文不完整的信息)。这个”提升”动作通常需要人工介入。
但这个选择也有代价:大量有价值的经验被困在 per-user 的 Memory 空间中,无法被其他用户共享。这是目前大多数记忆系统的一个盲区。
5.2 知识图谱
知识图谱是另一个重叠区域。
Graphiti 和 cognee 都使用知识图谱作为存储结构。Graphiti 的图谱中既有从对话中提取的个性化记忆(”用户目前住在北京”),也有从文档中提炼的通用知识(”PostgreSQL 支持 JSON 路径表达式”)。cognee 的 ECL 管线处理的数据源也同时包含对话和文档。
这意味着在知识图谱的实现中,Memory 和 RAG 在存储层被统一了——它们都是图谱中的节点和边。区别不再是”存在哪里”(它们存在同一个图里),而是”这条边属于谁”(per-user 还是 shared)和”这条边从哪来”(对话提取还是文档解析)。
Graphiti 用 episodes(对话片段)作为边的来源标记,每条边都记录它是从哪段对话中提取的。cognee 用 Ontology 定义领域概念,无论数据来自对话还是文档,都映射到相同的本体论结构上。
这种统一存储的好处是:Agent 可以在一次图遍历中同时获取个性化记忆和通用知识,不需要在两个系统之间切换。代价是:隔离性变弱——如果图谱查询不当,可能把其他用户的个性化信息混入当前用户的结果。
错误认知:用了知识图谱就不需要区分 Memory 和 RAG。正确理解:知识图谱统一了存储层,但 Memory 和 RAG 的逻辑区别(per-user vs shared、自动提取 vs 人工上传、实时 vs 延迟)依然存在。统一存储不等于统一语义。
5.3 生命周期管理
第三个重叠区域是生命周期管理——过时的知识和过时的记忆都需要处理,但处理方式不同。
RAG 的过时知识:文档版本过期了,API 接口废弃了,最佳实践更新了。处理方式是”更新文档 + 重新索引”——这是一个人工驱动的、可审计的过程。你知道哪个文档在什么时候被谁更新了。
Memory 的过时记忆:用户换工作了,技术栈变了,偏好改变了。处理方式更复杂——可能是用户显式告知(”我不再用 React 了”),可能是系统检测到矛盾信息后自动更新,也可能是记忆随时间衰减而逐渐被遗忘。
两种生命周期管理面临的挑战是相似的:都需要检测过时、都需要处理矛盾、都需要在不丢失有用信息的前提下去除不再适用的内容。但 RAG 的生命周期管理更”工程化”(有版本控制、有审批流程),Memory 的生命周期管理更”智能化”(需要 LLM 判断、需要推理矛盾)。
这个重叠区域的实际影响是:如果你同时有 Memory 和 RAG 系统,你可能会遇到这样的问题——Memory 说”用户用 PostgreSQL”,但 RAG 知识库中有一篇新文档说”项目已迁移到 MySQL”。哪个是最新?谁优先?
答案取决于具体情况:如果 Memory 是最近一次对话中更新的,应该优先(用户亲口说的比文档更可信)。但如果 Memory 是三个月前的,而 RAG 文档是昨天更新的,可能应该优先 RAG。大多数系统目前没有处理这种”Memory-RAG 矛盾”的机制——这是一个开放问题。
6. 互补关系:最佳实践是两者配合
讲完区别和重叠,现在来讲最重要的结论:Memory 和 RAG 不能互相替代,最佳实践是两者配合。
6.1 为什么不能只用 Memory
只用 Memory 的 Agent 像一个只凭经验办事的老员工——他记得你说过的话,但不查参考资料。当你问”PostgreSQL 16 有什么新特性”时,他只能根据之前对话中提到过的信息回答。如果之前没聊过这个话题,他要么承认不知道,要么根据旧信息猜测——两种都不是好结果。
只用 Memory 的具体问题:
- 知识上限是用户的对话历史:如果用户从未在对话中提到某个知识点,Agent 就不可能”记住”它
- 无法验证事实准确性:用户可能说错(”PostgreSQL 是 NoSQL 数据库”),Memory 会忠实记录这个错误
- 缺乏权威参考:当用户需要可引用的权威信息时,Memory 中的信息不够”正式”
6.2 为什么不能只用 RAG
只用 RAG 的 Agent 像一个只查文档的实习生——他什么资料都能找到,但完全不了解你。每次你都需要重新告诉他你的项目背景、技术偏好、之前踩过的坑。文档是全面的,但不针对你个人。
只用 RAG 的具体问题:
- 无法个性化:所有用户得到相同的答案,没有”我知道你在做什么”的上下文
- 无法记住历史:你上周遇到的那个 bug、你上次确认的技术决策——这些不在文档里,只在你和 Agent 的对话历史中
- 检索效率低:如果每次都需要从知识库中重新检索基础信息(比如”你用什么数据库”),既浪费计算又浪费时间
6.3 最佳实践:Memory 提供个性化上下文,RAG 提供权威知识
理想的 Agent 应该像一位既了解你又能查资料的高级工程师——他记住了你的偏好和历史(Memory),同时在需要时查阅最新的技术文档(RAG)。
具体协作方式:
场景一:代码助手
- Memory:”用户偏好 Python,使用 FastAPI 框架,项目用 PostgreSQL,代码风格遵循 Black 格式化”
- RAG:FastAPI 的 API 文档、PostgreSQL 的查询语法手册、最新版本的变更日志
- 协作:Agent 用 Memory 知道你的偏好,用 RAG 查阅最新的 API 用法,生成的代码既符合你的风格又保证正确性
场景二:技术支持
- Memory:”用户上次遇到的问题是通过 pgbouncer 解决的连接池耗尽”
- RAG:PostgreSQL 连接池的官方配置指南、pgbouncer 的最新版本说明
- 协作:Agent 用 Memory 了解你的历史和上下文,用 RAG 提供权威的配置建议
场景三:学习伴侣
- Memory:”用户正在学 Rust,已经理解了所有权和借用,目前在看生命周期”
- RAG:Rust Book 中关于生命周期的章节、常见的生命周期陷阱
- 协作:Agent 用 Memory 知道你的学习进度和已掌握的概念,用 RAG 提供结构化的学习材料
在每一个场景中,Memory 解决”了解你”的问题,RAG 解决”查资料”的问题。两者缺一不可。
7. 腾讯生态中的体现:DB-Agent-Memory 与 WeKnora
理论讲完了,来看一个具体的生态案例。
在腾讯的技术生态中,DB-Agent-Memory 做记忆,WeKnora 做 RAG。它们在功能定位上互补,但在”提炼后的事实”这个重叠区域存在需要处理的问题。
7.1 DB-Agent-Memory 的记忆角色
DB-Agent-Memory 是腾讯出品的四层金字塔记忆引擎,核心职责是从 Agent 与用户的交互中提取和存储个性化信息。它的四层结构是:
- Observation 层:原始对话片段(类似情景记忆)
- Fact 层:从对话中提炼的独立事实(”用户使用 PostgreSQL 9.6”)
- Summary 层:按主题聚合的摘要(”用户的数据库架构偏好”)
- Profile 层:用户画像级别的核心偏好(”用户是后端工程师,偏好 Python + PostgreSQL 技术栈”)
这个结构天然是为 Memory 设计的——每一层都是 per-user 的个性化信息,来源都是对话交互。
7.2 WeKnora 的 RAG 角色
WeKnora 是腾讯内部的知识图谱平台,核心职责是构建和维护企业的知识图谱。它提供知识的检索和推理能力,支持从非结构化文档中自动抽取实体和关系,构建结构化的知识图谱。
WeKnora 的定位是 RAG——它处理的是文档和知识,来源是人工上传的各类企业文档,粒度是企业级共享的知识库,更新需要经过索引管线。
7.3 重叠区域的问题
问题出在 DB-Agent-Memory 的 Fact 层和 Summary 层。
当 Agent 从对话中提取出一条事实——比如”项目 X 已从 PostgreSQL 迁移到 MySQL”——这条信息在 DB-Agent-Memory 中是 Memory(per-user,来源是对话)。但这条信息本质上是一条关于项目状态的知识——如果把它放进 WeKnora 的知识图谱中,其他查询”项目 X 数据库”的人也能受益。
这就是前面说的”提炼后的事实”重叠区域。在腾讯生态中,这个重叠带来了两个具体问题。
问题一:信息孤岛。Agent 从对话中学到的项目事实被锁定在 per-user 的 Memory 空间中。其他服务同一个项目的 Agent(或其他用户的 Agent)无法共享这条信息。如果你和同事分别在不同对话中向各自的 Agent 提到了项目迁移的事,两条 Memory 分别存储,互不知道对方也存在同样的信息。
问题二:Memory-RAG 矛盾。更棘手的情况是矛盾。假设 Agent 在一个月前的对话中记住了”项目 X 使用 PostgreSQL”(Memory),但上周 WeKnora 知识图谱中更新了一条”项目 X 已迁移到 MySQL”(RAG)。现在 Agent 同时面临两条信息:
- Memory:”用户使用 PostgreSQL”(一个月前,来自对话)
- RAG:”项目使用 MySQL”(一周前,来自知识图谱)
哪个正确?如果 Agent 只用 Memory,它会继续按 PostgreSQL 做事。如果 Agent 只用 RAG,它不知道用户个人的角色和偏好。如果两者都用,需要一个冲突解决机制——但目前大多数系统(包括 DB-Agent-Memory)没有显式的 Memory-RAG 矛盾处理。
可能的解决方向:
- 在 Fact 层添加时间戳和来源标记,让 Agent 能判断”这条记忆多新、来源是什么”
- 当 Memory 和 RAG 返回矛盾信息时,由 LLM 做最终仲裁(但这增加了 LLM 调用成本和延迟)
- 为项目级事实建立”共享记忆”空间——介于 per-user Memory 和全局 RAG 之间的中间层,让同一项目的 Agent 可以共享项目级上下文
这些方向目前都还在探索阶段,没有成熟的工业实践。这也是为什么理解 Memory 和 RAG 的区别与重叠如此重要——如果你在设计一个同时使用两者的系统,你必须提前想好这些冲突场景。
8. 一个对比总结表
把 Memory 和 RAG 的核心区别整理成一张表,方便查阅和复习。
| 维度 | Memory | RAG |
|---|---|---|
| 核心定义 | 从交互中自动学到的个性化信息 | 从外部文档中检索的权威知识 |
| 来源 | 对话(实时交互) | 文档(人工上传) |
| 粒度 | per-user(每用户独立) | 共享知识库(所有用户共享) |
| 写入触发 | 自动(系统/Agent 提取) | 人工(上传 + 索引) |
| 更新延迟 | 实时(当前或下次对话生效) | 分钟级(索引管线延迟) |
| 内容性质 | 主观的、情境的、个性化的 | 客观的、通用的、权威的 |
| 过时处理 | 隐式失效检测 + 矛盾更新 | 文档版本管理 + 重新索引 |
| 典型代表 | mem0 / DB-Agent-Memory / Claude Code | WeKnora / Confluence + 向量检索 |
| 解决的问题 | “了解你”——个性化、上下文、历史 | “查资料”——权威、准确、全面 |
| 不能替代对方的原因 | 无法提供用户没说过的通用知识 | 无法提供个性化的偏好和历史 |
9. 本章小结
回顾本章的核心要点:
- Memory 和 RAG 解决的是不同的问题:Memory 解决”了解你”,RAG 解决”查资料”
- 三个核心区别:个性化粒度不同(per-user vs 共享)、写入触发不同(自动 vs 人工)、时效性不同(实时 vs 分钟级延迟)
- 三个重叠区域容易混淆:提炼后的事实(Memory 中的事实可能具有通用价值)、知识图谱(Graphiti/cognee 在存储层统一了两者)、生命周期管理(两者都需要处理过时信息但方式不同)
- 互补关系不可替代:Memory 提供个性化上下文,RAG 提供权威知识,最佳实践是两者配合
- 腾讯生态中的体现:DB-Agent-Memory 做记忆,WeKnora 做 RAG,两者在”提炼后的事实”区域存在重叠,可能产生 Memory-RAG 矛盾
- 核心结论:经验和知识不是一回事——经验告诉你”这个人怎么样”,知识告诉你”这件事怎么样”,两者都需要但不能混为一谈
下一章我们从”Memory 和 RAG 的区别”转向”记忆系统本身的设计约束”——存什么、怎么存、何时忘,这是每个记忆系统都必须回答的五个问题。
导读目录:README.md 上一章:Ch05: Profile vs User Memory——写给 Agent 的 vs Agent 自己学的 下一章:Ch07: 记忆系统的设计约束——存什么、怎么存、何时忘