智能体面试准备(六):Agent 记忆系统设计——短期、长期与向量记忆的架构与实现
智能体面试准备六Agent 记忆系统设计——短期、长期与向量记忆的架构与实现你的 Agent 怎么记住用户上周说过的话——这个问题看似简单实际是 Agent 面试里区分度最高的题目之一。因为它考的不是单点知识而是架构设计能力上下文窗口管理、信息压缩、检索召回、遗忘策略每一层都有取舍。LLM 本身是无状态的所谓记忆全部是工程构造出来的。这篇把 Agent 记忆系统的分层设计、每层的实现方案与代码、以及面试高频追问一次讲清。一、为什么记忆是 Agent 的核心组件LLM 的两个先天限制决定了记忆系统的必要性无状态每次调用都是独立的模型不会记得上一次对话所有历史必须显式塞进 prompt上下文窗口有限且注意力会稀释即使是 128k 窗口塞满后不仅贵还会出现 lost-in-the-middle中间信息被忽略——窗口大小不等于有效记忆容量。所以记忆系统要解决的核心矛盾是信息无限增长 vs 上下文有限且昂贵。解法就是分层热数据放上下文短期记忆温数据压缩摘要冷数据外部存储按需检索长期记忆。这个思路与操作系统的内存分层寄存器→内存→磁盘完全同构面试时用这个类比会非常出彩——MemGPT 论文正是把 OS 虚拟内存思想搬进了 Agent 记忆管理。二、记忆分类一张表说清记忆类型存储位置生命周期典型内容实现手段短期/工作记忆上下文窗口内单次会话当前对话、工具结果消息列表 滑动窗口摘要记忆上下文内压缩态单次会话溢出历史的摘要LLM 递归摘要长期-情景记忆外部存储跨会话历史对话事件向量库 检索长期-语义记忆外部存储跨会话用户偏好、事实画像结构化 KV/知识图谱长期-程序记忆外部存储跨会话工作流、技能、经验教训文档/代码片段库这套分类借用了认知科学的术语episodic/semantic/procedural面试报出这三个词并各给一个 Agent 场景的例子情景上周聊过的需求细节语义用户偏好 Python 且讨厌啰嗦程序部署项目的标准操作流程立刻建立专业印象。高频追问语义记忆为什么不用向量库而用结构化存储因为用户画像类信息要求精确、可更新、可覆盖——用户从北京搬到上海必须覆盖旧值向量检索可能同时召回新旧两条产生矛盾结构化 KV 天然支持 upsert。向量库适合模糊语义匹配的情景记忆两者是互补关系。三、短期记忆管理窗口溢出的三种策略滑动窗口只保留最近 N 轮。实现最简单但会突然失忆丢掉早期关键信息比如任务最初的目标。递归摘要历史超过阈值时把最老的一段压缩成摘要插到头部反复进行。信息有损但保留主干LangChain 的 ConversationSummaryBufferMemory 就是这个方案。工程细节摘要要用独立的小模型调用做避免打断主流程摘要 prompt 要求保留实体、数字、承诺、未完成事项。重要性分级保留给每条消息打重要性标签用户目标 关键结论 工具原始输出溢出时先丢低级别内容。Claude Code、Manus 这类长程 Agent 普遍采用工具输出可丢弃/可截断用户指令永不丢的策略。实践中三者叠加滑动窗口保最近、摘要保主干、分级保关键。四、可运行代码三层记忆系统的完整实现下面用纯 Python无第三方依赖实现一个可运行的记忆系统短期滑动窗口 溢出摘要 基于 TF-IDF 余弦相似度的长期向量检索真实项目换成 embedding 模型 向量库接口不变。import math import re import time from collections import Counter # ---------- 长期记忆向量化存储 余弦检索 ---------- class VectorMemory: 用 TF-IDF 模拟 embedding 检索真实场景替换为 embedding API 向量库。 def __init__(self): self.items [] # [(text, meta, term_freq)] def _tokenize(self, text): return re.findall(r[\u4e00-\u9fff]|[a-zA-Z], text.lower()) def add(self, text, metaNone): tf Counter(self._tokenize(text)) self.items.append((text, meta or {}, tf)) def _cosine(self, tf1, tf2): common set(tf1) set(tf2) dot sum(tf1[t] * tf2[t] for t in common) n1 math.sqrt(sum(v*v for v in tf1.values())) n2 math.sqrt(sum(v*v for v in tf2.values())) return dot / (n1 * n2) if n1 and n2 else 0.0 def search(self, query, top_k2, min_score0.05): q_tf Counter(self._tokenize(query)) scored [(self._cosine(q_tf, tf), text, meta) for text, meta, tf in self.items] scored.sort(reverseTrue) return [(s, t, m) for s, t, m in scored[:top_k] if s min_score] # ---------- 记忆管理器短期窗口 溢出摘要 长期沉淀 ---------- class MemoryManager: def __init__(self, window_size4): self.window_size window_size self.short_term [] # 最近消息 self.summary # 递归摘要模拟 self.long_term VectorMemory() # 跨会话记忆 self.profile {} # 语义记忆结构化用户画像 def add_message(self, role, content): self.short_term.append({role: role, content: content, ts: time.time()}) if len(self.short_term) self.window_size: evicted self.short_term.pop(0) # 溢出消息进摘要模拟 LLM 摘要 沉淀到长期记忆 self.summary f[{evicted[role]}]{evicted[content][:30]}; self.long_term.add(evicted[content], {role: evicted[role]}) def update_profile(self, key, value): 语义记忆用 upsert 覆盖保证精确性。 self.profile[key] value def build_context(self, query): 组装最终 prompt 上下文画像 摘要 长期检索 短期窗口。 recalled self.long_term.search(query) parts [] if self.profile: parts.append(f## 用户画像\n{self.profile}) if self.summary: parts.append(f## 历史摘要\n{self.summary}) if recalled: lines [f- (相关度{s:.2f}) {t} for s, t, _ in recalled] parts.append(## 相关历史记忆\n \n.join(lines)) recent \n.join(f{m[role]}: {m[content]} for m in self.short_term) parts.append(f## 当前对话\n{recent}) return \n\n.join(parts) if __name__ __main__: mm MemoryManager(window_size3) mm.update_profile(语言偏好, Python) mm.add_message(user, 帮我调研 vLLM 的部署方案重点看显存占用) mm.add_message(assistant, vLLM 用 PagedAttention 管理显存建议预留 20% 余量) mm.add_message(user, 我们的显卡是 409024G 显存) mm.add_message(user, 另外记得数据库连接串要用环境变量) mm.add_message(assistant, 好的已记录环境变量规范) mm.add_message(user, 对了之前说的显卡是什么型号来着) print(mm.build_context(显卡 显存 型号))运行后可以看到窗口只留最近 3 条早期的4090、24G 显存已被挤出窗口但通过长期记忆检索被召回进上下文——这正是Agent 记住了窗口外信息的完整机制。这段代码覆盖手撕记忆模块的所有得分点窗口驱逐、摘要沉淀、向量召回、结构化画像、上下文组装。五、长期记忆的三个工程难题写什么记忆生成不能把所有对话原文都存进去噪声会淹没检索。主流做法是反思式写入会话结束或阶段完成时让 LLM 提取值得长期保留的事实/偏好/教训再写入Generative Agents 的 reflection 机制、Mem0 的事实提取都是这个思路。追问点什么时候写——事件驱动用户明确说记住 周期驱动会话结束批量反思结合。怎么取检索策略单纯向量相似度不够。Generative Agents 的经典打分公式是相关性 时近性 重要性三分量加权相关性用余弦相似度时近性用指数衰减decay^Δt重要性在写入时由 LLM 打 1~10 分。这条公式是面试的高频得分点务必能默写并解释每个分量的作用。怎么忘遗忘与冲突记忆会过时和矛盾。手段包括TTL 过期、访问频率淘汰LRU 思想、写入时冲突检测新记忆与已有记忆语义冲突时触发合并或覆盖——Mem0 的 ADD/UPDATE/DELETE 决策。记忆冲突怎么办是压轴追问答写入时让 LLM 判断新旧关系并选择增/改/删即可。六、面试答题框架与高频题设计一个有跨会话记忆的个人助理 Agent推荐结构分层短期窗口摘要、语义结构化画像upsert、情景向量库、程序技能文档写路径会话结束触发反思式提取LLM 判断增/改/删读路径每轮用当前 query 检索 top-k按相关性时近性重要性排序注入 system prompt治理PII 脱敏、用户可查看/删除自己的记忆合规卖点、记忆条数上限与淘汰。其他高频题速答长上下文模型1M token会让记忆系统过时吗——不会。成本与延迟随上下文线性增长、注意力稀释依旧存在、跨会话持久化仍需外部存储长窗口只是把短期记忆变大了。RAG 和记忆系统什么关系——机制同源外部存储检索注入对象不同RAG 检索的是外部知识库记忆检索的是 Agent 自身经历记忆还多了写入、更新、遗忘的生命周期管理。多 Agent 场景记忆怎么共享——公共黑板共享记忆池 私有记忆隔离写入公共池需要格式约定与权限控制。自检清单能报出情景/语义/程序三分类并各举一例吗能默写相关性时近性重要性检索公式吗能说清语义记忆为什么用结构化存储吗能手写一个带驱逐和召回的记忆管理器吗四问皆通记忆环节稳拿高分。下一篇讲多智能体协作角色分工、辩论机制与流水线编排的实现。

相关新闻

终极高效GIF生成工具:gifski完整指南,让视频转GIF动画更简单

终极高效GIF生成工具:gifski完整指南,让视频转GIF动画更简单

终极高效GIF生成工具:gifski完整指南,让视频转GIF动画更简单 【免费下载链接】gifski GIF encoder based on libimagequant (pngquant). Squeezes maximum possible quality from the awful GIF format. 项目地址: https://gitcode.com/gh_mirrors/gif…

2026/9/25 4:43:18 阅读更多 →
智能体面试准备(五):规划与任务分解——从 Plan-and-Execute 到动态重规划的工程实现

智能体面试准备(五):规划与任务分解——从 Plan-and-Execute 到动态重规划的工程实现

智能体面试准备(五):规划与任务分解——从 Plan-and-Execute 到动态重规划的工程实现 Agent 面试里,"工具调用"考的是基本功,"规划能力"考的才是深度。面试官常用的开场是:"你的 …

2026/10/12 22:19:44 阅读更多 →
Jellium Desktop界面动画性能测试:测量动画性能

Jellium Desktop界面动画性能测试:测量动画性能

Jellium Desktop界面动画性能测试:测量动画性能 【免费下载链接】jellium-desktop An unofficial desktop client for Jellyfin 项目地址: https://gitcode.com/GitHub_Trending/je/jellium-desktop Jellium Desktop作为一款非官方的Jellyfin桌面客户端&…

2026/10/5 12:01:02 阅读更多 →

最新新闻

DSO编译运行实战:从环境配置到参数调优全解析

DSO编译运行实战:从环境配置到参数调优全解析

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

2026/10/14 1:39:10 阅读更多 →
并发写入的优雅礼让:用应用级队列与文件锁(flock)彻底消灭 SQLite 写入超时

并发写入的优雅礼让:用应用级队列与文件锁(flock)彻底消灭 SQLite 写入超时

秋雨下了一整天,小书房的窗框被雨水打得泛出一层深褐色的湿润。我坐在桌前,一边在手账编辑器里随手敲打着今天的读书记摘,一边开着后台脚本批量整理手机刚同步过来的上百张秋游照片。 就在我按下手账保存键的同一瞬间,相册整理脚本…

2026/10/14 1:39:10 阅读更多 →
STM32C5与CubeMX2实战:从选型到低功耗排错全记录

STM32C5与CubeMX2实战:从选型到低功耗排错全记录

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

2026/10/14 1:39:10 阅读更多 →
基于Spring Boot与uni-app的校园食堂订餐系统:从架构设计到订单状态机实战

基于Spring Boot与uni-app的校园食堂订餐系统:从架构设计到订单状态机实战

简介:这份资源是面向高校计算机相关专业学生与Java开发学习者的毕业设计完整文档,主题为基于Spring Boot的校园食堂订餐系统的设计与实现,可帮助读者理解如何将所学技术落地到真实校园服务场景中。系统针对疫情期间食堂拥挤、学生外卖依赖、就…

2026/10/14 1:39:10 阅读更多 →
人脸超分与关键点估计迭代协作:注意力恢复机制解析

人脸超分与关键点估计迭代协作:注意力恢复机制解析

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

2026/10/14 1:39:10 阅读更多 →
YOLOv3电塔绝缘子检测权重:快速推理与微调实战

YOLOv3电塔绝缘子检测权重:快速推理与微调实战

简介:这是一份面向电力设施智能监测场景的YOLOv3电塔绝缘子检测训练成果包,适合目标检测初学者、电力巡检算法开发者及需要小目标检测参考方案的技术人员使用。资源包共990个文件,约520.07MB,包含json标注数据、png与jpg图像样本、…

2026/10/14 1:38:10 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/12 18:11:17 阅读更多 →