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/10 14:52:26 阅读更多 →
ComfyUI图像放大革命:PID与PixelDiT技术实现细节重生

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

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

2026/8/15 0:50:51 阅读更多 →
2D 太空全向物理漂移与陨石分裂碰撞

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

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

2026/8/16 2:49:40 阅读更多 →

最新新闻

ArcGIS管网数据生产实战:从表格到拓扑完整流程

ArcGIS管网数据生产实战:从表格到拓扑完整流程

1. 项目概述:从零到一构建管网空间数据在市政、水利、石油化工乃至园区管理的日常工作中,我们常常会遇到一个基础但繁琐的任务:将一堆只有坐标和属性的表格数据,比如阀门位置、水表读数、管线材质规格,变成一张能在GIS…

2026/8/16 3:59:10 阅读更多 →
Go语言钉钉机器人插件ddingtalk实战:从入门到生产级告警系统构建

Go语言钉钉机器人插件ddingtalk实战:从入门到生产级告警系统构建

1. 项目概述与核心价值最近在折腾一个内部告警通知系统,需要把各种服务日志、监控告警实时推送到团队群里。市面上现成的方案要么太重,要么定制化不够灵活。直到我发现了largezhou/ddingtalk这个 OpenClaw 插件,它专门用于深度集成钉钉机器人…

2026/8/16 3:59:10 阅读更多 →
Linux上安装FFmpeg

Linux上安装FFmpeg

FFmpeg 是一套处理多媒体文件的软件。凭借这些强大的库,FFmpeg 能够转换格式、推流以及处理音频和视频文件。许多 Linux 的前端应用都使用 FFmpeg 作为后端支持,所以这些应用对 FFmpeg 的依赖度非常高。举个例子,录屏软件可能会用到 FFmpeg 将…

2026/8/16 3:59:10 阅读更多 →
LeetCode AI助手:苏格拉底式引导与面试模拟提升算法思维

LeetCode AI助手:苏格拉底式引导与面试模拟提升算法思维

这次我们来看一个专门为 LeetCode 刷题和面试准备设计的浏览器扩展工具。它不是一个需要本地部署的 AI 模型,而是一个直接集成在浏览器侧边栏的智能助手。核心功能非常直接:在你刷 LeetCode 时,它能在旁边提供苏格拉底式的引导提示&#xff0…

2026/8/16 3:58:09 阅读更多 →
云原生AI助手深度对比:AWS Q、Azure Copilot与国内CloudQ如何选型

云原生AI助手深度对比:AWS Q、Azure Copilot与国内CloudQ如何选型

1. 从“云原生AI助手”的混战说起:我们到底需要什么?最近几个月,云服务商在AI领域的动作密集得让人眼花缭乱。先是AWS在re:Invent大会上正式推出AWS Q,紧接着微软的Azure AI Studio和Azure Copilot也动作频频,而国内各…

2026/8/16 3:57:09 阅读更多 →
OpenClaw与Deepgram构建自动化语音转录工作流实战

OpenClaw与Deepgram构建自动化语音转录工作流实战

1. 项目概述:当笔记工具遇上语音智能最近在折腾一个挺有意思的自动化流程:把语音笔记自动转录成文字。核心工具是 OpenClaw 和 Deepgram。OpenClaw 你可能听说过,它是一个开源的、功能强大的自动化工作流平台,可以连接各种应用和服…

2026/8/16 3:57:09 阅读更多 →

日新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/16 0:00:54 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/16 0:00:55 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/16 0:03:55 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/16 0:00:54 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/16 0:00:55 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/16 0:03:55 阅读更多 →

月新闻

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

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

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

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

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

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

2026/8/14 14:06:45 阅读更多 →
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/15 2:35:29 阅读更多 →