AI智能体长期记忆系统:从RAG到Memory-Skill的工程实践

AI智能体长期记忆系统:从RAG到Memory-Skill的工程实践 1. 项目概述一个关于“记忆”的AI技能最近在折腾AI智能体Agent和RAG检索增强生成相关的东西发现一个挺有意思的GitHub项目叫memory-skill。光看名字你可能会觉得这是个简单的“记忆”功能模块但实际深入进去你会发现它触及了当前AI应用落地的一个核心痛点如何让AI拥有持续、稳定且可管理的长期记忆能力。我们平时用的ChatGPT这类大模型本质上是“无状态”的。你每次开启一个新对话它就像一张白纸完全不记得你们之前的交流。虽然有些平台提供了“上下文”功能但那通常只是把过往的对话记录一股脑地塞进提示词Prompt里不仅效率低下、消耗大量Token而且当对话轮次一多模型很容易“忘记”最早的关键信息或者被中间大量的无关对话干扰。memory-skill这个项目就是试图系统性地解决这个问题。它不是简单地做聊天记录持久化而是设计了一套机制让AI能够像人一样对交互过程中的关键信息进行“摘要”、“提取”和“按需回忆”。这个项目特别适合两类朋友一类是正在开发AI聊天机器人、智能客服或者虚拟伙伴的开发者你需要你的AI角色能记住用户的偏好、历史约定等关键信息另一类是对RAG和Agent架构感兴趣的技术爱好者想了解如何在实际项目中为AI赋予“记忆”这一核心能力。接下来我就结合自己的实践和拆解带你彻底搞懂这个“记忆技能”的实现思路、核心细节以及如何把它应用到你的项目中。2. 核心设计思路从“全量上下文”到“智能记忆体”在深入代码之前我们必须先理解memory-skill想要替代的传统方案及其局限性这样才能明白它设计上的高明之处。2.1 传统方案的瓶颈上下文窗口的囚徒目前让AI拥有“记忆”最朴素的方法就是把整个对话历史都作为上下文输入。假设我们使用一个拥有128K上下文窗口的模型看起来能记住很多内容。但这种方法存在几个致命问题Token消耗与成本每一轮对话都需要将越来越长的历史记录发送给模型。这导致API调用成本线性增长响应速度也会因为需要处理更长的文本而下降。信息稀释与干扰并非所有历史对话都对当前问题有帮助。大量的寒暄、无关话题会稀释关键信息的浓度导致模型注意力分散甚至产生“幻觉”用早期不重要的信息来回答当前问题。关键信息丢失即使上下文窗口足够大模型在处理长文本时对位于序列中间或开头的信息的捕捉能力也会减弱。一个在对话第5轮提到的用户“对花生严重过敏”的关键信息可能在50轮后就被模型“忽略”了。缺乏结构化纯文本的历史记录只是一串流水账AI无法主动地对其进行分类、检索和关联。当你想问“我之前提到过哪些关于项目的截止日期”时模型无法快速定位只能重新阅读全文。memory-skill的设计哲学就是跳出“全量上下文”的思维定式构建一个外部的、结构化的、可管理的“记忆体”。2.2memory-skill的解决之道记忆的写入、存储与读取这个项目的核心思路可以类比为我们人类大脑处理记忆的方式我们不会像录像机一样记住每一帧画面而是会对经历的事件进行编码理解重点、存储放入长期记忆和检索在需要时回想。对应到memory-skill其工作流也分为三个核心环节记忆写入Encoding当一轮对话结束时系统不会保存完整的对话原文而是将这一轮或几轮对话交给一个“记忆生成器”通常也是一个AI模型进行处理。这个生成器的任务是从对话中提取出值得长期记忆的、结构化的信息。例如从“我下周五下午3点要和客户张三在星巴克开会讨论预算案”这句话中提取出{“实体”: “会议” “参与者”: [“我” “张三”] “时间”: “下周五15:00” “地点”: “星巴克” “主题”: “预算案”}。这就是一个记忆“条目”。记忆存储Storage将这些结构化的记忆条目存储到一个向量数据库如Chroma, Pinecone, Weaviate中。存储的不是原始文本而是条目的向量化嵌入Embedding。同时原始的记忆条目文本或更结构化的JSON也会被持久化到数据库或文件中方便精确召回。记忆读取Retrieval当新一轮对话开始时系统会将用户的当前查询或对话的当前状态也转化为向量然后去向量数据库中执行相似度搜索找出与当前语境最相关的几条历史记忆。最后将这些检索到的记忆条目作为补充上下文与当前的用户问题一起提交给主AI模型进行回答。这样一来无论对话进行了多少轮每次提交给主模型的“有效上下文”都是“当前问题 最相关的几条记忆”长度可控且信息高度相关、浓度高。这本质上是一个动态的、基于检索的上下文管理策略。3. 核心模块拆解与实操要点理解了宏观设计我们来看memory-skill具体是如何实现这几个环节的。虽然不同版本实现可能有差异但其核心模块万变不离其宗。3.1 记忆生成器从对话中提炼“金块”这是整个系统的“大脑”决定了记忆的质量。它的实现通常是一个精心设计的提示词工程Prompt Engineering任务。核心提示词设计示例你是一个记忆提取专家。请分析以下对话片段并提取出其中值得长期记忆的、关于人物、事实、偏好、任务或承诺的关键信息。 请以JSON格式输出包含以下字段如果存在 - “memory_text”: 对记忆的简洁自然语言描述。 - “entities”: 涉及的关键实体如人名、组织名、项目名。 - “memory_type”: 记忆类型如“personal_preference”个人偏好、“fact”事实、“todo”待办、“event”事件。 - “importance”: 重要性评分1-1010为最高。 对话片段 {conversation_chunk} 输出要求只输出JSON对象不要有其他任何解释。实操要点与避坑指南模型选择不一定需要GPT-4这样的顶级模型。GPT-3.5-Turbo、Claude Haiku 或开源的 Llama 3 8B 等模型在指令遵循和JSON格式输出上已经表现不错成本更低。关键在于提示词要清晰明确。对话分块不是每轮对话都生成记忆。通常有两种策略1)定时触发每N轮对话后将最近N轮内容打包发送给记忆生成器。2)事件触发检测到对话中包含明显的事实陈述、承诺或偏好表达时可通过关键词或另一个分类模型触发才启动记忆生成。重要性评分这个字段非常关键它决定了记忆的“保质期”和检索优先级。一个“用户喜欢喝美式咖啡”重要性6的记忆可能比“用户今天穿了蓝色衬衫”重要性1的记忆保存更久在相关场景下也更优先被召回。你可以在后续的存储和检索逻辑中利用这个评分。格式稳定性务必在提示词中强调“只输出JSON”并做好后处理。有时模型会输出 Markdown 格式的代码块或额外解释需要用代码进行清洗和校验确保解析成功。注意记忆生成是异步的、离线的。它不应该阻塞主对话流程。通常的做法是在主对话响应返回给用户后后台异步执行记忆生成和存储任务。3.2 记忆存储层向量数据库的选型与优化生成的记忆条目需要被存储以供检索。这里向量数据库是核心。主流选型对比数据库特点适用场景Chroma轻量、开源、易嵌入Python原生支持好适合快速原型和本地开发。个人项目、开发测试、对运维要求不高的场景。Pinecone全托管云服务无需运维性能稳定支持高级过滤。生产环境、团队项目、希望免去数据库运维负担。Weaviate开源功能强大自带模块化设计支持混合搜索向量关键词。需要高度定制化、复杂查询逻辑的中大型项目。Qdrant开源Rust编写性能优异Docker部署方便API与Pinecone兼容。追求性能、计划自托管且有一定运维能力的生产环境。实操配置要点嵌入模型选择存储和检索的向量来源于记忆文本的嵌入Embedding。常用的有OpenAI的text-embedding-3-small、Cohere的Embed模型或开源的BGE-M3、Snowflake Arctic Embed。选择时权衡效果、速度、成本。对于记忆检索嵌入模型对语义的理解深度比绝对精度更重要。元数据存储向量数据库不仅存储向量还能存储元数据。务必把memory_text、importance、memory_type、timestamp等作为元数据存进去。这样在检索时你不仅可以做向量相似度搜索还可以进行元数据过滤。例如“检索所有memory_type为personal_preference且importance 5 的记忆”。索引与分区随着记忆条目增多为所有记忆建一个大的索引可能效率低下。考虑按用户ID或会话ID进行分区。这样检索某个用户的记忆时只需要在其所属的分区内搜索速度更快也避免了用户间记忆混淆。记忆更新与淘汰记忆不是一成不变的。用户可能说“我最近不喜欢美式了改喝拿铁了”。你需要设计逻辑来处理记忆的更新。简单的做法是插入一条新的、重要性更高的记忆并在检索时优先取最新或重要性最高的。更复杂的可以设计真正的更新和逻辑删除。同时可以设定自动淘汰规则例如定期清理importance低于某个阈值且过旧的记忆。3.3 记忆检索器让相关记忆“随叫随到”检索环节决定了在回答当前问题时哪些历史记忆会被唤醒。这里不仅仅是简单的向量相似度计算。高级检索策略查询重写用户的当前问题可能很短比如“我上次说的会议时间是什么”。直接用这个问题去检索效果可能不好。可以先用一个轻量模型对查询进行重写和扩展使其包含更多上下文语义。例如重写为“用户询问之前约定过的会议的具体时间信息”。混合检索结合向量检索语义相似和关键词检索字面匹配。例如使用Weaviate的hybrid search或Elasticsearch与向量数据库结合。这对于精确匹配名称、日期等非常有效。递归检索与摘要有时单次检索到的多条记忆是碎片化的。可以引入一个“记忆总结”步骤先将检索到的Top K条相关记忆条目交给AI模型让其生成一个连贯、简洁的摘要再将这个摘要作为上下文。这能进一步压缩Token占用并提升信息质量。相关性评分与阈值为检索结果设置一个相似度分数阈值。低于这个阈值的记忆即使是最相似的结果也可能与当前问题无关强行加入上下文反而会造成干扰。这个阈值需要通过实验来确定。一个典型的检索代码片段伪代码def retrieve_memories(user_query, user_id, top_k5, importance_threshold3): # 1. 查询重写可选 enhanced_query query_rewriter(user_query) # 2. 生成查询向量 query_embedding embed_model.encode(enhanced_query) # 3. 向量数据库检索附带元数据过滤 results vector_db.query( query_embeddings[query_embedding], where_filter{ “user_id”: {“$eq”: user_id}, “importance”: {“$gte”: importance_threshold} }, n_resultstop_k * 2 # 多取一些供后续处理 ) # 4. 按综合分数相似度分 * 重要性权重排序 scored_memories [] for mem, sim in zip(results[‘metadatas’], results[‘distances’]): # 将距离转换为相似度分数假设使用余弦相似度距离越小越相似 similarity_score 1 - sim composite_score similarity_score * (mem[‘importance’] / 10.0) scored_memories.append({**mem, “composite_score”: composite_score}) scored_memories.sort(keylambda x: x[‘composite_score’], reverseTrue) # 5. 返回Top K条 return scored_memories[:top_k]4. 集成到AI智能体工作流memory-skill本身是一个“技能”它需要被集成到一个更大的AI智能体Agent框架中才能发挥作用比如 LangChain, LlamaIndex, AutoGen 或自定义的Agent循环。4.1 在对话循环中的集成点一个典型的、集成了记忆技能的AI对话循环如下用户输入用户发送消息。记忆检索系统调用retrieve_memories函数获取与当前用户输入最相关的历史记忆。构造提示词将检索到的记忆格式化后作为“长期记忆”或“相关背景”与系统指令、最近的短期对话历史最近3-5轮一起组合成最终发送给主AI模型的提示词。模型响应主AI模型基于这个富含上下文的提示词生成回答。记忆写入异步在将回答返回给用户的同时或之后系统将本轮或最近几轮对话内容送入后台的“记忆生成”管道进行异步处理并存储新的记忆。4.2 系统提示词设计示例如何将记忆自然地融入系统指令是关键一步。以下是一个增强版的系统提示词你是一个有帮助的AI助手。在与用户的对话中你可以利用以下“长期记忆”来提供更个性化和连贯的服务 长期记忆开始 {formatted_retrieved_memories} 长期记忆结束 此外以下是最近的对话历史 {short_term_conversation_history} 请基于以上所有信息回应用户的最新请求。如果长期记忆中的信息与近期对话冲突请以近期对话为准。格式化记忆 (formatted_retrieved_memories)的方式很重要。简单的做法是将每条记忆的memory_text用“- ”连接起来。更优的做法是标注来源例如“[记忆用户曾表示喜欢在咖啡中加一份浓缩]”。4.3 与“短期记忆”的协同这里要区分两个概念长期记忆由memory-skill管理结构化、持久化、可检索存储跨会话的核心信息。短期记忆/工作记忆通常就是最近几轮的原始对话历史直接放在上下文窗口里。它用于维持对话的即时连贯性。两者需要协同工作。短期记忆处理对话流长期记忆提供深度背景。在构造提示词时两者缺一不可。5. 实战部署与性能调优理论说再多不如实际跑起来。我们来看看部署memory-skill时需要关注的实际问题。5.1 技术栈选择与搭建一个最小可用的技术栈可能包括后端框架FastAPI 或 Flask用于提供API。AI模型接口OpenAI API, Anthropic Claude API或本地部署的 Ollama (运行 Llama 3 等开源模型)。向量数据库使用 Chroma 的本地模式最快上手生产环境考虑 Qdrant 或 Pinecone。任务队列由于记忆生成是异步的可以使用 Celery Redis或者更简单的 Pythonasyncio后台任务。存储记忆的原始文本和元数据除了存在向量库最好再用一个关系型数据库如SQLite, PostgreSQL存一份方便管理和复杂查询。5.2 参数调优与评估这是一个“没有标准答案”的领域需要根据你的具体场景进行实验和调优。关键参数包括记忆生成频率每轮都生成每3轮还是基于内容触发频率太高成本高且可能产生冗余记忆太低则可能遗漏关键信息。检索数量 (Top K)每次检索多少条记忆太少可能信息不全太多会占用上下文窗口并可能引入噪声。通常从3-5条开始测试。重要性阈值过滤掉低重要性记忆能提高检索质量。但这个阈值设多少合适相似度阈值低于多少分就算不相关不应该返回如何评估建立一个简单的测试集包含多轮对话。人工评估在关键问题点上AI的回答是否正确地运用了应有的历史记忆。可以设计一些“记忆挑战”问题比如在对话很后面突然问一个很早前提到的细节。通过调整上述参数观察回答准确率的变化。5.3 常见问题与排查实录在实际集成中你肯定会遇到下面这些问题问题1AI开始“胡言乱语”把不同用户的记忆混在一起了。排查检查向量数据库检索时的元数据过滤条件。确保user_id或session_id过滤条件被正确添加和应用。检查记忆生成时是否准确标记了所属用户。解决在数据存储和检索的每个环节都强制传递并验证用户身份标识。为每个用户在向量库中创建独立的集合Collection或分区Partition。问题2记忆似乎没有被用到AI的回答像是没看到记忆一样。排查首先检查记忆检索函数是否被正确调用并打印出实际检索到的记忆内容。检查这些记忆内容是否被正确地格式化并插入到了发送给主模型的最终提示词中。检查主模型的系统提示词是否明确指示了它去“使用”提供的长期记忆。有时候需要更强烈的指令如“你必须参考以下背景信息来回答问题”。解决在日志中完整记录每一轮的检索结果和发送给模型的完整提示词脱敏后进行对比分析。问题3生成了大量无用或重复的记忆把数据库塞满了。排查分析记忆生成器的输出。是不是提示词不够精确导致它把闲聊内容也当成了记忆检查importance字段的分布是否大部分都是低分解决优化记忆生成提示词强调提取“关键、持久、可操作”的信息。在存储前加入去重逻辑计算新记忆与已有记忆的向量相似度如果过高且重要性不如已有的则选择丢弃或合并。实现一个后台清理任务定期删除低重要性、过旧的记忆。问题4响应延迟明显变长。排查使用性能分析工具确定瓶颈在哪。是向量检索慢还是记忆生成慢调用大模型API解决向量检索慢确保向量数据库建立了合适的索引减少每次检索的Top K值考虑将向量库部署在离应用服务器更近的地方。记忆生成慢将记忆生成任务完全异步化确保绝不阻塞主响应链路。使用更快的模型如Haiku进行记忆生成。6. 进阶思考与扩展方向当你把基础版的memory-skill跑通后可以考虑下面这些进阶玩法让你的AI智能体变得更“聪明”。6.1 记忆的关联与推理目前的记忆是孤立的条目。能否让记忆之间产生关联例如识别到“项目A的负责人是张三”和“张三的邮箱是zhangsanxx.com”这两条记忆当用户问“怎么联系项目A的负责人”时系统能自动推理出答案。 这需要引入知识图谱的概念。在存储记忆时不仅存文本和向量还尝试解析出实体和关系构建一个小的图谱。检索时不仅能做语义搜索还能做图谱查询。6.2 记忆的主动提醒记忆不应该只是被动检索。可以设计一个“主动记忆”模块。例如系统存储了一条“用户下周五下午3点有会”。在每周五上午系统可以主动扫描记忆库中所有memory_type为event且时间在未来的条目然后主动给用户发送提醒“嗨根据我们的聊天记录提醒您今天下午3点有会议哦。” 这需要记忆存储中包含结构化的时间字段并有一个定时任务扫描器。6.3 多模态记忆记忆不只是文本。用户可能发了一张图片说“这是我家的猫”。目前的文本记忆系统很难处理这个。未来的方向是将图片通过多模态模型如GPT-4V进行描述生成文本记忆存储同时将图片的特征向量也存入专门的向量库。当用户提到“我的猫”时系统能同时检索到文本描述和图片特征甚至能生成一张类似的图片或进行更深入的对话。6.4 记忆的隐私与安全这是一个严肃的问题。长期记忆可能包含用户的个人信息、偏好甚至敏感数据。必须做到加密存储所有记忆在持久化到数据库前应进行加密。用户控制提供清晰的界面让用户查看、编辑和删除AI关于他的所有记忆。数据合规遵守相关数据保护法规明确告知用户数据如何被使用。安全检索确保检索接口有严格的权限验证防止越权访问他人记忆。7. 结语记忆是智能的基石折腾完memory-skill这个项目我最大的体会是为AI赋予记忆远不止是做一个“聊天记录保存”功能。它是一个系统工程涉及提示词工程、向量检索、异步任务、数据建模等多个技术点的融合。它迫使我们去思考什么是值得记忆的如何高效地记忆又如何精准地回忆这个项目的价值在于它提供了一个清晰、可实施的架构范式。你可以基于这个范式用不同的模型、不同的数据库去实现它并把它嵌入到你的聊天机器人、智能客服、数字员工或者任何需要长期上下文的AI应用中去。开始动手时建议从最简单的版本开始用 Chroma 存向量用 GPT-3.5 做记忆生成和主模型先实现核心的“记-存-取”循环。跑通之后再逐步加入重要性评分、元数据过滤、异步处理等高级特性。在这个过程中你会对AI智能体的“状态管理”有更深的理解。最后一个善意的提醒当你真的让AI记住了很多事情时请务必善待你的用户做好隐私保护。因为拥有记忆的AI不仅仅是一个工具它开始扮演一个更复杂的角色。技术实现很酷但负责任地使用技术更重要。