Agent记忆系统设计:短期上下文与长期外部记忆的协同实践
1. 记忆系统Agent的“大脑”与“笔记本”最近在社区里看到不少朋友在讨论Agent开发尤其是关于记忆模块的设计经常能听到这样的困惑“我的Agent怎么聊着聊着就把之前说过的话给忘了”或者“为什么Function Call的结果Agent处理不了对话直接卡住了”这背后其实都指向了同一个核心问题Agent的记忆系统设计。如果把Agent比作一个智能体那么它的“大脑”就是处理当前对话的短期上下文而它的“笔记本”就是用来记录重要信息、供未来查阅的长期外部记忆。一个只会用“大脑”思考从不做笔记的Agent就像我们人类一样只能处理眼前有限的几件事一旦信息量稍大或者对话轮次一多就会“失忆”。而一个设计良好的记忆系统能让Agent拥有持续学习和进化的能力真正实现多轮、复杂、有状态的交互。在实战中我发现很多初涉Agent开发的团队最容易踩的坑就是混淆了“短期上下文”和“长期外部记忆”的边界或者干脆只用了前者。结果就是Agent的表现极不稳定时灵时不灵。今天我们就来彻底拆解Agent的记忆系统从原理到实践讲清楚短期上下文和长期外部记忆到底该怎么设计、怎么用以及如何避免那些让你对话“当场死机”的经典陷阱。2. 短期上下文Agent的“工作记忆区”短期上下文在技术实现上通常指的就是我们传给大语言模型LLM的那段Prompt里面包含了系统指令、用户当前的问题、以及最近几轮的对话历史。你可以把它想象成Agent的“工作记忆区”或“大脑的缓存”所有即时的思考、推理和决策都发生在这里。2.1 短期上下文的核心作用与工作原理它的核心作用有两个一是提供决策依据让LLM基于当前的对话历史和指令来生成回复二是传递执行状态特别是Function Call函数调用的结果必须及时回填到这里。这里就引出了一个至关重要的原则也是很多新手会忽略的致命点Function Call的“执行结果”必须放进短期上下文否则本轮对话会当场死机。为什么我们来模拟一下流程LLM分析用户问题发现需要调用一个外部函数比如查询天气。LLM生成一个结构化的Function Call请求例如{“name”: “get_weather”, “arguments”: {“city”: “北京”}}。你的程序执行这个函数拿到了结果例如{“city”: “北京”, “weather”: “晴”, “temperature”: “25°C”}。关键步骤你必须把这个执行结果作为一条新的消息通常是role: “function”追加到当前的对话上下文中。然后将包含了这条function结果消息的完整上下文再次发送给LLM。LLM看到了函数执行的结果才能基于这个结果组织最终的自然语言回复给用户。如果在第4步遗漏了LLM在下一轮生成时根本不知道函数调用已经发生以及结果是什么它可能会完全忽略之前要调用函数这回事给出一个无关的回复。或者因为它“记得”自己发出了调用指令但没看到结果陷入逻辑混乱生成无意义的输出。更常见的是在需要依赖函数结果才能继续的对话流中对话直接无法推进看起来就像“死机”了。所以短期上下文是一个有状态的、滚动的窗口。它的大小受限于LLM的上下文长度如4K、8K、16K、128K tokens。当对话轮次增加超出这个窗口时最早的历史就会被“遗忘”从技术上讲是被截断。2.2 短期上下文的管理策略与常见陷阱管理短期上下文不仅仅是简单地把所有历史对话堆进去。你需要策略1. 摘要压缩策略当对话历史很长时盲目截断会丢失关键信息。更好的做法是进行摘要压缩。例如每经过N轮对话或者当上下文长度接近阈值时调用LLM本身对之前的对话历史生成一个简洁的摘要。然后用这个摘要替换掉大段的原始历史再继续新的对话。这样既保留了核心信息又节省了宝贵的token。2. 关键信息提取策略另一种思路是在对话过程中主动识别并提取关键实体和信息如用户提到的项目名、日期、特定需求等将这些结构化信息单独存储这其实已经过渡到长期记忆了而在上下文中只保留最近几轮最“鲜活”的对话。3. 一个实战中的大坑角色Role混淆在构建上下文消息列表时消息的角色role至关重要。通常有system,user,assistant,function。一个常见的错误是把所有非用户输入都塞进assistant角色。请务必遵守system: 定义Agent的初始指令和身份通常只在对话开始时出现一次。user: 用户说的话。assistant: Agent说的话即LLM生成的回复文本。function:Function Call执行后返回的结果。把function结果错放在assistant里可能会干扰LLM对对话结构的理解。正确的消息流看起来是这样的[ {role: system, content: 你是一个天气助手...}, {role: user, content: 北京今天天气怎么样}, {role: assistant, content: null, function_call: {name: get_weather, arguments: {city: 北京}}}, {role: function, name: get_weather, content: {\city\: \北京\, \weather\: \晴\, \temperature\: \25°C\}}, {role: assistant, content: 北京今天天气晴朗气温25摄氏度非常适合外出。} ]短期上下文是Agent实时思考的舞台但它容量有限且不持久。要构建真正有“记忆力”的Agent我们必须引入长期外部记忆。3. 长期外部记忆Agent的“知识库”与“经验簿”如果说短期上下文是大脑的缓存那么长期外部记忆就是大脑皮层里的长期记忆外加一个随身携带的笔记本和资料库。它的核心目的是跨越对话会话Session持久化存储信息并在未来的交互中快速、准确地检索出来。3.1 为什么需要长期记忆突破上下文长度限制LLM的上下文再长比如128K也有上限且全部放在上下文里推理成本极高更贵、更慢。长期记忆可以将海量信息存储在外部按需取用。实现个性化与持续学习记住用户的偏好“我不喜欢咖啡”、历史任务细节“上周你帮我订的酒店是XX”、以及Agent自身积累的经验“上次用方法A解决这个问题失败了”。支持复杂、多步骤任务对于一个需要多天、多次交互才能完成的项目Agent必须能把中间状态、已收集的信息可靠地保存下来下次接着干。3.2 长期记忆系统的核心组件一个完整的长期记忆系统通常包含三个部分1. 记忆存储器这是物理存储的地方。选择很多向量数据库主流选择如 Pinecone、Chroma、Weaviate、Qdrant以及国内的一些云服务。它们擅长存储文本的向量嵌入Embedding并做相似性搜索。适合存储“非结构化”的经验、知识片段、对话摘要。传统数据库如 SQLite、PostgreSQL、MySQL。适合存储“结构化”的信息比如用户配置、订单号、任务状态等。简单文件存储如 JSON 文件。适用于原型验证或极其简单的场景不推荐生产环境。2. 记忆读写器负责决定什么该记、以什么格式记以及什么时候去读。写策略不是用户说的每句话都要记。常见的触发策略包括检测到用户表达了明确偏好“我住在上海”完成了一个重要任务节点对话中产生了值得总结的结论。写入的内容通常需要经过清洗和结构化比如生成一个包含“时间戳”、“实体”、“摘要”、“类型”等字段的记忆对象。读策略检索当新对话开始时或对话中提及某些关键词时需要从长期记忆中召回相关信息。最常用的方法是向量相似性检索将当前用户的问题或对话上下文编码成向量去向量数据库中搜索最相关的N条记忆。也可以结合关键词过滤元数据过滤来提升精度。3. 记忆处理器在检索到相关记忆后直接把这些记忆文本塞进上下文可能不够高效或准确。处理器的作用是对记忆进行加工例如相关性排序与过滤剔除相关性分数过低的记忆。摘要与融合如果检索出多条相似记忆可以合并或摘要成一条。格式化将记忆转换成适合插入LLM上下文的自然语言描述例如“根据我们之前的对话我记得您更喜欢窗口的座位并且对花生过敏。”3.3 搭建长期记忆的实战步骤假设我们使用 Chroma轻量级易于本地部署作为向量数据库为Agent添加一个“记住用户喜好”的长期记忆功能。步骤1设计记忆结构首先定义一条记忆长什么样。这没有固定标准但一个好的结构包含{ “id”: “unique_id”, “content”: “用户明确表示他最喜欢的颜色是蓝色。”, # 记忆的文本内容 “embedding”: [0.12, -0.45, …], # 由文本编码成的向量由数据库管理 “metadata”: { “user_id”: “user_123”, “type”: “preference”, # 记忆类型preference/fact/task_context等 “entity”: “color”, # 关联的实体 “timestamp”: “2023-10-27T10:00:00Z”, “source_session”: “session_abc” } }步骤2实现记忆写入在对话过程中监听或分析消息触发写入。import chromadb from sentence_transformers import SentenceTransformer # 初始化 client chromadb.PersistentClient(path“./memory_db”) collection client.get_or_create_collection(name“user_memories”) embed_model SentenceTransformer(‘all-MiniLM-L6-v2’) # 一个轻量级的嵌入模型 def save_memory(user_id, content, memory_type, entity): # 生成嵌入向量 embedding embed_model.encode(content).tolist() # 准备元数据 metadata { “user_id”: user_id, “type”: memory_type, “entity”: entity, “timestamp”: datetime.now().isoformat() } # 存入Chroma collection.add( documents[content], embeddings[embedding], metadatas[metadata], ids[f”{user_id}_{int(time.time())}”] # 简单生成ID )步骤3实现记忆检索当新对话开始或进行中检索相关记忆。def retrieve_memories(user_id, query, n_results3): # 将查询文本转换为向量 query_embedding embed_model.encode(query).tolist() # 从该用户的记忆中检索增加元数据过滤提高精度 results collection.query( query_embeddings[query_embedding], n_resultsn_results, where{“user_id”: user_id} # 只检索当前用户的记忆 ) # 处理结果 retrieved_memories [] if results[‘documents’]: for doc, meta in zip(results[‘documents’][0], results[‘metadatas’][0]): retrieved_memories.append({ “content”: doc, “metadata”: meta, “distance”: results[‘distances’][0][results[‘documents’][0].index(doc)] }) # 可以在这里根据distance距离越小越相关进行过滤 return retrieved_memories步骤4将记忆整合进上下文检索到的记忆需要被巧妙地插入到发给LLM的上下文中。通常放在system指令之后或者最近的历史对话之前。# 在构建LLM上下文时 context_messages [] context_messages.append({“role”: “system”, “content”: f”你是助手。以下是你之前了解到的关于用户的信息\n{formatted_memories}”}) # … 追加历史对话和当前问题这里的formatted_memories就是将检索到的多条记忆内容用自然语言串联起来例如“用户曾说过他喜欢蓝色。用户还提到他对花生过敏。”3.4 长期记忆的挑战与优化记忆冲突与更新如果用户说“我喜欢蓝色”后来又说“我现在更喜欢绿色了”。如何处理简单的方案是用新记忆覆盖旧记忆通过元数据关联同一entity并删除旧的。更复杂的方案可以引入记忆的“强度”或“新鲜度”衰减模型。检索精度与召回率向量检索并不总是精准。优化方法包括使用更好的嵌入模型在元数据中添加更丰富的标签采用混合检索向量关键词对检索结果进行LLM二次重排序。记忆的抽象与泛化记住“用户喜欢蓝色”是具体的能否抽象出“用户对颜色有明确偏好”这条更高阶的记忆这需要更高级的认知架构目前通常通过定期用LLM总结对话来实现。4. 短期与长期的协同构建完整的记忆流短期上下文和长期外部记忆不是孤立的它们必须协同工作形成一个闭环的记忆流。一个典型的工作流程如下会话开始用户发起新对话。Agent首先从长期记忆中检索与该用户相关的记忆如偏好、未完成任务并将其作为背景信息插入短期上下文的开头。对话进行Agent基于短期上下文包含系统指令、长期记忆背景、近期对话与用户交互。期间可能触发Function Call其结果必须立刻回填到短期上下文。记忆触发在对话过程中监控是否产生了值得长期存储的信息。这可以通过规则检测到“记住”、“我喜欢”等关键词或通过一个小型LLM分类器来判断。记忆固化当触发记忆点时将当前短期上下文中相关的片段可能是经过LLM摘要的进行结构化处理生成记忆对象存入长期记忆库向量数据库。上下文管理同时监控短期上下文的长度。如果接近模型限制可以对较早的、不那么重要的对话历史进行摘要压缩或将确定已固化的信息从上下文中移除只保留一个引用指针以节省空间。会话结束/暂停在对话结束时可以启动一个更全面的总结过程将整个会话的要点和结论写入长期记忆。这个流程确保了Agent既能关注当下又能积累过去并为未来做好准备。5. 避坑指南记忆系统开发中的典型问题在开发Agent记忆系统时我踩过不少坑这里分享几个最典型的坑1混淆记忆与对话历史把整个对话历史日志直接当长期记忆存进向量库。这会导致检索出大量无关的闲聊片段噪音极大。长期记忆应该是提炼后的、高价值的信息结晶而不是原始日志。坑2忽视记忆的时效性与冲突没有设计记忆更新机制。比如用户地址变了但Agent检索到的还是旧地址。解决方案是为记忆添加版本管理或“最后更新时间”字段并在检索时优先返回最新的或者在写入新记忆时主动清理旧的、冲突的记忆。坑3检索到的记忆直接“硬塞”进上下文如果检索到5条记忆不分青红皂白全部以原始文本形式塞进系统提示可能会占用大量token甚至干扰主要任务。需要对记忆进行优先级排序、摘要和格式化。例如“关于您的颜色偏好相关度85%您喜欢蓝色。关于您的饮食禁忌相关度90%您对花生过敏。”坑4向量嵌入模型选型不当使用一个在通用语料上训练的嵌入模型来编码非常垂直领域的对话比如医疗、法律可能导致相似性搜索效果很差。如果条件允许可以考虑用领域数据对嵌入模型进行微调或者选择在相关领域表现更好的模型。坑5忘记为记忆添加访问控制在Multi-Agent多智能体系统中不同Agent的记忆可能需要隔离。或者在单用户场景下要确保用户A的记忆绝不会被用户B检索到。这需要在存储和检索时严格加入user_id、agent_id等元数据过滤条件。记忆系统是Agent从“玩具”走向“工具”从“单次对话”走向“持续服务”的关键桥梁。理解短期上下文与长期外部记忆的分工与协作是设计出强大、实用Agent的必修课。它没有一成不变的方案需要你根据具体的应用场景、性能要求和资源约束不断地进行权衡、设计和迭代。

相关新闻

供应链安全攻防升级:恶意软件清除行动与AI误报噪音双重夹击

供应链安全攻防升级:恶意软件清除行动与AI误报噪音双重夹击

曾经有那么一段时间, 成功将一场大规模恶意软件行动打破瓦解, 这就表明开源生态安全向前跨越了重要的一步。现在, 这种所拥有的成就感已经大幅降低。就在行动被破坏的时候, 攻击者常常能够快速重新整顿, 再一次展开行动, 而防御方却遭遇了一项全新的挑战: 那就是怎样从越来越多…

2026/8/7 6:59:03 阅读更多 →
ComfyUI图像放大革命:PID与PixelDiT技术实现细节重生

ComfyUI图像放大革命:PID与PixelDiT技术实现细节重生

在AI绘画领域,图像放大一直是个“老大难”问题。传统的放大方法,无论是简单的双线性插值,还是AI驱动的超分辨率模型,往往只是在原有像素基础上进行“猜测”和“平滑”,导致放大后的图像细节模糊、纹理失真,…

2026/8/7 6:59:03 阅读更多 →
2D 太空全向物理漂移与陨石分裂碰撞

2D 太空全向物理漂移与陨石分裂碰撞

为你带来具有全向自由度、多目标跟踪雷达、惯性漂移弹道模拟以及多段子弹连发机制的殿堂级高燃街机游戏——「赛博原力:星际生存(Asteroids 风格 / 2D 太空全向物理漂移与陨石分裂碰撞)」。前面我们写过了极坐标插刀、重力小鸟和…

2026/8/7 6:59:03 阅读更多 →

最新新闻

083、YOLOv11改进-知识蒸馏策略中学生模型设计与损失函数选择——即插即用蒸馏模块提升轻量模型mAP达3.2%

083、YOLOv11改进-知识蒸馏策略中学生模型设计与损失函数选择——即插即用蒸馏模块提升轻量模型mAP达3.2%

083、YOLOv11改进-知识蒸馏策略中学生模型设计与损失函数选择——即插即用蒸馏模块提升轻量模型mAP达3.2% 一、踩坑实录:蒸馏不是简单“抄作业” 上个月调YOLOv11n的蒸馏,跑了三天结果mAP反而掉了0.5%。debug时发现教师模型和学生模型的特征图尺寸对不上,蒸馏loss直接爆炸…

2026/8/8 12:17:25 阅读更多 →
2025年五大无偏见渲染引擎评测与应用指南

2025年五大无偏见渲染引擎评测与应用指南

1. 2025年渲染引擎行业现状与核心需求在数字内容创作领域,渲染引擎的选择直接决定了最终输出的视觉质量和生产效率。经过2024年的技术迭代,主流渲染引擎在物理准确性、实时反馈和跨平台兼容性方面都取得了显著突破。作为从业12年的三维技术总监&#xff…

2026/8/8 12:17:25 阅读更多 →
AdGuard浏览器扩展终极指南:5分钟实现无广告隐私保护浏览

AdGuard浏览器扩展终极指南:5分钟实现无广告隐私保护浏览

AdGuard浏览器扩展终极指南:5分钟实现无广告隐私保护浏览 【免费下载链接】AdguardBrowserExtension AdGuard browser extension 项目地址: https://gitcode.com/gh_mirrors/ad/AdguardBrowserExtension AdGuard浏览器扩展是一款完全免费开源的广告拦截工具&…

2026/8/8 12:17:25 阅读更多 →
LCD1602驱动全解析:从初始化时序到HD44780控制器实战

LCD1602驱动全解析:从初始化时序到HD44780控制器实战

1. 项目缘起:从一堆方块到清晰字符的跨越 如果你玩过单片机,尤其是像51、STM32这类入门级MCU,那么你对LCD1602这个老朋友一定不陌生。它可能是你硬件生涯中,继点亮LED之后,遇到的第一个“有内容”的输出设备。但很多新…

2026/8/8 12:17:25 阅读更多 →
AD操作记录

AD操作记录

本人使用AD各种操作记录,快捷键需要在对应的界面设置。原理图部分原理图与PCB选择联动ShiftCtrlXPCB部分泪滴设置TE设置坐标轴原点EOSPCB层数管理DK导入CADENCE文件1,设置环境变量,在系统变量中的PATH中添加cadence的安装路径例如C:\Cadence\…

2026/8/8 12:17:25 阅读更多 →
Maven本地仓库配置与IDEA全局设置详解:提升Java开发效率

Maven本地仓库配置与IDEA全局设置详解:提升Java开发效率

1. 项目概述:为什么Maven本地仓库配置是Java开发的基石 如果你是一名Java开发者,或者正准备踏入这个领域,那么“Maven”和“IDEA”这两个名字对你来说一定不陌生。前者是项目构建和依赖管理的核心工具,后者则是我们每天打交道的集…

2026/8/8 12:16:25 阅读更多 →

日新闻

AI多智能体时代来临,读懂MCP与A2A架构,抢占企业数字化新风口

AI多智能体时代来临,读懂MCP与A2A架构,抢占企业数字化新风口

当下AI应用飞速普及,无数企业下场搭建智能体系统,可落地阶段难题接踵而至:上下文无限堆积频繁爆栈、AI工具调用准确率低下、Token成本居高不下、企业数据权限混乱暗藏安全隐患……很多团队卡在架构搭建环节,空有前沿技术概念&…

2026/8/8 0:00:07 阅读更多 →
PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码

PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码

PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码 【免费下载链接】php-qrcode A PHP QR Code generator and reader with a user-friendly API. 项目地址: https://gitcode.com/gh_mirrors/ph/php-qrcode 在当今数字时代,二维码已…

2026/8/8 0:00:08 阅读更多 →
UniApp微信小程序隐私保护组件开发:从原理到实战

UniApp微信小程序隐私保护组件开发:从原理到实战

1. 项目缘起:为什么我们需要一个隐私保护通用组件?最近在维护一个基于uniapp开发的微信小程序矩阵时,我遇到了一个非常棘手的问题。随着平台对用户隐私保护的要求越来越严格,几乎每一个新版本发布,或者在某些特定机型&…

2026/8/8 0:00:08 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/6 22:02:27 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/8 8:58:26 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/7 23:24:08 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/7 17:02:37 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/7 23:54:54 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/7 17:02:36 阅读更多 →