从0到1:AI Agent开发全方面指南——第五天:Agent架构之Memory(记忆能力设计)
第五天Agent架构之Memory记忆能力设计前面我们已经学习了ReAct循环的前三个组件规划器(Planner)生成推理路径推理痕迹执行器(Executor)协调执行行动工具集(Tools)调用外部能力观察本章节讲解最后一个组件记忆体(Memory)——存储历史观察、中间结果和任务进度。完成Memory的学习后您将对ReAct模式有完整理解记忆能力是Agent的知识库负责存储和检索信息。一、什么是Agent的记忆记忆就是存储信息并在需要时能够回忆起来。对AI Agent来说用户与它交互产生的所有内容都是它的记忆。实战例子有无记忆的区别无记忆的Agent有记忆的Agent每次对话都像第一次见面记住你之前说过的话不知道你的喜好记得你喜欢什么、讨厌什么无法连续对话能接上之前的话题二、Agent的三层记忆Agent的记忆模仿人类分为三层记忆层相当于人类的存放什么存放多久感官记忆感觉记忆刚输入的文本、图像等毫秒级一用完就忘短期记忆短期记忆当前对话的上下文本次会话会话结束就清空长期记忆长期记忆用户偏好、历史知识、业务数据永久保存随时可查重要信息召回用户输入感官记忆短期记忆上下文窗口长期记忆向量数据库为什么需要长期记忆LLM的上下文窗口就那么大比如4K、128K tokens装不下无限多的内容。长期记忆就像给Agent配了一个外接硬盘把需要记住的东西都存起来用的时候快速查出来。来源CSDN-Agent记忆系统四层架构四、滑动窗口记忆管理短期记忆会随着会话结束而清空但我们可以采用滑动窗口策略管理记忆。常见的记忆管理策略有三种全量记忆是保留所有历史对话适合上下文长度可控的短对话滑动窗口是仅保留最近N轮对话适合长对话多轮交互摘要记忆是定期压缩总结历史适合超长对话资源受限的情况。实战例子滑动窗口 vs 全量记忆假设有10轮对话全量记忆会保留全部10轮而滑动窗口保留3轮的话就只能看到第8-10轮。如果是100轮对话差距就更明显了全量记忆要处理全部100轮而滑动窗口只需要关注最近的3轮。这种设计能有效控制上下文长度防止LLM的输入溢出。代码示例sliding_window_memory.pyclassSlidingWindowMemory: 滑动窗口记忆管理器 核心思想只保留最近N轮对话模拟人类短期记忆 适用于长对话场景防止上下文溢出 def__init__(self,window_size5): 初始化滑动窗口 参数 window_size: 保留的对话轮数默认5轮 self.window_sizewindow_size self.history[]# 完整的对话历史self.short_term[]# 短期记忆滑动窗口内的defadd_message(self,role,content): 添加一条消息 参数 role: 角色user/assistant content: 消息内容 message{role:role,content:content}# 添加到完整历史self.history.append(message)# 添加到短期记忆self.short_term.append(message)# 如果短期记忆超限移除最老的iflen(self.short_term)self.window_size:self.short_term.pop(0)defget_context(self): 获取当前上下文用于发送给LLM 返回 短期记忆中的对话列表 returnself.short_termdefget_full_history(self): 获取完整历史用于存入长期记忆 返回 完整对话历史列表 returnself.history# 使用示例memorySlidingWindowMemory(window_size3)# 添加对话memory.add_message(user,我想去北京旅游)memory.add_message(assistant,北京3天推荐行程Day1天安门故宫...)memory.add_message(user,帮我订机票)memory.add_message(assistant,为您找到以下航班...)memory.add_message(user,推荐酒店)memory.add_message(assistant,北京五星级酒店推荐...)# 获取上下文只看最近3轮contextmemory.get_context()print(f短期记忆{len(context)}条消息)# 获取完整历史存入向量数据库full_historymemory.get_full_history()print(f完整历史{len(full_history)}条消息)来源CSDN-从0到1掌握Agent记忆8种方案五、向量数据库让记忆能模糊查找向量数据库就是让Agent能够模糊查找记忆的技术。什么是向量简单理解把一句话、一段文字转化成一串数字这串数字就是向量。实战例子向量的好处搜索词传统数据库向量数据库“首都的天气”找不到北京天气能找到因为语义相似“上次去旅游的事”找不到具体某次对话能找到相关的记忆来源向量数据库原理参考 Redis《AI Agent Memory》架构设计redis.io/blog/ai-agent-memory-stateful-systemsEmbedding是什么Embedding就是把文本转成向量的过程。就像把一本书的内容缩略成一本书的名字方便快速查找。实战例子Embedding的比喻现实例子相当于Embedding地图用颜色和等高线表示真实地形书签用几个字标记一大段内容压缩包把大文件变小方便存储传输六、RAG让Agent能查资料RAG检索增强生成是让Agent从向量数据库中查找相关内容然后结合上下文回答问题的技术。查出来存进去相似度搜索相关文档文档切块转成向量向量数据库用户问题转成向量上下文生成答案RAG能做什么查企业知识库、产品文档阅读PDF、联网搜索新闻基于历史对话回答问题来源RAG技术由Lewis等人在2020年提出arXiv:2005.11401七、代码示例代码示例vector_db_rag.py# # 向量数据库与RAG实现# fromlangchain.vectorstoresimportChromafromlangchain.embeddingsimportOpenAIEmbeddingsfromlangchain.text_splitterimportRecursiveCharacterTextSplitter# 1. 把知识存进向量数据库defstore_knowledge(docs): 知识入库文档 - 分块 - 转向量 - 存数据库 embeddingsOpenAIEmbeddings()# 文本转向量的模型text_splitterRecursiveCharacterTextSplitter(chunk_size1000,# 每1000字符切一块chunk_overlap200# 块与块之间重叠200字符保持连续性)# 分割文档chunks[]fordocindocs:splitstext_splitter.split_text(doc)chunks.extend(splits)# 存入向量数据库vectorstoreChroma.from_texts(textschunks,embeddingembeddings,persist_directoryknowledge_db# 存到本地文件夹)vectorstore.persist()returnvectorstore# 2. 从向量数据库查询相关记忆defretrieve_memories(query,vectorstore,top_k5): 查询问题 - 转向量 - 相似度搜索 - 返回最相关的几条 docsvectorstore.similarity_search(query,ktop_k)return\n.join([doc.page_contentfordocindocs])# # 使用示例# if__name____main__:# 存知识docs[苹果是一种水果,苹果公司成立于1976年,苹果有丰富的营养]vectorstorestore_knowledge(docs)# 查记忆resultretrieve_memories(苹果是什么,vectorstore)print(result)# 输出苹果是一种水果、苹果有丰富的营养语义相关的都被找到了