ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

RAG与Memory的区别与选型指南:Agent开发中的知识检索与状态记忆

RAG与Memory的区别与选型指南:Agent开发中的知识检索与状态记忆 RAG 和 Memory 是 Agent 开发里最容易被混在一起的两个概念。很多人做知识库问答时第一反应是我用了 RAG是不是就不需要 Memory 了也有人反过来把会话历史一股脑拼进系统提示词然后说这就是 Memory。先说结论这两个东西解决的问题根本不一样。RAG 解决的是“Agent 不知道外部知识”的问题Memory 解决的是“Agent 记不住刚才说过什么、做过什么、用户偏好是什么”的问题。它们可以配合但不能互相替代。这篇文章适合正在选型 Agent 框架、准备做知识库问答、或者想优化多轮对话体验的开发者。我会先帮你分清这两个概念再给一套实际可用的选型判断路径最后说落地时最容易踩的坑。重点不是堆功能而是让你能在自己的场景里判断现在该加 RAG该加 Memory还是两个都加。1. 先分清问题RAG 解决“信息缺失”Memory 解决“状态遗忘”1.1 RAG 的本质是给 Agent 装一个可检索的外部知识库RAG 全称是 Retrieval-Augmented Generation检索增强生成。它的核心思路不是把知识写进模型参数而是先从外部文档里检索出和用户问题相关的片段再把片段作为上下文交给语言模型让模型基于这些片段生成回答。典型场景是企业内部文档问答、产品手册查询、法律法规检索、学术论文阅读。这些内容要么不在模型训练数据里要么更新很快。比如你的产品上周刚改了价格模型知识还停留在半年前这时候就算模型本身很聪明它也会答错。RAG 的价值就在于把答案的“依据”从模型内部搬到外部知识库每次回答前先查最新文档。所以判断一个场景要不要用 RAG可以问自己一个问题用户问题的答案是否需要依赖某个具体文档里的准确信息如果需要那就要考虑 RAG。如果只是常识性问答模型本身就能回答没有必要上来就做一套检索链路。RAG 的关键组件包括文档加载、切块、向量化、向量存储、检索、重排序、生成。每一步都有参数要调后面我会专门讲。1.2 Memory 的本质是让 Agent 记住交互历史和状态Memory 关注的是时间维度的信息。它包含短期的会话上下文也包含长期的用户画像、偏好和任务状态。举几个具体例子用户上一轮说了“我要订明天早上九点的会议室”这一轮说“改到十点”Agent 需要知道“这间会议室”指的是哪一间。用户连续问了五个问题最后说“结合前面几条给我一个总结”Agent 不能只看到最后一句话。用户已经在系统里绑定过企业 ID 和部门Agent 在后续回答中应该默认记住而不是每次重新问。这些都是 Memory 的职责。实现方式也很多样把最近几轮对话拼进系统提示词、用摘要压缩历史、用向量库存记忆条目、用外部数据库记录用户属性或者用专门的记忆模块。判断场景是否需要 Memory 同样可以问一个问题用户问题的答案是否依赖刚才聊过的内容或者用户长期信息如果是就需要 Memory。光靠 RAG 检索外部文档是不够的因为外部文档里没有“用户刚刚说过什么”这个信息。1.3 最容易出现的误区把 RAG 和 Memory 混着用我在实际项目里见过两种典型误区。第一种把 RAG 库当成 Memory 用。有人把历史对话也切块存进向量库用户提问时同时检索文档和历史。这么做不是完全不行但很容易失控。历史对话噪声多相关性不稳定检索出来的片段可能互相矛盾而且会快速消耗上下文空间。更关键的问题是历史对话里的很多信息根本不需要向量化比如“用户刚说了 OK”这句话没有知识价值存进向量库只会干扰检索。第二种把 Memory 当成 RAG 用。有人为了省事把产品文档全文塞进记忆模块每次请求都把文档拼进提示词。如果文档很短还能凑合文档一长很快超过上下文窗口模型反而抓不住重点延迟也上去了。正确思路应该是RAG 的检索对象是稳定的知识型内容Memory 的检索对象是动态的交互状态和用户事实。两者可以在同一个 Agent 里共存但定位完全不同。2. 从 Agent 工作流程看 RAG 和 Memory 到底放在哪个环节2.1 Agent 的典型执行循环一个 Agent 执行任务时通常会经历这样的循环接收用户输入结合上下文和记忆判断是否需要外部知识调用工具或检索生成回复最后更新记忆。在这个循环里Memory 是贯穿始终的。Agent 每一次做出决策都需要知道当前处于什么状态而 RAG 通常是在“需要外部知识”这个节点触发不是每次提问都要走一遍检索。用伪代码表示会更容易理解user_input receive() context memory.build_context(user_id, session_id) if need_external_knowledge(user_input): docs rag.retrieve(user_input) context docs response llm.generate(user_input, context) memory.save(user_id, session_id, user_input, response)这里 Memory 负责提供背景RAG 负责补充检索片段。两者都拼进上下文但来源不同用途也不同。2.2 Memory 在整个会话中的角色Memory 在系统中通常分成短期记忆和长期记忆两层。短期记忆主要保存当前会话的对话轮次、工具调用结果、临时变量。它的特点是时效性强但也容易被新消息覆盖。实现时最常用的是维护一个消息列表每次请求把最近 N 轮拼进提示词。N 一般由上下文窗口、模型能力和成本共同决定。长期记忆则保存跨会话的稳定信息。比如用户姓名、公司、偏好、历史订单、订阅状态。这类信息往往需要结构化存储或者以记忆条目的形式写入独立数据库。长期记忆要注意一个问题用户偏好会变化。不能把用户半年前的选择当成永远不变的偏好需要给记忆条目加时间戳或者版本。配置 Memory 时常见的参数有会话 ID、保留最近对话轮数、摘要触发阈值、记忆写入条件。不同框架参数名不一样但你要关心的核心问题是这些信息应该在什么时候写入什么时候被清理。2.3 RAG 在任务中的触发时机RAG 不是每次用户提问都要触发。如果用户只是在闲聊或者问题本身在模型知识范围内走 RAG 反而增加延迟和噪声。比较常见的做法是增加一个路由判断先判断用户问题是否需要外部知识。可以用规则、分类器也可以让模型自己决定。比如“查一下最新的政策文件”明显需要走检索“帮我写一段欢迎语”通常不需要。一旦确定要走 RAG流程一般是这样理解用户问题必要时扩展成多个子查询。对查询做向量化。在向量库中检索最相似的片段。对结果做重排序把真正相关的排名提前。把筛选后的片段拼接到提示词中。让模型基于片段生成答案并尽量给出引用来源。整个过程里切块策略对效果影响最大。固定长度切块简单但容易把语义切断按段落和标题切块更合理但不同文档结构差异很大。常见做法是先用文档结构粗切再对特别大的块做二次切分。3. 到底怎么选先回答五个关键问题再看决策表3.1 选型之前先问自己五个问题与其直接问“RAG 和 Memory 用哪个”不如先把场景拆开。我一般会先回答这五个问题用户的问题是否依赖外部文档或实时数据用户的问题是否依赖刚才的对话历史或用户长期信息外部知识的更新频率高不高当前模型的上下文窗口能容纳多少内容你更在意回答准确率还是更在意交互的连续性和个性化第一个问题指向 RAG第二个问题指向 Memory第三个问题决定你要不要做文档同步第四个问题影响你的方案复杂度第五个问题决定你的优化优先级。举个例子。一个产品手册问答机器人用户的问题大多数依赖外部文档但是单轮问答为主连续追问的情况很少。这种情况 RAG 优先Memory 只需要保留很浅的会话历史就够了。另一个例子。一个招聘助手用户会连续交流自己的经历、求职意向、薪资期望。这些信息不是外部文档里的知识而是用户动态提供的状态。这种情况 Memory 优先RAG 只在需要查询岗位信息时触发。3.2 一张表帮你快速选型场景推荐方案说明产品文档问答RAG 优先Memory 辅助答案依赖文档知识需要及时更新多轮对话中的个性化推荐Memory 优先RAG 按需需要记住用户偏好商品库查询适合走 RAGAgent 执行复杂任务两者结合Memory 记录任务状态RAG 检索操作手册或规则客服机器人两者结合Memory 保存用户订单和上下文RAG 检索政策文档纯闲聊机器人只上 Memory不需要外部知识重点在上下文连贯单轮知识问答只上 RAG没有跨轮依赖Memory 成本可以省掉这张表是经验判断不是绝对规则。如果你的场景比较特殊按照自己的数据分布来调整。3.3 两种常见组合模式除了上面这种表格我再给你一个更简单的版本。极简模式只使用 Memory加上模型自带知识。适合简单客服、闲聊、任务型对话。优点是开发成本低缺点是没有私有知识时模型容易编造答案。知识库模式只使用 RAG做单轮问答。适合文档检索场景比如搜政策、搜手册。优点是不用维护复杂历史缺点是连续追问效果很差用户问“刚才说的那个条款呢”模型根本不知道。混合模式RAG 和 Memory 一起用。这是真实 Agent 场景中最常见的选择。Agent 既需要私有知识又需要跨轮状态。混合模式不等于把所有功能堆一起而是让两条链路各司其职。这里有一个很容易被忽视的判断不要看到一个 Agent 框架自带 RAG 和 Memory 模块就以为两个都用一定更好。如果场景真的只需要文档检索强行加 Memory 反而会让问题复杂化。选型的第一步永远是看需求而不是看功能列表。4. 实际落地先从最小例子跑通再做混合方案4.1 环境准备动手之前先确认你的运行环境。不用一步到位但下面几个条件要尽量提前准备好。语言和框架Python 生态下常用 LangChain、LlamaIndex也可以自己用 FastAPI 搭接口。如果用的是 Dify、Spring AI 这类框架模块会更多一些但核心思路一致。向量库常见选择有 Qdrant、Chroma、Milvus、pgvector。学习阶段用 Chroma 最轻量生产环境再考虑 Qdrant 或 Milvus。嵌入模型和语言模型可以调云端 API也可以用本地模型。本地模型要额外关注显存和内存如果机器配置不高先把模型体积选小一点。输入输出格式明确你要处理的是 txt、Markdown、PDF 还是 Word 文档以及对话结果的返回格式。注意原始材料里没有给出版本号落地时请先确认你所用的框架和依赖版本。不同版本的 API 变化很大不要拿旧教程直接套。4.2 先跑通纯 RAG 的最小样例我建议不要一上来就做混合方案。先把 RAG 单条链路跑通再考虑 Memory。最小步骤是加载一个文档比如一份产品说明的 txt 文件。按长度切片比如每块 500 字符重叠 50 字符。调用嵌入模型把每个切片转成向量。把向量存入向量库。输入一个测试问题检索相似片段。把片段拼进提示词让模型生成回答。# 伪代码示例实际参数以你的环境为准 chunks split_text(text, chunk_size500, chunk_overlap50) embeddings embed_model.encode(chunks) vector_store.add(chunks, embeddings) question 这个产品的价格调整政策是什么 results vector_store.search(question, top_k3) prompt f基于以下资料回答\n{results}\n问题{question} answer llm.invoke(prompt)跑通之后先验证三件事检索结果是否相关回答是否基于检索片段以及会不会出现“编造文档中没有的内容”。如果回答看起来像模型在自由发挥说明提示词约束不够或者检索片段根本没有被模型认真使用。4.3 再跑通 Memory 的最小会话RAG 稳定之后再单独加 Memory。最简单的做法就是维护一个消息列表每次请求把最近几轮拼进提示词。messages memory.get_recent(session_id, max_turns10) user_input 我叫张三 prompt build_prompt(messages, user_input) answer llm.invoke(prompt) memory.add(session_id, user_input, answer)测试时用一组连续问题先问“我叫张三”再问“我叫什么”最后问“我刚才说了什么”。如果模型都能回答说明最小会话记忆是通的。这里先不要急着做摘要。先用原始消息跑通观察上下文长度对回答质量的影响再决定要不要把早期消息压缩成摘要。摘要会省 token但也会丢失细节需要权衡。4.4 混合后的最小流程两条链路都稳定后再合并成一个流程# 伪代码示例 messages memory.get_recent(session_id) if should_use_rag(question): docs rag.search(question) context format_docs(docs) format_messages(messages) else: context format_messages(messages) answer llm.invoke(question, context) memory.add(session_id, question, answer)这已经是一个非常够用的混合方案。它没有复杂的路由模型没有长期用户画像但能覆盖大部分场景有知识时检索文档有历史时参考历史两者都满足时一起用。4.5 判断标准混合方案跑起来之后不要只看“能回答”就结束还要盯几个指标单条响应延迟。如果响应变慢优先看检索耗时和上下文长度。检索命中质量。随机抽 20 个问题看检索结果是否真的覆盖答案。上下文占用。连续对话到第 10 轮后提示词占了多少 token如果超过模型窗口的 80%就要做摘要或限制轮数。是否重复引用同一段文档。如果 top_k 里三块内容高度重复说明切块重叠太多需要调整。记忆是否准确。用户上一轮说的事情这一轮是否被正确复用。5. 混合使用时的架构要点和常见坑5.1 Memory 和 RAG 不要抢同一块上下文混合方案最常出的问题不是功能不够而是上下文不够用。RAG 检索出来的片段可能很长Memory 里又有十几轮历史。两者都塞进提示词之后二十分钟过去模型看到的大部分内容都是历史对话和检索片段反而找不到当前用户问题在哪。解决思路是给上下文做一个预算。比如模型上下文窗口是 8000 token你可以规定RAG 片段最多占 3000Memory 最多占 2500留给模型发挥的空间至少 2000。比例不一定固定但一定要有预算意识。Memory 侧可以压缩最近 2-3 轮保留原始消息更早的用摘要代替。RAG 侧可以限制top_k 设成 3 或 5每段长度通过切块参数控制。不要以为检索出 10 块都有用很多时候 3 块高质量片段比 10 块噪声更有价值。5.2 记忆的写入和清理记忆不是存得越多越好。把所有对话原样存下来很快会把存储和上下文都拖垮。写入策略上我会优先保存有状态价值的信息。比如用户明确说过“我偏好某个品牌”“我下周要出差”“我已经完成了第一步”这些信息值得写入记忆。而“好的”“嗯”“谢谢”这类消息价值很低不写反而更干净。清理策略同样重要。长期记忆里要给每条记录加时间戳当用户说“我改主意了”时新记录要能覆盖旧记录而不是让模型同时看到矛盾信息。会话记忆里超过最大轮数的消息要么丢弃要么摘要不能无限累积。5.3 RAG 检索质量和切块策略RAG 最容易翻车的点不是模型而是文档加载和切块。常见问题包括PDF 里表格提取后乱掉、页眉页脚成为噪声、扫描件没有 OCR、文档编码不是 UTF-8。这些都会让后续检索质量大打折扣。处理文档时先人工抽查几个片段别急着全部灌进向量库。切块也不是只看字符数。固定长度切块最容易把一句话切成两半导致检索结果语义不完整。更好的办法是按标题、段落、列表先拆分再对超大块二次切分。切块长度和重叠率是互相影响的一般先设 500-800 字符、10% 重叠再根据检索结果调整。另一个容易忽略的点是引用溯源。企业级 RAG 不能只给答案还要能说明答案来自哪份文档的哪一段。否则答错了没法排查用户也不敢采信。热词里提到的“RAG 的引用溯源与 groundedness”就是这个意思。5.4 混合方案排查链路混合方案出了问题时按这个顺序排查不要一上来就怀疑模型能力。回答像没读过文档先看检索片段是否相关。如果片段本来就不对模型再强也答不对。连续对话答错先看 Memory 是否覆盖了关键信息。有时候是保存了但模型没有用上有时候是根本没保存。提示词超长或响应很慢先看上下文预算、检索片段数量、历史轮数。超长通常不是模型问题是策略问题。回答前后矛盾先看 Memory 里的旧信息和新信息是否冲突有没有清理机制。RAG 命中但生成乱编先看提示词是否明确要求“只能基于资料回答”并且允许模型在资料不足时说不知道。5.5 值得关注的进阶方向如果你已经跑通了基础的 RAG Memory下一步可以关注几个更细的方向。Agentic RAG 是一个思路不让每次请求都固定走检索流程而是让 Agent 自己判断什么时候需要调用检索工具。这样能减少无效检索节省成本和时间。Memory Channel 也是一种参考把记忆拆分成不同通道比如会话记忆、实体记忆、任务记忆。每个通道存不同类型的信息检索时按需取用。对复杂 Agent 场景来说比单一大列表更稳定。还可以考虑加入知识图谱或 MCP 这类外部模块但前提是你的基础链路已经稳定。否则一次堆太多功能出了问题很难定位。我的建议是先跑通最小闭环再逐步加能力。6. 几个可以直接拿去用的选型经验6.1 先区分“知识”和“状态”这是整个选型最核心的一句话。如果信息是一个事实比如“发货政策是 24 小时内”“这座城市的面积是 1000 平方公里”往 RAG 方向走。 如果信息是动态状态比如“用户刚刚选择了 5 号商品”“用户当前登录的是企业账号”往 Memory 方向走。 如果一个信息既有知识属性又有状态属性比如用户选择的产品型号是动态状态而该型号的官方技术参数是外部知识就要拆成两段处理状态放 Memory技术参数走 RAG。6.2 不要一开始就追求大而全很多 AI Agent 框架自带 Memory 和 RAG 模块默认配置不一定适合你的场景。我见过不少团队上来就配置了长期记忆、向量数据库、重排序、多轮摘要、工具调用结果系统看起来能力很强但用户随便问几个问题就开始乱答。原因就是链路太长任何一个环节的噪声都会被放大。更稳的做法是先用最简单的方式跑通一个列表存历史一个向量库查文档。验证核心链路之后再逐步加摘要、重排序、权限控制。6.3 用问题反推方案我不太推荐先选框架再想场景。反过来先收集真实用户问题再做分类会更靠谱。把用户问题分成四类事实查询答案能在外部文档里找到典型如“这个品类的退货标准是什么”。这类走 RAG。连续追问答案依赖上一轮语气和上下文典型如“刚才说的那个方案预算改成 2 万怎么调整”。这类走 Memory。任务执行需要 Agent 记住步骤和状态同时可能要查操作手册。这类 RAG Memory 都要。个性化推荐需要记住用户偏好同时检索内容库。这类也是混合方案。分类之后你会发现很多场景其实只需要其中一个不需要一上来就把所有能力全开。6.4 一定要留可观测性混合方案最怕“看起来能用但出了问题不知道从哪里排查”。我建议每个请求都记录三份信息这次有没有触发 RAG检索了哪些片段命中分数多少Memory 带了哪些历史是否做了摘要最终模型生成了什么答案有没有引用来源。这些日志存在本地文件或数据库里都可以关键是别省略。有了日志你才能判断回答错误是检索问题、记忆问题还是模型问题。否则用户反馈一句“你回答错了”你连从哪里开始查都不知道。我个人更建议把项目拆成两个阶段第一阶段跑通单文档 RAG 加会话 Memory确认两条链路都稳定第二阶段再做路由、摘要、长期记忆和更复杂的 Agentic RAG。不要一开始就把所有高级概念都堆上去。很多问题不是工具能力不够而是前置环境和输入材料没有处理干净。先把基础链路做扎实后面加什么功能都更容易判断值不值。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表