news 2026/9/28 3:47:03

Agent记忆与RAG对比学习笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent记忆与RAG对比学习笔记

Agent :记忆与 RAG的区别与联系

适用读者:正在学习 / 开发 LLM Agent、RAG 系统的工程师。本文从概念、对比、存储底座、代码实现、优化手段五个层面,把 Agent 记忆(Memory)与 RAG 的关系讲透。


目录

  1. 为什么 Agent 需要 “记忆” 和 “检索”

  2. 概念基础:RAG 与 Agent 记忆

  3. 核心区别:一张表 + 六个维度

  4. 共同联系:数据库是两者的底座

  5. 记忆的实现方式(含完整代码)

  6. 记忆与 RAG 的优化手段

  7. 落地架构:记忆 + RAG + Agent 如何配合

  8. 总结与常见误区


一、为什么 Agent 需要 “记忆” 和 “检索”

大语言模型本身有三个天然缺陷:

  1. 上下文有限:GPT 类模型的上下文窗口再大也有上限,长对话必然溢出;

  2. 知识静态:模型训练完成后知识就冻结了,无法知道训练截止日之后的新事实;

  3. 无状态:模型是 “一次性” 的 —— 每次调用都是独立函数,不记得上一轮说过什么。

RAG 和 Agent 记忆分别补上了两块短板:

缺陷对应解法作用
知识静态、可能过时RAG(检索增强生成)把外部知识库实时检索出来,注入 Prompt
无状态、上下文有限Agent 记忆(Memory)把对话历史、用户偏好、状态持久化,跨轮 / 跨会话复用

一句话概括:

RAG 解决 “模型不知道” 的问题,记忆解决 “模型不记得” 的问题。


二、概念基础:RAG 与 Agent 记忆

2.1 RAG:检索增强生成

RAG(Retrieval-Augmented Generation)在生成前先检索外部知识,把检索结果拼进 Prompt,再让模型基于这些材料回答。

\[文档库] ──▶ \[切分 Chunk] ──▶ \[Embedding 向量化] ──▶ (向量数据库)   ▲ \[用户问题] ──▶ \[Query Embedding] ────────────────────────────┘   ▼   \[相似度检索 Top-K] ──▶ \[注入 Prompt] ──▶ \[LLM 生成回答]

典型流程:

  1. 离线索引:文档 → 切分(chunk)→ 向量化(embedding)→ 写入向量数据库;

  2. 在线检索:用户问题 → 向量化 → 在向量库中找最相似的 Top-K 片段;

  3. 生成:检索结果 + 问题 + 指令拼成 Prompt → LLM 输出。

特点:知识来源是外部静态文档,可实时更新(重新索引)、可溯源(引用原文)、无需训练模型。

2.2 Agent 记忆:状态的持久化

Agent 记忆把 “这个用户是谁、之前聊了什么、任务做到哪一步” 等运行时状态存下来,让 Agent 表现出连续性和个性化。

学术界把记忆分为四类(参考认知科学对记忆的划分):

记忆类型英文含义存储形态
短期记忆Short-term / Working Memory当前会话内上下文、任务中间状态上下文列表、缓存
情景记忆Episodic Memory发生过的事件(“上周帮用户改过合同”)事件日志、向量库
语义记忆Semantic Memory沉淀出的事实与偏好(“用户是律师”)键值表、向量库
程序性记忆Procedural Memory技能 / 工具使用流程代码、Prompt 模板、工具描述

特点:数据来源是交互过程本身,动态写入、持续演化、高度个性化。


三、核心区别:一张表 + 六个维度

3.1 对比总表

维度RAG(检索增强生成)Agent 记忆(Memory)
要解决的问题模型知识不足 / 过时模型无状态 / 不连续
数据来源外部知识库:文档、网页、数据库记录交互历史:对话、行为、反馈、状态
写入方式批量索引(离线 / 定时),静态实时增量写入,随对话演化
读取方式每次问答都检索外部知识按需召回,常与短期上下文拼接
数据粒度文档块(chunk),面向 “知识”事件 / 事实 / 偏好 / 状态,面向 “个体”
时效性知识更新依赖重新索引天然反映最新交互
个性化程度低(同一知识库对所有用户一致)高(记忆是用户专属的)
可溯源强(可引用原文出处)弱(记忆是加工后的摘要 / 事实)
生命周期知识库常驻,随文档更新随用户关系长期演化,可遗忘可沉淀
典型存储向量数据库为主向量库 + 关系库 + KV + 图库组合

3.2 六个关键差异点详解

差异一:回答的是不同问题

  • RAG:给模型喂 “知识”(What)。

  • 记忆:给模型喂 “经历”(Who / When / How)。

差异二:数据的写路径不同

  • RAG 是 “一次索引、多次读取”,写操作低频;

  • 记忆是 “每轮对话都在写”,写操作高频且需要去重、冲突解决。

差异三:召回策略不同

  • RAG 是 “必检”:每轮都检索知识库(除非命中缓存);

  • 记忆是 “按需”:需要时才从长期记忆召回,日常对话主要用短期上下文。

差异四:个性化程度

  • 同一个 RAG 知识库,服务所有用户,答案一致;

  • 记忆严格按用户隔离,是 “千人千面” 的来源。

差异五:遗忘机制

  • RAG 靠删除文档 / 重新索引实现 “遗忘”;

  • 记忆需要专门的遗忘策略(过期、重要性评分、用户主动删除)。

差异六:失败模式

  • RAG 失败:检索不到相关内容 → 幻觉风险;

  • 记忆失败:召回错误记忆 → 答非所问或泄露历史信息。

3.3 两者不能互相替代

  • RAG 替代不了记忆:RAG 不知道 “用户上次聊到哪了”,无法跨轮保持上下文。

  • 记忆替代不了 RAG:记忆是交互产物,装不下企业知识库;把公司全部文档写进记忆既贵又不可维护。

  • 正确姿势是组合:短期记忆承载当前对话,长期记忆承载个性化,RAG 承载外部知识。

\[用户] ──▶ \[Agent 主循环] ──┬──▶ \[短期记忆:当前会话]   ├──▶ \[长期记忆:用户画像/历史]   └──▶ \[RAG:外部知识检索]   │   ▼   \[Prompt 组装] ──▶ \[LLM] ──▶ \[输出(并回写记忆)]

四、共同联系:数据库是两者的底座

RAG 和记忆的 “殊途同归” 点在于:它们都是 “读数据库 → 拼 Prompt → 生成” 的模式,区别只是存了什么、怎么索引。

4.1 共同的架构位置

┌─────────────── 数据层:各类数据库 ───────────────┐ │ │ │ 向量数据库 关系型数据库 键值/缓存 图数据库 │ │ Chroma/FAISS MySQL/PG Redis Neo4j │ │ Milvus/pgvector │ │ │ │ 对象存储:原始文档 / 历史归档(S3、MinIO) │ │ │ └──────────────────────┬───────────────────────────┘   │   ┌────────────┴────────────┐   ▼ ▼   \[RAG 管道] \[Agent 记忆层]

4.2 数据库选型对照表

数据库类型代表产品RAG 中承担的角色记忆中承担的角色
向量数据库Chroma、FAISS、Milvus、Qdrant、Pinecone、pgvector存文档 chunk 的 embedding,做相似度检索存历史对话 / 事件 / 事实的 embedding,做语义召回
关系型数据库PostgreSQL、MySQL、SQLite存文档元数据、chunk 归属、权限存用户表、偏好表、状态表、结构化事件
键值 / 缓存Redis检索结果缓存、embedding 缓存短期记忆、会话状态、TTL 自动过期
图数据库Neo4j、NebulaGraph知识图谱增强检索(实体关系)实体关系记忆(“用户 A 与项目 B 的关系”)
对象存储S3、MinIO原始文档归档长音频 / 图片等非结构化历史

4.3 关键点:为什么 “向量数据库” 是交集

两者都需要语义检索,所以向量数据库成为最大交集:

  • RAG:query_embeddingvsdocument_chunk_embedding

  • 记忆:query_embeddingvsmemory_item_embedding

两者共用同一套 “Embedding → 近似最近邻(ANN)检索” 技术栈。这也是为什么很多框架(LangChain、LlamaIndex)里 RAG 检索器和记忆检索器的 API 几乎一样。


五、记忆的实现方式(含完整代码)

下面从简到繁给出 5 种记忆实现,代码基于 Python,依赖openai(或任何兼容接口)、chromadb、sqlite3。所有代码是可直接运行的骨架,换掉 embedding 和 LLM 客户端即可上生产。

5.1 短期记忆:上下文窗口管理(最基础)

短期记忆的核心是 “放得下”—— 用 token 预算管理上下文,超出就丢最老的。

"""短期记忆:带 Token 预算的滑动窗口上下文管理""" class ShortTermMemory:   def \_\_init\_\_(self, max\_tokens: int = 4000, encoder=None):   self.messages = \[] # \[{"role": ..., "content": ...}]   self.max\_tokens = max\_tokens   # encoder: 传入分词器(如 tiktoken / transformers 的 tokenizer)   self.\_encoder = encoder   def \_count\_tokens(self, text: str) -> int:   if self.\_encoder is None:   # 兜底估算:中英文混排约 1 字符 ≈ 0.6\~1 token   return int(len(text) \* 0.8)   return len(self.\_encoder.encode(text))   def add(self, role: str, content: str):   self.messages.append({"role": role, "content": content})   self.\_trim()   def \_trim(self):   """超出预算时丢弃最老的中间消息,始终保留 system 指令"""   keep = \[m for m in self.messages if m\["role"] == "system"]   rest = \[m for m in self.messages if m\["role"] != "system"]   total = sum(self.\_count\_tokens(m\["content"]) for m in keep)   trimmed = \[]   for m in reversed(rest): # 从最新往旧加   total += self.\_count\_tokens(m\["content"])   if total > self.max\_tokens:   break   trimmed.append(m)   self.messages = keep + list(reversed(trimmed))   def get(self):   return self.messages \# 使用示例 mem = ShortTermMemory(max\_tokens=2000) mem.add("system", "你是一个智能助手") mem.add("user", "我叫小明") mem.add("assistant", "你好小明") print(mem.get())

局限:只解决 “当前会话不溢出”,跨会话就丢了。要跨会话,需要下面几种长期记忆。

5.2 长期记忆:向量化存储 + 语义召回

把历史对话切成条目,embedding 后存进向量库;新会话按问题语义召回相关记忆注入 Prompt。

"""长期记忆:向量库 + 语义召回(使用 ChromaDB)""" import chromadb from chromadb.utils import embedding\_functions class LongTermMemory:   def \_\_init\_\_(self, collection\_name: str = "agent\_memory",   embed\_model="text-embedding-3-small"):   self.client = chromadb.PersistentClient(path="./memory\_db")   self.ef = embedding\_functions.OpenAIEmbeddingFunction(   api\_key="sk-xxx", model\_name=embed\_model   )   \# 若已有同名 collection 则复用   try:   self.col = self.client.get\_collection(   collection\_name, embedding\_function=self.ef)   except Exception:   self.col = self.client.create\_collection(   collection\_name, embedding\_function=self.ef)   def write(self, memory\_id: str, text: str, metadata: dict = None):   """写入一条记忆:文本 + 元数据(时间、用户、类型)"""   self.col.upsert(   ids=\[memory\_id],   documents=\[text],   metadatas=\[metadata or {"time": "", "type": "fact"}],   )   def recall(self, query: str, top\_k: int = 5, user\_id: str = None) -> list:   """按语义召回记忆;可加 where 条件过滤用户"""   where = {"user\_id": user\_id} if user\_id else None   res = self.col.query(   query\_texts=\[query], n\_results=top\_k, where=where   )   return res\["documents"]\[0]   def forget(self, memory\_id: str):   self.col.delete(ids=\[memory\_id]) \# 使用示例 mem = LongTermMemory() mem.write("u1-pref-1", "用户是前端工程师,主用 TypeScript",   {"user\_id": "u1", "type": "preference"}) mem.write("u1-hist-1", "上周用户问过 React 服务端渲染的优化方案",   {"user\_id": "u1", "type": "episode"}) hits = mem.recall("用户做什么开发", user\_id="u1") print(hits) # \['用户是前端工程师,主用 TypeScript', ...]

关键设计点:

  • 每条记忆要有user_id,严格按用户隔离(记忆是隐私数据);

  • 元数据至少包含:类型(偏好 / 事件 / 事实)、时间戳、来源;

  • upsert保证重复写入以 id 去重。

5.3 摘要记忆:滚动压缩(长对话不丢信息)

对话太长时,与其丢掉老内容,不如让模型把老内容压缩成摘要再存下来。

"""摘要记忆:滚动对话摘要(LangChain 风格,手写版)""" class SummaryMemory:   def \_\_init\_\_(self, llm\_client, summarize\_prompt: str = None):   self.llm = llm\_client # 任意 LLM 客户端   self.summary = "" # 已积累的摘要   self.buffer = \[] # 待处理的近期对话   self.buffer\_limit = 6 # 每 6 轮压缩一次   self.summarize\_prompt = summarize\_prompt or (   "把下面对话压缩为不超过 3 句话的摘要,保留关键事实、决定和用户偏好。\n"   "已有摘要:{summary}\n新增对话:\n{buffer}"   )   def add(self, role: str, content: str):   self.buffer.append({"role": role, "content": content})   if len(self.buffer) >= self.buffer\_limit:   self.\_compress()   def \_compress(self):   prompt = self.summarize\_prompt.format(   summary=self.summary,   buffer="\n".join(f"{m\['role']}: {m\['content']}" for m in self.buffer),   )   self.summary = self.llm.chat(prompt) # 伪代码:换真实客户端   self.buffer = \[]   def build\_prompt(self) -> str:   """组装给 Agent 的上下文:摘要 + 近期缓冲"""   recent = "\n".join(f"{m\['role']}: {m\['content']}" for m in self.buffer)   return f"\[历史摘要]\n{self.summary}\n\[近期对话]\n{recent}"

特点:上下文占用从 O (对话轮数) 降到 O (摘要长度),但摘要过程有信息损耗,适合与向量记忆配合使用。

5.4 结构化记忆:SQL 存事实与状态

偏好、任务状态这类 “结构化事实” 适合用关系型数据库,便于精确查询和统计。

"""结构化记忆:SQLite 存用户偏好与任务状态""" import sqlite3 import json class StructuredMemory:   def \_\_init\_\_(self, db\_path: str = "agent\_state.db"):   self.conn = sqlite3.connect(db\_path)   self.conn.execute("""   CREATE TABLE IF NOT EXISTS memories (   user\_id TEXT NOT NULL,   key TEXT NOT NULL,   value TEXT NOT NULL, -- JSON 序列化   updated\_at TEXT DEFAULT (datetime('now')),   PRIMARY KEY (user\_id, key)   )   """)   self.conn.commit()   def set(self, user\_id: str, key: str, value):   self.conn.execute(   "INSERT OR REPLACE INTO memories (user\_id, key, value) VALUES (?,?,?)",   (user\_id, key, json.dumps(value, ensure\_ascii=False)),   )   self.conn.commit()   def get(self, user\_id: str, key: str):   row = self.conn.execute(   "SELECT value FROM memories WHERE user\_id=? AND key=?",   (user\_id, key),   ).fetchone()   return json.loads(row\[0]) if row else None   def query\_by\_type(self, user\_id: str, key\_prefix: str):   """按前缀查一类记忆,例如 key 用 'pref.\*' / 'task.\*' 命名空间"""   rows = self.conn.execute(   "SELECT key, value FROM memories WHERE user\_id=? AND key LIKE ?",   (user\_id, key\_prefix + "%"),   ).fetchall()   return {k: json.loads(v) for k, v in rows} \# 使用示例 sm = StructuredMemory() sm.set("u1", "pref.language", "中文") sm.set("u1", "task.current", {"id": 42, "step": "review"}) print(sm.get("u1", "pref.language")) # 中文 print(sm.query\_by\_type("u1", "task.")) # {'task.current': {...}}

要点:用key做命名空间(pref.*、task.*、fact.*),写入用INSERT OR REPLACE天然去重。

5.5 完整的最小 Agent 记忆系统

把上面几种组合成一个可运行的最小 Agent:短期窗口 + 长期向量记忆 + 结构化偏好。

"""最小完整 Agent:短期 + 长期 + 结构化记忆组合""" from dataclasses import dataclass, field @dataclass class MinimalAgent:   short: ShortTermMemory = field(default\_factory=ShortTermMemory)   long: LongTermMemory = field(default\_factory=LongTermMemory)   structured: StructuredMemory = field(default\_factory=StructuredMemory)   user\_id: str = "default\_user"   def run(self, user\_input: str) -> str:   \# 1) 从长期记忆召回相关历史(语义)   recalled = self.long.recall(user\_input, top\_k=3, user\_id=self.user\_id)   \# 2) 读取结构化偏好   prefs = self.structured.query\_by\_type(self.user\_id, "pref.")   \# 3) 组装上下文   context = {   "recalled\_memories": recalled,   "preferences": prefs,   }   \# 4) 此处调用 LLM:prompt = 系统指令 + context + 短期窗口   \# response = llm.chat(prompt) # 伪代码   response = f"\[模拟回复] 召回 {len(recalled)} 条记忆"   \# 5) 写入短期记忆,并把重要信息沉淀到长期记忆   self.short.add("user", user\_input)   self.short.add("assistant", response)   self.\_consolidate(user\_input, response)   return response   def \_consolidate(self, user\_input: str, response: str):   """把本轮对话沉淀为长期记忆条目(生产环境应由 LLM 抽取要点)"""   memory\_id = f"{self.user\_id}-{hash(user\_input) % 100000}"   self.long.write(   memory\_id,   f"用户说:{user\_input};助手答:{response}",   {"user\_id": self.user\_id, "type": "episode"},   )

运行闭环:每轮对话 = 召回 → 组装 → 生成 → 写入 → 沉淀。


六、记忆与 RAG 的优化手段

6.1 检索优化(RAG 和记忆共用)

(1)混合检索:向量 + 关键词(BM25)

纯向量检索对专有名词、代码、ID 类查询不敏感,混合检索可显著提升召回率。

"""混合检索:向量召回 + BM25 关键词召回 + 融合""" from rank\_bm25 import BM25Okapi def hybrid\_search(query: str, chunks: list, embed\_fn, top\_k: int = 5):   """chunks: 候选片段列表(或直接从向量库取更大召回集再融合)"""   \# 向量召回(此处简化为两两相似度,生产用向量库 ANN)   import numpy as np   q\_vec = embed\_fn(\[query])\[0]   c\_vecs = embed\_fn(chunks)   vec\_scores = (c\_vecs @ q\_vec).tolist() # 余弦相似度   \# 关键词召回   tokenized = \[c.split() for c in chunks]   bm25 = BM25Okapi(tokenized)   bm25\_scores = bm25.get\_scores(query.split())   \# 融合:归一化后加权相加(RRF 更稳健,见下)   v\_norm = np.array(vec\_scores) / max(np.max(vec\_scores), 1e-9)   b\_norm = np.array(bm25\_scores) / max(np.max(bm25\_scores), 1e-9)   fused = 0.7 \* v\_norm + 0.3 \* b\_norm   idx = np.argsort(fused)\[::-1]\[:top\_k]   return \[chunks\[i] for i in idx]

(2)Rerank 重排序:先粗召回 Top-100,再用重排模型(如 Cohere Rerank /bge-reranker)精排 Top-5,精度提升明显。

\# 伪代码:粗召回 → 精排 def retrieve\_with\_rerank(query, candidate\_ids, rerank\_fn, top\_k=5):   candidates = \[load\_chunk(i) for i in candidate\_ids] # 粗召回 Top-100   scores = rerank\_fn(query, candidates) # 重排模型打分   ordered = \[c for \_, c in sorted(zip(scores, candidates), reverse=True)]   return ordered\[:top\_k]

(3)查询改写(Query Rewrite):对口语化 / 指代不明的问题,先让 LLM 改写 / 生成多个子查询(HyDE 生成假设文档)再检索。

6.2 写入优化(记忆特有)

(1)记忆整合(Consolidation):高频相似记忆 → 定期合并成更高层的摘要,避免记忆碎片化。

"""记忆整合:定期把同类记忆合并为一条""" def consolidate\_memories(memories: list, llm\_client) -> str:   """memories: 同一主题的多条原始记忆 -> 返回合并摘要"""   joined = "\n".join(f"- {m}" for m in memories)   prompt = ("以下是与同一主题相关的记忆,请合并去重,提炼成不超过 100 字的"   f"总结,保留所有不重复的事实:\n{joined}")   return llm\_client.chat(prompt)

(2)记忆评分与遗忘:给每条记忆打 “重要性 + 最近使用” 分,低分 / 过期记忆定期清理或降级归档。参考 Ebbinghaus 遗忘曲线思路:长期未使用的记忆降权。

"""记忆评分:重要性 × 新鲜度,低于阈值则遗忘""" import time def memory\_score(importance: float, last\_accessed: float, now: float, &#x20; half\_life: float = 30 \* 86400) -> float: &#x20; """half\_life: 30 天;越久没访问,新鲜度衰减越快""" &#x20; freshness = 0.5 \*\* ((now - last\_accessed) / half\_life) &#x20; return importance \* freshness \# 示例:重要性 0.9,10 天未访问 score = memory\_score(0.9, time.time() - 10 \* 86400, time.time()) \# 若 score < 0.2 -> 删除或移动到冷存储

(3)冲突解决:同一事实的新旧记忆矛盾时,默认 “新值覆盖旧值”,但保留旧值到审计表。

6.3 成本优化

手段做法收益
上下文压缩摘要记忆 / 关键信息抽取后再入 Prompt大幅降低 token 成本
缓存Redis 缓存相同问题的检索结果 / LLM 回复命中率提升后延迟和费用双降
记忆分级热记忆(常用)常驻,冷记忆(低频)存廉价存储控制向量库规模
增量索引RAG 只重索引变更文档,而非全量重建减少索引成本

6.4 架构优化:分层记忆 + 反思

\[每轮对话] ──▶ 是否重要? &#x20; │是 │否 &#x20; ▼ ▼ &#x20; \[工作记忆·短期] \[丢弃/极简记录] &#x20; │ &#x20; ▼ &#x20; \[定期整合 Consolidation] &#x20; │ &#x20; ▼ &#x20; \[语义记忆·长期向量库] ──▶ \[按需召回] &#x20; │ &#x20; ▼ &#x20; \[反思:LLM 提炼用户画像] ──▶ \[用户画像·结构化存储] ──▶ \[按需召回]

反思机制(Reflection):不是直接存原始对话,而是定期让 LLM 从多轮对话中提炼用户画像(“用户偏好深度优先的答案”" 用户反感空话 "),画像比原始对话更精炼、更好用。这也是 MemGPT /mem0 等框架的核心思想之一。


七、落地架构:记忆 + RAG + Agent 如何配合

7.1 分层上下文组装(生产级参考)

\[用户输入] ──▶ \[意图/路由] ──┬──▶ 需要外部知识? &#x20; │ │是 │否 &#x20; │ ▼ ▼ &#x20; │ \[RAG 检索] \[仅用记忆] &#x20; │ 文档向量库 &#x20; ▼ &#x20; \[记忆召回:短期窗口 + 长期语义 + 画像] &#x20; ▼ &#x20; \[Prompt 组装:系统指令 + 记忆 + 检索片段 + 当前问题] &#x20; ▼ &#x20; \[LLM] ──▶ \[输出] ──▶ \[写入闭环:更新短期/长期记忆]

7.2 代码:RAG + 记忆同框的最小 Agent

"""Agent = 短期记忆 + 长期记忆 + RAG 检索,组合示例""" class RagMemoryAgent: &#x20; def \_\_init\_\_(self, llm, vector\_db, doc\_store, memory\_long): &#x20; self.llm = llm &#x20; self.vector\_db = vector\_db # 文档向量库(RAG 用) &#x20; self.doc\_store = doc\_store # 文档原始内容 &#x20; self.memory\_long = memory\_long # 记忆向量库 &#x20; self.history = \[] # 短期记忆 &#x20; def answer(self, question: str, user\_id: str) -> str: &#x20; \# 1) 记忆召回 &#x20; memories = self.memory\_long.recall(question, top\_k=3, user\_id=user\_id) &#x20; \# 2) RAG 检索 &#x20; doc\_ids = self.vector\_db.query(question, top\_k=3) &#x20; passages = \[self.doc\_store.get(i) for i in doc\_ids] &#x20; \# 3) 组装(分层:记忆在前,知识在后,问题在最后) &#x20; prompt = "\n".join(\[ &#x20; "\[用户相关记忆]", &#x20; \*memories, &#x20; "", &#x20; "\[参考资料]", &#x20; \*passages, &#x20; "", &#x20; "\[当前问题] " + question, &#x20; ]) &#x20; answer = self.llm.chat(prompt) &#x20; \# 4) 写回记忆 &#x20; self.history.append((question, answer)) &#x20; self.memory\_long.write(f"{user\_id}-{len(self.history)}", &#x20; f"Q:{question}\nA:{answer}", &#x20; {"user\_id": user\_id, "type": "episode"}) &#x20; return answer

组装顺序经验:系统指令 → 用户记忆(个性化) → 检索知识(事实依据) → 短期上下文 → 当前问题。记忆与知识之间用分隔符区分,防止模型混淆来源。


八、总结与常见误区

8.1 一句话总结

RAG 和 Agent 记忆是 “同一套检索 - 生成架构的两个实例”:RAG 检索外部知识,记忆检索内部经历;它们的共同底座是数据库(尤其向量数据库),差别在于数据来源、写入方式、个性化程度和生命周期。

8.2 常见误区

  1. “给 Agent 配了 RAG 就不需要记忆”—— 错,RAG 不解决连续性和个性化;

  2. “记忆就是把所有对话塞进 Prompt”—— 错,上下文会溢出,必须压缩 / 检索 / 分级;

  3. “记忆只能存向量库”—— 错,偏好和状态适合 SQL,热点会话适合 Redis,实体关系适合图库;

  4. “RAG 和记忆是同义词”—— 错,前者解决知识,后者解决状态,二者互补而非互斥;

  5. “记忆越多越好”—— 错,脏数据、过期数据、隐私数据会拉低效果甚至造成泄露,必须有写入治理和遗忘机制。

8.3 选型速查

你的场景优先方案
回答基于公司知识库的问题RAG + 向量数据库
跨会话记住用户偏好结构化记忆(SQL)+ 用户画像
长对话不丢上下文短期窗口 + 滚动摘要
让 Agent 记住 “做过的事”情景记忆(向量库 + 元数据)
全部都要分层记忆 + RAG 组合架构

参考与延伸阅读

  • LangChain 文档:Memory 模块(ConversationBufferMemory / SummaryMemory 等)

  • MemGPT(Letta):分层记忆 + 自我编辑记忆的开源框架

  • mem0:面向 Agent 的长期记忆层,支持向量库 / 图库后端

  • 《Retrieval-Augmented Generation for Large Language Models: A Survey》(Gao et al.)

  • LlamaIndex:RAG 与 Agent 记忆统一抽象(Memory / ChatMemoryBuffer)

注:文中代码为教学骨架,生产使用请补充鉴权、限流、隐私脱敏、数据备份与合规(如 GDPR 对用户数据删除权的支持)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 3:45:13

深度解读Work Agent长程任务执行机制:AI自主完成复杂工作的底层逻辑

深度解读Work Agent长程任务执行机制&#xff1a;AI自主完成复杂工作的底层逻辑过去三年AI交互的形态发生了清晰的迭代&#xff0c;最早的生成式AI产品以单轮问答为核心&#xff0c;用户输入一个问题&#xff0c;系统返回对应答案&#xff0c;交互链路在单次对话结束后就完全终…

作者头像 李华
网站建设 2026/9/28 3:45:05

STM32F1 HAL库编译报错根源与精准修复指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华