AI Agent长期记忆系统设计:从上下文窗口到向量检索的实践

发布时间:2026/10/20 3:44:58
AI Agent长期记忆系统设计:从上下文窗口到向量检索的实践 最近我在折腾一个开源AI个人助理框架——先叫它ClawKit吧项目名不重要重要的是它背后那套记忆体系让我眼前一亮。过去大模型应用最让我头疼的问题就是“聊完就忘”你前两天才告诉它你养了一只叫年糕的猫今天它就能一本正经地问你养没养过宠物。这种体验放在客服、陪聊、个人助理场景里完全没法接受。ClawKit的做法是把对话历史、用户画像、知识笔记分开管理再配合向量检索让模型在每次回答前主动“回忆”相关内容。说白了就是给大模型装一个可以读写的“大脑外挂”。这篇文章适合两类人被多轮对话一致性折磨的开发者以及想给自己的AI Agent加长期记忆的产品经理。我把这套记忆体系的架构、实现细节和踩坑记录整理出来照着做你也能让模型拥有“数字生命”。1. 先把问题说透大模型为什么“记不住事”1.1 上下文窗口的天花板很多人刚接触大模型开发时第一反应是既然模型记不住那我每次把历史聊天记录全塞进上下文窗口不就行了这个思路没错但撑不久。以常见的商用大模型API为例上下文窗口通常是32K、128K token。看着很大换算成中文大概是几千到几万字。可是一旦对话轮次多起来比如一个用户连续用了半天AI助理光是聊天记录就可能超过窗口长度。更别提Agent场景下还要塞工具调用结果、检索到的文档片段、系统提示词。强行截断历史记录会导致另一个问题模型“失忆断层”。前面聊到一半的方案后面对话完全接不上用户必须重复说明。而且长上下文的token费用不是开玩笑的按千token计价的话每次请求都带一大堆历史成本会指数级上涨。我在早期版本里就干过这种“暴力拼接”的事把所有聊天记录拼成一个messages数组塞给模型。结果就是响应越来越慢、费用越来越高、用户体感却越来越差。窗口上限就像电脑内存你不可能让所有程序都常驻内存得有存储、有淘汰、有索引。1.2 聊完就忘背后的“人格分裂”记忆缺失不只影响效率更影响体验。“人格分裂”这个词听着玄其实每个做对话产品的开发者都撞见过。昨天用户说“我女儿叫糖糖今年5岁”今天模型问“你有孩子吗”用户明确说过“我不吃香菜点餐别推荐”结果模型还是推荐了香菜料理。这种不一致在单轮对话里不容易暴露但在跨天、跨会话的长期使用场景中极其致命。用户会明显感觉到这个AI没有把我当成熟人它每次都是陌生人。深层原因是大模型本身没有任何持久状态。你调用的那一刻它就是一张白纸加上你喂给它的内容。没有记忆机制AI就不可能形成“连续的人格”——所谓的“数字生命”也就无从谈起。1.3 长期记忆到底缺什么要解决“记不住”不是简单把历史存下来。长期记忆体系至少得具备三个能力写入对话过程中产生的关键信息能被结构化提取并保存。检索面对新的问题能从海量记忆中快速找回相关片段。整合新旧记忆冲突时怎么处理过时的记忆怎么遗忘/覆盖。这三个能力缺一个记忆体系就是残废的。只保存不检索等于建了个没人查的档案库只检索不整合模型会被互相矛盾的记忆搞糊涂。ClawKit这套方案最让我认可的地方就是它把这三个能力拆成了清晰的模块而不是一锅粥地存个聊天记录SQLite了事。下面的内容我会逐个拆解。2. 记忆体系整体设计把人的记忆机制搬进AI2.1 三层记忆架构工作记忆、短期记忆、长期记忆参考认知科学里人的记忆分层这套体系把AI记忆分成了三层工作记忆Working Memory当前上下文窗口里正在处理的信息。对应的是最近几轮对话、正在执行的工具调用结果、当前任务状态。短期记忆Short-term Memory当前会话内、但已滑出窗口的内容。通过摘要压缩保留核心信息会话结束后进入长期记忆。长期记忆Long-term Memory跨会话持久化存储的用户画像、事实信息、历史事件、知识笔记。可以按用户ID隔离。三层结构最大的好处是职责清晰。工作记忆管“当下”短期记忆管“本节”长期记忆管“一生”。不同层级的存储介质也不同工作记忆在模型上下文里短期记忆在Redis或内存缓存长期记忆在数据库或文件系统。我在设计自己的Agent时直接抄了这个三层模型。一开始总觉得分层麻烦觉得不如一个列表搞定。但实际跑下来分层对资源消耗的降低非常明显——你不再需要把所有历史都塞给模型只需要动态调取最相关的一小部分。2.2 为什么分层而不是一个超大记忆文件有人会问那我直接把所有记忆写到一个大文件里每次检索不也行吗技术上确实行但工程上会崩。原因有三点。第一单个超大文件会让检索失效。向量检索需要把记忆切块后embedding如果一条记忆块太大、太混杂embedding的语义就不准确检索效果直线下降。第二更新成本高。用户改了偏好你是改某一条记录还是重写整个文件不分层的话“改一条小的”往往变成“重建整个索引”。第三权限和隔离难做。一个家庭场景里有爸爸、妈妈、孩子三个人共用同一个AI记忆必须按身份隔离。不分层不隔离就会出现爸爸的偏好干扰妈妈的对话这种灾难。ClawKit的记忆文件实际采用了“按用户分区 按类型分类”的结构。用户在关系型数据库或本地文件中有一个ID所有记忆条目都带user_id字段读取时强制过滤。类型上区分为fact事实、preference偏好、event事件、note笔记。事实和事件类的记忆写入时还会带上时间戳方便后续做时间线回溯。2.3 记忆的写入、读取、归档三通道记忆系统的核心是三条数据流写入链路对话轮次完成后后台任务提取关键信息用另一个LLM调用做信息抽取结构化后写入长期记忆库。读取链路用户新消息进来先做query改写/嵌入然后从记忆库检索topK条相关记忆注入系统提示词或上下文前缀。归档链路短期记忆达到阈值后触发摘要摘要写入长期记忆原始逐字记录按策略清理或压缩。写入链路的一个关键设计是“异步处理”。用户发消息时主流程必须先保证响应速度不能等记忆提取完成才回复。一般用队列或定时任务做对话结束、间隔几分钟、或积累到N条后再触发一次记忆抽取。我最初犯的错就是在请求链路里同步等记忆写入每次回复多了好几秒延迟体验很糟。3. 核心模块拆解与实现细节3.1 会话记忆把窗口“压缩”成摘要短期记忆的落地方式是会话摘要session summary。当对话轮次超过阈值比如30条消息系统会触发一次摘要将窗口内前20条的核心内容压缩成一个总结然后用总结替换原始消息。摘要的质量直接决定记忆体系的效果。这里分享一下我踩出来的经验摘要别只让模型自由发挥要给模板。比如固定要求输出“用户信息...当前项目进展...未解决问题...情绪/偏好...”。结构化模板能显著提高摘要的信息密度和后续检索命中率。摘要时机要“懒触发”。每次对话都做摘要会造成大量无用计算建议在会话空闲后比如用户2分钟没发消息或消息条数达到阈值时再做。阈值我试过20、30、50最终觉得30比较合适——太早摘要会丢细节太晚则窗口压力大。会话摘要本身也要有“生命周期”。今天的会话摘要明天就可能变成长期记忆里的一条普通记录不能再当作工作记忆来用。这个过期机制金字塔上端不放下面讲长期记忆时会具体说。3.2 长期记忆向量检索与语义召回长期记忆是这套体系的重头戏。它解决的核心问题面对一条新消息如何从过去所有记忆中找出相关的部分。方案是“语义检索 关键字兜底”。先把记忆条目切块每条控制在200-500字左右然后用embedding模型转成向量存入向量数据库。新消息过来同样转成向量做余弦相似度检索取topK5~8条。同时做一个简单的BM25关键字检索兜底因为embedding偶尔会对专有名词不敏感比如人名、地名、项目代号。embedding模型的选择我在实操中比较过几类方案商用API的embedding接口效果最稳对中文理解好缺点是调用有延迟和费用。本地开源的嵌入模型隐私性好、零成本但中文语义理解差一些需要挑一个好一点的版本。轻量级方案比如哈希分词后BM25完全不用模型适合快速原型但语义能力有限只建议做兜底。ClawKit默认跑的是“商用API向量化 本地BM25兜底”的混合策略。这个组合实测下来召回质量比纯向量检索高不少。原因是中文里很多记忆条目是人物和事件名称BM25精确匹配反而比语义相近更可靠。3.3 记忆整合与遗忘机制记录会积累也会过时。没有清理机制的记忆库用久了会变成一锅粥。比如用户去年说“我在学吉他”今年已经不学了。如果旧记忆一直在检索结果里模型会反复提及过时信息非常尴尬。这套系统处理记忆冲突的方式我给的建议是“信任新记忆 标注时间戳”。具体来说每一条记忆都带created_at和updated_at字段。当新记忆和旧记忆指向同一个主题通过语义相似度或同Key识别系统默认用新记忆覆盖旧记忆但保留历史版本到归档表。检索结果排序时时间衰减因子参与计算。太老的记录比如超过90天降权除非用户显式提及。遗忘机制我用了一个简单但有效的策略置为低活跃度而非物理删除。把很少被检索命中的记录标记为inactive不进默认检索范围。这样既能控制噪音又保留了数据万一后续要回溯还能翻出来。3.4 记忆文件结构与状态持久化ClawKit在本地用JSONLJSON Lines格式存储记忆每行一条JSON记录。之所以不用标准JSON数组是因为JSONL可以流式追加不会因为文件变大而需要整体读写。备份、日志管道处理也更方便。一个典型的记忆条目长这样{ id: mem_fact_0001, user_id: user_8899, type: fact, content: 用户养了一只名叫年糕的猫两岁英短。, created_at: 2026-01-08T11:20:00Z, updated_at: 2026-01-08T11:20:00Z, last_hit_at: 2026-01-08T14:00:00Z, hit_count: 3, vector_id: vec_0001, status: active }如果换成了SQLite或PostgreSQL结构也类似。关键是字段别省last_hit_at和hit_count是遗忘算法的基础type决定检索时的权重比如preference类型在推荐场景里权重要调高status控制是否进入活跃检索。4. 实操配置15分钟跑通第一版记忆系统4.1 环境准备与依赖安装先说环境。我跑这套系统的机器配置是CPU 8核、内存16GB、无独立GPU操作系统是Ubuntu 22.04。没有GPU完全够用因为重活都甩给API。依赖清单大致如下Python 3.10一个向量数据库本地用Chroma或sqlite-vss体验生产可以用Qdrant/pgvectorembedding模型的API或本地库一个对话模型APIRedis可选用于短期缓存安装阶段比较快的路径是直接建虚拟环境用pip装向量库客户端和HTTP框架几分钟搞定。如果本地部署embedding模型需要多装一个模型运行库下载模型权重这一块稍微久一点。我建议第一次做原型时直接用API版embedding先跑通流程再考虑本地化替换。4.2 记忆模块配置文件示例我用的是YAML配置结构简单看着直观。给你一个精简版作为模板memory: mode: hybrid short_term: max_messages: 30 summary_trigger_idle_seconds: 120 summary_template: summary_template_v2 long_term: store: chroma collection_name: user_memory embedding_model: text-embedding-3-small embedding_dim: 1536 top_k: 6 similarity_threshold: 0.55 retrieval: use_bm25: true bm25_weight: 0.3 forget: time_decay_days: 90 min_hit_count: 2几个关键参数我展开说一下similarity_threshold是检索的“及格线”。低于这条线的记忆不会被召回。我试过0.5、0.55、0.6、0.7最后定在0.55-0.6。设置太高0.7很多相关的记忆被过滤掉太低0.4大量无关信息会混进来污染上下文。top_k控制在5-8之间比较合适。太多会挤占上下文太少则可能漏掉关键记忆。bm25_weight是关键词检索结果的混合系数。0.3听起来不大但往往能精准救回embedding漏掉的专有名词。4.3 如何配置提示词让模型“利用”记忆有了记忆检索能力还不够模型得把检索到的记忆用起来。这就需要在系统提示词里做明确引导。我用的系统提示词片段是这样的你是一个AI个人助理。在回答前请优先参考以下关于用户的记忆信息。 如果记忆信息与当前问题相关你应该基于记忆回答如果记忆中没有相关信息 可以直接回答并说明“我不记得这一点”。 【用户记忆】 {memory_context}注意{memory_context}替换为检索到的记忆摘要列表而不是把所有原始记忆都塞进去。每条记忆格式化如下- [2026-01-05] 用户偏好日常通勤时间约40分钟喜欢听播客 - [2026-01-03] 事实用户养猫名字叫年糕只给与当前问题相关的5-6条剩下的留给“不知道就说不知道”。这个引导词能让模型明显减少胡编乱造也避免它把无关记忆硬扯进回答。4.4 用一套真实对话验证记忆效果配置好了怎么验证有没有生效我建议做一个20轮的跨天模拟对话测试。第一天对话内容用户我叫阿杰你帮我记录一下我最近在准备迁居到杭州。AI好的已记录。用户我喜欢喝手冲咖啡尤其是耶加雪菲豆。AI明白已加入偏好记忆。第二天对话内容新会话不带第一天历史用户早上好还记得我吗AI记得你叫阿杰最近在准备迁居杭州。你偏好耶加雪菲的手冲咖啡今天想喝点什么建议吗如果能做到第二段这种连续感记忆系统就算通了。我测试时还故意问了一句“我养了什么宠物”来检验事实回忆如果回答“我不记得”且检索没召回就需要检查embedding和检索链路了。5. 常见问题与排查实录5.1 记忆不生效先查检索链路还是写入链路这是最容易踩的第一个坑。现象是明明保存了记忆模型回答时却完全没用上。排查顺序建议按“写入 → 检索 → 注入 → 调参”四步走。写入先查数据库看对话后有没有新增记忆记录。没有写入说明摘要/抽取任务没触发成功。常见原因是异步任务崩了而且没有重试机制。检索手动拿一条新消息去测检索接口看返回topK里有没有相关记忆。没有说明embedding或者阈值有问题。注入确认检索到的记忆确实被拼到了系统提示词里。我见过有人检索模块写好了但忘了在最终prompt模板里引用memory_context变量。调参如果上面都正常但模型依然无视记忆检查提示词里是否明确要求“基于记忆回答”。很多模型会优先听用户最新指令记忆信息的优先级需要在系统提示词里强调。我最初就卡在第四步记忆明明检索到了但模型觉得那只是参考信息不是必须遵守的事实。后来我改了提示词加了一句“当记忆信息与用户当前说法矛盾时用户当前说法优先但你可以提示存在冲突”。这样既保证了时效性又不至于让模型被旧记忆带偏。5.2 检索答非所问问题出在“切块”和“向量化”有时候保存和注入都正常但检索出来的记忆跟问题八竿子打不着。多半是切块策略或者向量化环节出了问题。切块太大一条记忆里混了多个主题embedding的语义重心会被稀释。比如一条记忆写“用户喜欢篮球和话剧周一休息”三个不相关信息检索“用户周末想干什么”时这条记忆因为“周一休息”相关而被召回实际上携带了大量无关噪音。解决办法是让写入阶段的信息抽取更“原子化”一条记忆只表达一个事实或偏好。宁可用10条细记忆也不用1条大杂烩记忆。检索时可以多召回几条但每条都是精准的。向量化环节还有一个常见坑换了embedding模型但没有重新向量化旧数据。新旧向量分布不一致检索效果会严重退化。如果你切换了embedding模型务必对历史记忆做一次全量重建索引。5.3 记忆膨胀与上下文污染用了一段时间后记忆越来越多系统开始把大量记忆注入上下文导致模型回答被“污染”——比如用户问今天天气模型却絮叨起三个月前聊过的旅游计划。这是典型的“过度召回”。破解思路有几个收紧阈值把similarity_threshold从0.5调到0.62过滤掉弱关联记忆。限制条数和总量注入的记忆条数上限设为5条每条不超过500字。按type加权天气类问题只召回“event/note”类型不召回preference和历史偏好避免无关记忆抢占权重。还要注意记忆注入的上下文也占用token成本。我用一个计数变量对注入的记忆做预算管理比如每次请求只留800 token给记忆区域超出部分按相关性截断。5.4 隐私与数据安全本地存储的边界给AI“长期记忆”这件事天然伴随隐私风险。记忆库里有用户的姓名、作息、偏好甚至健康信息存本地相对安全但一旦接入云端或共享就要做严格的访问控制。实操层面的经验敏感信息脱敏在记忆抽取阶段就对关键词做模糊化。比如把手机号中间四位替换成星号只保留完整手机号的最后一个引用。按用户隔离所有记忆查询强制带user_id禁止跨用户检索。测试时我常用一个超级管理员账号去查看全局记忆结果不小心把A用户记忆带进了B用户的上下文这个坑必须从一开始就堵死。导出一键清除给用户提供“清除全部记忆”的按钮。这不仅是合规要求也是信任建设。我维护的一个社区版本里有用户明确要求“你们可以记住我的偏好但我要随时能一键删掉”。还有一个细节容易被忽略记忆系统的日志文件里往往包含原始对话内容。如果日志被上传到第三方监控平台等于变相泄露用户隐私。建议在日志输出前对消息体打码只保留消息级别信息和分析元数据不保留全文。5.5 长周期记忆“漂移”时间衰减调参心得最后给一个隐藏比较深的坑。跑了一个多月后系统会发现自己遗忘了一些其实很重要的内容或者反复记住了一些早该过时的内容。问题出在时间衰减参数上。我把time_decay_days设置得太短30天导致一条“用户正在找工作”这种中长期事实在40天后就被降权用户再次提及时模型表现得很陌生。调参建议把时间衰减周期调到90天以上但配合“持续活跃”机制——也就是hit_count较高的记忆即使时间久也不降权。让“被反复提到的事实”拥有更长生命周期。用户的工作变动、搬家的偏好只要还常用就不该被时间淘汰。如果你发现某些类型的记忆总是过早失效建议按type单独设置不同的衰减策略。比如“preference”类型衰减慢“event”类型衰减快这样体系就更像人的记忆了——习惯很难忘一次性事件很快就淡忘了。最后再分享一个小技巧我个人在实际操作中最受益的一条经验是别一开始就追求“完美记忆”先把闭环跑通再说。很多人上手就想把记忆系统的召回精度做到95%以上结果把大量时间花在调embedding和阈值上反而忽略了记忆体系最基础的短板——写入链路稳定不稳定、数据格式规范不规范、提示词有没有引导模型使用记忆。先把这三点做扎实哪怕检索策略糙一点用户体验都会有质的提升。另外记忆体系的迭代建议“对话驱动”。每次用户抱怨AI记性差就复现当时的对话把失败案例变成一条测试集。我目前维护了一个memory_regression_cases文件里面记录了几十个历史失败场景。每次改动记忆模块就跑一遍回归测试确保修了A问题不会搞坏B场景。这个习惯让我少踩了很多坑也推荐你试试。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询