资讯动态

大模型记忆系统设计:从上下文窗口到Agent长期记忆的完整指南

发布时间:2026/10/20 13:45:43 来源:尧图企业网站定制
你和一个大模型聊天聊到第二十轮它突然又问一遍你最开始告诉过它的名字和口味偏好。那一刻你会觉得它像条金鱼——明明刚才聊得热火朝天转头就全忘了。先别急着怪它大模型本身确实没有“长期记忆”每次对话能用到的只有上下文窗口里那点文本窗口之外全是空白。最近我把一套记忆系统装进了自己的Agent小Demo里效果可以说是yyds它不再反复问我同一个问题能主动调用历史信息还表现出一种“我记着你”的稳定感。这篇文章就和你聊聊这类记忆系统到底怎么设计最小可用版本怎么搭出来以及为什么说理解了记忆系统你就摸到了Agent架构师的门槛。1. 为什么大模型天生是“金鱼记忆”三个关键原因1.1 上下文窗口决定了它只能活在“当下”理解大模型的记忆问题首先要看它跑起来的基本方式。模型本质上是一个文本预测器你把“用户历史提问助手历史回复当前问题”拼成一段文本塞进它的输入它再根据这段文本生成下一个词。这一段文本的允许上限就是上下文窗口常见的有几千、几万甚至几十万个Token。Token简单理解成“词的碎片”一个汉字可能占1到2个Token。窗口一大就能放下更多历史窗口一缩小放不下的历史就会被无情截断。这个截断不是“选择性遗忘”而是物理层面的丢失模型永远不会知道前面到底聊了什么。1.2 “金鱼记忆”的三个典型痛点我在实际体验中把这种“金鱼记忆”带来的难受拆成了三条第一多轮对话里的关键信息会反复丢失。比如用户第3轮说了“我家里有老人需要安静模式”第20轮再聊到音响设置时模型已经完全没有这个概念。它不是不关心你是真的没有地方存放。第二用户得不停做重复劳动。你每换个新会话或者对话一长就得重新介绍一遍自己的背景、偏好、约束条件。长期下来使用体验会非常割裂你和大模型的关系永远停在“初次见面”。第三模型无法从过去交互中积累经验。它每一次回复都是“一次性”的上次怎么解决问题下次遇到类似问题还是从零开始不会变得更聪明。这就导致很多看起来很智能的功能落地到真实场景里性能就打了折扣。1.3 从记忆角度重新理解Agent“Agent”这个词这两年特别火但很多人一上来就想着规划、调用工具、自我反思直接把架构搞复杂了。我自己的体会是想让Agent真正“自主”记忆是绕不开的第一步。没有记忆的Agent每一步都像失忆的人在做决策——它可能知道怎么写代码但它不记得用户已经说过自己用的是Windows也不记得上一轮已经尝试过哪些方案。有了记忆Agent才能把过去的状态、偏好、执行结果带进当前决策里。所以与其说是“搞一个Agent”不如先“搞一套记忆系统”这才是真正迈入Agent架构师身份的入口。2. 记忆系统的核心设计从数据模型到五大模块2.1 记忆系统不神秘五个模块就能说清给大模型装记忆系统听上去很高大上拆开之后其实就是五个核心模块写入模块从对话或任务中提取值得记的信息理解什么该记什么不该记。存储模块把记忆以结构化的方式保存下来可以存在本地文件、数据库也可以存在向量检索工具里。检索模块当新问题到来时从存储中挑出最相关的那几条记忆塞回大模型的上下文。更新模块对已有记忆做修正、合并、衰减或删除防止信息过时。反馈模块根据生成结果的效果反过来调节记忆的重要度形成闭环。这五个模块拆开后我们做的每一样事情都变得可控制了。我在做模拟项目X时就是先按这个五模块思路做了一版跑了大概一个月发现很多问题出在不同模块的衔接上比如写入时记了太多噪音检索时就容易被误导但整体架构没有变过。2.2 用“人的记忆”做类比立刻就能懂记忆系统怎么设计我特别喜欢用人类记忆来类比。人有“感觉记忆”“工作记忆”“长期记忆”放进大模型场景里我们是把记忆系统分成两层的工作记忆 上下文窗口。当前对话历史、当前任务状态、临时的中间结果都放在这里。它很小、很快、用完就走。长期记忆 外部存储。那些跨越会话仍然需要保留的信息比如用户偏好、领域知识、历史经验都放到这里。它很大、很慢、需要主动检索才能调出来。人类想不起某件事时不会把一辈子所有记忆都翻一遍而是顺着线索回忆。大模型的长期记忆也一样不能一股脑把全部历史都塞进上下文而是要用检索手段把“相关记忆”唤起。这个“唤起”的质量基本决定整个系统的智商。2.3 记忆的数据结构应该长什么样别一上来就直接往数据库里怼文本。我见过很多初学的朋友把“记忆”等价于“聊天记录”然后写个函数把全部聊天记录拼进Prompt最后发现又贵又乱。真正好用的记忆应该是结构化的条目每个条目至少包含这些字段字段作用示例唯一ID支持修改、删除m_1024内容文本记忆点的可读表达用户偏好美式咖啡不加糖向量表示用于语义相似度检索[0.1, 0.5, …]时间戳记录写入和最后访问时间2025-01-20 10:30重要性分数控制记忆的留存优先级0.1~1.0关联标签快速过滤和分组咖啡、偏好、用户访问次数体现记忆被使用的频率7次我有一次就是因为在设计表结构时少加了“关联标签”结果检索时经常把用户关于“咖啡”的偏好跟品牌“咖啡”新功能的说明混在一起。后来补上标签字段召回准确率才明显提上来。数据结构想清楚后面所有模块都会轻松很多。3. 30分钟搭一个最小可用记忆系统附代码3.1 技术选型的现实考量很多人一听到“记忆系统”就想到要引入向量数据库、编排框架、各种重工具。实际上最小可用版本完全可以靠一个JSON文件加几十行代码跑起来。重点不是工具选得有多重而是逻辑链路有没有通。我建议分三种情况个人Demo、学习实验用内存字典或本地JSON文件即可逻辑简单方便逐步调试。小规模业务用关系型数据库存元数据另外加一个向量检索能力比如开源向量索引库重点数据落库。大规模生产才需要考虑分布式向量检索、缓存、持久化和高可用。我的经验是先跑通最小闭环再谈扩展。不要一开始就在架构上炫技后面调试问题时会把自己劝退。3.2 核心流程写入、检索、更新、遗忘一个记忆系统的核心流程可以用四句话提炼写入从当前对话中抽取“值得记住的信息”转为向量保存。检索拿当前问题转成向量去存储里找最相似的一批记忆。更新当用户修改偏好时旧记忆要被覆盖或标记为失效。遗忘长期未被使用且重要度不高的记忆定期清理。这个流程不是一次性做死的而是每次对话结束后都反复运行。3.3 代码一个极简的实现思路下面这套代码不是我空想出来的是我在模拟项目X里最早跑通的骨架核心逻辑只用了几十行。import time from dataclasses import dataclass, field from typing import List, Callable dataclass class Memory: content: str vector: list None importance: float 0.5 created_at: float time.time() last_access: float time.time() access_count: int 0 tags: List[str] field(default_factorylist) class MemorySystem: def __init__(self, embed_func: Callable): self.memories [] self.embed embed_func def remember(self, content: str, importance: float 0.5, tags: List[str] None): vec self.embed(content) self.memories.append( Memory(contentcontent, vectorvec, importanceimportance, tagstags or []) ) def recall(self, query: str, top_k: int 3, threshold: float 0.75): q_vec self.embed(query) scored [] for mem in self.memories: score cosine_similarity(q_vec, mem.vector) if score threshold: scored.append((score, mem)) scored.sort(reverseTrue, keylambda x: x[0]) return [mem for _, mem in scored[:top_k]] def forget_old(self, max_age_days: int 30, min_importance: float 0.2): now time.time() self.memories [ m for m in self.memories if (now - m.last_access) / 86400 max_age_days or m.importance min_importance ]这里故意隐去了embedding函数、余弦相似度的具体实现因为它们取决于你选用的模型和工具。重点是记忆系统骨架长这样能写、能忆、能忘。3.4 如何接到大模型上让它像换了个脑子记忆系统有了怎么接到大模型核心就一步构造Prompt时把检索到的记忆和当前对话一起传过去。def build_prompt(query: str, history: List[str], memory_sys: MemorySystem): memory_text \n.join(- m.content for m in memory_sys.recall(query)) history_text \n.join(history[-6:]) # 只取最近6轮控制长度 return f[已知记忆]\n{memory_text}\n\n[对话历史]\n{history_text}\n\n[用户]\n{query}这样大模型的上下文里就多了一块“记忆先导知识”相当于在开始推理前先唤起相关经验。实测下来它在回答时明显更愿意复用历史信息也更能保持前后一致。另外一个容易忽略的点写入也要交给大模型做一次提炼。不要直接把整段聊记原文存进去而是给大模型一个提示词把“用户偏好、事件事实、状态变化”抽取成一句话。比如对话里用户说“我不太吃辣”就存成“用户不吃辣饮食偏好清淡”这样后续检索更精准。4. 从记忆系统到Agent架构师补上这几块拼图4.1 记忆不只是存取更是决策的原料很多朋友觉得记忆系统就是个“数据库”那是太小看它了。Agent的每一次决策本质上都是“感知 记忆 推理”的组合。没有记忆Agent就只剩下“感知 推理”每步都是一次独立计算无法形成连续策略。举个例子一个任务型Agent要帮用户写一份月度总结它需要知道前几周做过哪些任务哪些已经完成哪些被用户取消了。这些状态信息如果不在记忆里Agent就会漏掉重要内容甚至编造不存在的进度。只有把任务状态、用户反馈、工具执行结果都写进记忆Agent的决策才能站在历史数据上而不是凭空想象。4.2 规划、工具调用、记忆三者的配合我理解Agent架构时最有效的模型是一个三层循环理解与检索拿到用户目标先从记忆中找出相关信息作为本次决策的上下文。规划与执行大模型根据上下文制定步骤调用外部工具比如代码执行器、数据查询、文件操作得到结果。记录与更新执行结果、错误信息、用户反馈全部写回记忆并调整重要度。这套循环里记忆是贯穿始终的。规划需要记忆提供背景工具调用结果需要记忆保存状态错误处理需要记忆避免重蹈覆辙。如果你只是把记忆系统当作一个独立模块而不把它嵌进Agent主循环那它永远只是“能记住聊天记录的聊天机器人”。4.3 小白也能用的“架构师思考法”我自己也是从小白阶段过来的刚开始听“Agent架构”总觉得很遥不可及。后来发现一个特别管用的思考框架用厨师做菜来类比Agent。菜谱 记忆里面记录了做菜的步骤、注意事项、上次成功的经验。食材 数据和工具没有食材厨师无从下手。厨师 大模型负责看菜谱、处理食材、做菜。每做一道新菜后的心得 更新记忆下次再做会更快更好。你不需要一开始就把整家餐厅的平台搭好。先把“菜谱”设计好也就是记忆系统再把“食材”准备齐也就是工具接口最后让“厨师”动起来一个Agent的雏形就已经出来了。这种思考方式让我从“只会调API”很快过渡到“能设计一个小型Agent系统”。5. 我给记忆系统装“外脑”时踩过的坑都在这里了5.1 记忆污染检索回来一堆错误的不算什么关键是你还很难察觉最常踩的坑就是“记忆污染”。一开始我把对话里所有内容都塞进记忆结果检索时经常命中一些边角料信息反而把真正重要的用户意图淹没了。后来我加了两个筛子。一个是相关性阈值相似度低于某个值就不召回另一个是信息类型过滤只保留“用户偏好”“事实陈述”“任务状态”三类忽略寒暄、语气词和重复内容。加了这些之后Prompt里的噪音明显变少生成质量也上了一个台阶。5.2 过时信息记忆不能只进不出“用户说喜欢美式两周后他说最近开始喝冷萃了”如果记忆系统不更新模型还会继续推荐美式这就叫过时信息。最基础的办法是给每条记忆标注写入时间和最后访问时间检索时按时间衰减权重越老的记忆可信度越低。更精确一点的做法是当检测到新的信息与旧记忆冲突时主动生成一条“旧记忆失效”的记录或者直接把旧条目标记为失效。我试过在写入模块里加一个“冲突检测”提示词让大模型判断新记忆是否颠覆旧记忆效果不错就是会多花费一点Token但值得。5.3 成本与延迟别把记忆系统变成玩具嵌入Embedding调用和向量搜索都会带来额外延迟和成本如果每一步都实时做全量检索系统会非常慢。我的做法是二级混合先用关键词或标签快速过滤圈定一个小候选集。再对候选集做向量相似度排序。这样既能保证精度又能大幅减少计算量。还有一个经验是记忆的“写入”可以异步化不阻塞主对话流程。把对话回复先返回给用户后台再慢慢抽取记忆、写入存储体验上完全无感。5.4 隐私与边界记忆能力也要有底线记忆系统保存了大量用户个人信息这不是可以随意处理的。我在项目里至少做了三件事给用户提供“清除全部记忆”的入口支持按标签删除特定记忆敏感信息单独加密不参与普通检索。这里特别提醒一下不要把所有用户原文都永久保存尤其是涉及身份、地址、资金的信息。尽量在写入前做脱敏处理或者只保存抽象化后的偏好与结论。给AI装记忆既要像人一样记得住也要懂得分寸。6. 实战Demo一个会记住用户偏好的小助手6.1 场景设定我在模拟项目X里做过一个极简的“日常偏好助手”演示记忆系统的价值。场景非常简单用户进行多次对话助手需要记住用户的称呼、饮食偏好、日程安排并在后续对话中主动使用。第一次对话用户说“我叫阿白平时喜欢喝美式工作日早上9点开会。”助手当时正常回复同时后台提取出三条记忆用户称呼阿白。饮品偏好美式咖啡。工作日固定事项早上9点开会。这些记忆进入存储后无论用户下次什么时候回来甚至新开一个会话只要问一句“帮我推荐明天早上的饮料”系统就能检索到“美式咖啡”和“9点开会”给出更贴合的回答。6.2 关键环节演示数据流是这样的用户输入 → 大模型抽取记忆 → 写入记忆系统 → 用户再次访问 → 检索相关记忆 → 构造Prompt → 大模型回答核心抽取逻辑可以用提示词完成从对话中提取所有可以长期保留的用户信息包括但不限于用户称呼、偏好、固定日程、家庭成员、重要约束。 只输出结构化条目每条不超过20个字。如果没有新信息输出“无”。实测下来这个简单提示词就能工作得不错。之后在检索时加上“记忆先导”片段回复的个性化程度很直观地变高了。比如用户在说“今天来杯咖啡”时助手会敏锐地加上一句“还是按你平时的习惯来杯美式吗”6.3 从Demo到生产环境还差几步这个Demo能跑通但离生产还有不小的距离。至少还差这些持久化把内存里的记忆落盘防止服务重启就丢失。扩展性支持多个用户之间的数据隔离防止串记忆。评测机制定义“记忆准确率”“召回利用率”不断迭代抽取和检索策略。运维监控记录记忆条目的写入来源、访问热度、失真情况方便排查问题。一个小Demo帮我们验证了思路真正的生产系统则更像是一个持续进化的产品。不要因为Demo简单就觉得不过如此你把它跑通一次就已经站在Agent架构师的门槛上了。最后再分享一点个人体会。我在把记忆系统塞进自己的Agent之后最大的感触不是代码量多少而是它让我一下子理解了对话与决策的关系。之前总觉得“Agent”离自己很远直到发现记忆这块想明白了规划、工具调用、自我纠错这些大词都会自然落地。如果你也在搭自己的Agent建议先别急着堆复杂框架从一套几十行的记忆模块起步把“写入—存储—检索—更新—遗忘”这条闭环跑通你会有一种“原来我也可以做架构设计”的踏实感。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑