Agent记忆分层与RAG检索
Agent 短期+长期记忆架构,RAG 检索与选择性遗忘机制
原题:当AI Agent需要维护超长历史记忆(如数千轮对话或跨天任务上下文)时,受限于模型上下文窗口和推理效率,无法将全部历史直接传入模型。请设计一个高效且可扩展的记忆管理机制,涵盖短期与长期记忆的分层架构、基于语义与时间等维度的检索策略、记忆的动态更新与选择性遗忘机制,并说明如何结合检索增强生成(RAG)实现上下文压缩与信息保留的平衡。
Agent · 高德真题
回答与解析
核心架构:三层记忆体系
工作记忆(Working Memory)
- 最近2-4轮对话,直接拼接进prompt
- 包含当前任务状态、工具调用中间结果
短期记忆(Short-term Memory)
- 当前会话内的历史(数小时级)
- 按对话轮次分块,维护时间索引和主题标签
长期记忆(Long-term Memory)
- 跨会话的持久化知识(天/周/月级)
- 存储于向量数据库,支持语义检索
多维度检索策略
| 维度 | 实现方式 | 权重场景 |
|---|---|---|
| 语义相似度 | 对话Embedding + 向量检索(如HNSW) | 用户询问历史相关话题 |
| 时间衰减 | 指数衰减函数:score × e^(-λ·Δt) | 近期记忆优先 |
| 重要性标记 | LLM自动打标(关键决策/用户确认/异常事件) | 重要节点不被遗忘 |
| 访问频率 | LRU + 频次统计 | 热点记忆缓存加速 |
混合检索公式:Final_Score = α·semantic + β·recency + γ·importance
动态更新与遗忘机制
记忆写入流程
原始对话 → LLM提取结构化记忆(实体-关系-摘要)→ 语义去重 → 分级存储
关键策略
- 摘要压缩:每N轮对话由LLM生成摘要,替代原始文本
- 增量更新:相同实体的新信息合并更新,保留时间戳链
- 主动遗忘:低频访问+低重要性记忆进入"冷存储",可配置彻底删除
RAG深度集成:上下文压缩
检索后处理
- 重排序(Rerank):Cross-Encoder精排Top-K结果
- 信息密度筛选:优先选包含实体、动作、结论的片段
- 动态窗口分配:工作记忆固定槽位 + RAG结果弹性槽位
Prompt注入模板
[系统指令]
[工作记忆:最近对话]
[RAG检索:相关历史摘要] ← 动态填充
[当前用户输入]
平衡策略:设置token预算上限,RAG结果按相关性截断,确保总上下文<模型上限的80%
工程实现要点
- 存储层:向量库(Milvus/Pinecone)+ 图数据库(Neo4j存关系)+ 时序库(TTL自动过期)
- 实时性:记忆写入异步化,检索路径优先读缓存
- 可观测:记录"检索→使用→反馈"链路,持续优化索引
学习建议
建议从人类记忆类比入手,理解记忆分层原理;掌握向量检索、摘要抽取、RAG流程,并动手实现简易记忆系统以加深理解。
口语版讲法(约4分钟)
- 一句话点题:本质是平衡上下文窗口和记忆密度
- 三层记忆体系:工作记忆、短期、长期
- 检索策略:语义+时间+重要性混合
- 动态更新与遗忘:摘要压缩、增量更新、冷存储
- RAG集成与工程风险
这个问题其实问的是,当模型上下文窗口成为瓶颈时,怎么在有限空间里塞进最有价值的历史信息。说白了,不是能不能记住所有东西,而是怎么在遗忘和保留之间做聪明的取舍。
我的核心思路是分层记忆。你可以类比人类记忆,工作记忆就是手边最近两三轮对话,直接拼进prompt,保证当前任务连贯。短期记忆是当前会话里几小时内的历史,按对话轮次分块,维护时间索引和主题标签。长期记忆才是跨会话的持久化知识,存到向量数据库里,按需检索。这个分层的好处是,高频访问的放在最上层,成本最低,低频的沉到下层,检索时才拉出来,这样既控制了每次推理的输入长度,又保留了整体信息的可回溯性。
具体检索时,我不会只用语义相似度。因为用户可能问的是昨天刚提过的事,语义上跟今天的话题不相关,但时间近就应该优先。所以我的策略是混合打分:语义相似度用 Embedding 加 HNSW 做近似检索,时间衰减用指数函数,重要性由LLM自动打标,比如用户确认过的关键决策、异常事件,这些节点权重高,不容易被遗忘。最后综合得分是语义、时效性和重要性的加权和,权重可以按场景调。举个例子,客服场景里用户问退款进度,语义上跟历史退款单关联大,时间上最近的操作也关键,重要性标记过的退款确认信息优先级最高,这样检索出来的片段才准。
记忆的动态更新和遗忘是另一个重点。每次新对话进来,我不会直接存原始文本,而是让LLM提取结构化记忆,实体、关系、摘要,然后做语义去重。如果同一个实体有新信息,就增量更新,保留时间戳链。对于长期不访问且重要性低的记忆,我把它打入冷存储,可以配置彻底删除。这样既控制了存储成本,也避免了陈旧信息干扰。这里有个坑:如果去重做不好,同一个实体反复出现,检索时就会重复命中,浪费上下文窗口,甚至引入矛盾。上线前我会特别关注去重阈值和摘要质量。
最后是RAG的深度集成。检索回来的结果不能一股脑塞进去,我会先做 重排,用 Cross-Encoder 精排Top-K,然后筛选信息密度高的片段,优先保留包含实体、动作、结论的句子。Prompt里固定给工作记忆留槽位,RAG结果弹性填充,总token控制在模型上限的80%以内,留余量给模型思考。这个平衡很微妙:RAG结果太少,记忆不够;太多,模型可能迷失在上下文里。我的做法是设一个token预算,如果检索结果超了,就按相关性截断,相关性低的直接丢掉。
还有一个有意思的方向:当记忆规模大到一定程度,比如跨天、跨用户,单纯向量检索的召回率会下降,因为语义漂移。我倾向于引入图结构,把实体之间的关系显式存起来,这样检索时能沿着关系链找到间接相关的记忆。比如用户之前问过A商品的优惠,后来问B商品,如果A和B同属一个品类,图结构就能把A的优惠信息关联过来,而向量检索可能因为语义不直接匹配而漏掉。
所以整体上,我会把记忆管理看成一个分层存储加混合检索的工程系统,核心是平衡上下文窗口利用率和信息密度。前提是LLM的摘要和打标能力要可靠,否则下游检索和更新都会受影响。常见失败场景是摘要丢失关键细节,或者重要性打分不准导致重要记忆被遗忘,这些都需要通过可观测链路持续调优。
关键一句:当记忆规模大到语义漂移时,向量检索召回率下降,可引入图结构显式存储实体关系来提升关联记忆的召回。
面试官还可能这样问
- 问法 1 · 场景切入
假设你做一个客服Agent,用户可能连续聊上几百轮,或者隔几天回来继续问。现在模型一次只能看几千token,你会怎么设计记忆系统,让Agent既记住刚才说了什么,又能在需要时翻出三天前的关键信息?
- 问法 2 · 层层追问
Agent的上下文窗口有限,你怎么管理对话历史?……如果历史有几万轮呢,是不是全部存下来?……那如何既保留有用信息又不让prompt超长?……怎么在需要时快速找到相关的历史片段?
- 问法 3 · 直球架构
设计一个面向超长对话的Agent记忆管理机制,要求分层架构涵盖短期和长期记忆,支持语义、时间等多维度检索,还要有动态更新和选择性遗忘。结合RAG,你怎么平衡上下文压缩和信息保留?