Day17:LangChain Memory系统详解:让AI Agent拥有记忆,实现多轮对话
Day17LangChain Memory系统详解让AI Agent拥有记忆实现多轮对话一、引言在构建智能对话Agent时记忆Memory是决定其能否进行连贯对话的关键。没有记忆的Agent就像金鱼每次对话都从零开始无法理解“刚才提到的那个城市天气如何”这类上下文依赖的问题。LangChain提供了强大的Memory系统可以轻松为Agent添加短期和长期记忆能力。今天我们将深入探讨LangChain的Memory模块以通义千问Qwen大模型为例从零实现一个能记住对话历史的Agent。你将学会使用ConversationBufferMemory和ConversationSummaryMemory存储对话历史将Memory集成到Agent中实现多轮对话编写一个天气查询示例让Agent根据历史天气信息推荐着装使用StructuredTool替代简单的tool装饰器体验更灵活的工具定义方式所有代码均基于以下版本验证通过langchain 0.1.17 langchain-classic 1.0.3 langchain-community 0.0.38 langchain-core 0.1.53 langchain-text-splitters 0.0.2二、LangChain Memory 概述LangChain将记忆分为两类短期记忆在单个会话中存储对话历史如ConversationBufferMemory直接缓存所有消息。长期记忆对历史进行摘要或向量化存储如ConversationSummaryMemory定期总结对话减少token消耗。Memory模块的核心作用是在Agent调用LLM之前将历史对话注入到Prompt中让模型感知上下文。下图展示了Memory的工作流程Memory将历史消息附加到下一次LLM调用中三、环境准备首先安装所需依赖推荐使用虚拟环境pip install langchain0.1.17 langchain-community0.0.38 langchain-core0.1.53由于我们使用通义千问模型需要安装dashscopeSDKpip install dashscope在代码中导入必要的模块importosfromlangchain.memoryimportConversationBufferMemory,ConversationSummaryMemoryfromlangchain.agentsimportinitialize_agent,AgentTypefromlangchain.toolsimportStructuredToolfromlangchain_community.chat_modelsimportChatTongyi注意langchain-community中的ChatTongyi封装了通义千问API需配置环境变量DASHSCOPE_API_KEY获取方式阿里云控制台。四、初始化千问大模型# 设置API密钥建议从环境变量读取os.environ[DASHSCOPE_API_KEY]your-api-key-here# 创建千问模型实例llmChatTongyi(modelqwen-turbo,# 可选 qwen-turbo, qwen-plus, qwen-maxtemperature0.7,max_tokens1024)五、对话缓冲存储器ConversationBufferMemoryConversationBufferMemory是最简单的记忆形式它将所有对话消息按顺序存储并在每次调用时以字符串或消息列表的形式返回。5.1 基本用法memoryConversationBufferMemory(return_messagesTrue)# 保存用户消息和AI回复memory.save_context({input:你好},{output:您好有什么需要帮助的})memory.save_context({input:今天天气怎么样},{output:北京今天晴15-25℃})# 加载记忆变量print(memory.load_memory_variables({}))5.2 在链中使用通过load_memory_variables获取历史然后将其注入Prompt模板。六、对话摘要存储器ConversationSummaryMemory当对话非常长时ConversationBufferMemory会导致token超限。ConversationSummaryMemory通过LLM定期总结对话内容只保留摘要。summary_memoryConversationSummaryMemory(llmllm)summary_memory.save_context({input:你好},{output:您好})summary_memory.save_context({input:今天天气怎么样},{output:北京今天晴15-25℃})print(summary_memory.load_memory_variables({}))七、使用 StructuredTool 定义工具之前我们常用tool装饰器快速定义工具但StructuredTool提供了更强大的功能你可以显式定义输入参数的名称、类型、描述甚至返回值的schema。这对于复杂工具或需要精确控制参数描述的场景非常有用。下面我们用StructuredTool创建一个天气查询工具defget_weather_func(city:str)-str:根据城市名返回天气信息模拟数据city_weather{北京:晴15-25℃,上海:多云18-22℃,广州:阵雨20-26℃,深圳:多云转阴22-28℃}returncity_weather.get(city,暂无该城市天气信息)# 使用 StructuredTool.from_function 创建工具weather_toolStructuredTool.from_function(funcget_weather_func,nameget_weather,description根据城市名查询当前天气,# 可以指定参数schema可选# args_schema: 可以传入一个pydantic模型来定义参数)StructuredTool也可以直接实例化但from_function是最便捷的方式。八、将Memory集成到Agent中实现多轮对话接下来我们实战创建一个Agent它拥有天气查询工具并利用ConversationBufferMemory记住历史从而回答“适合穿什么衣服”这类依赖上下文的问题。8.1 初始化带记忆的Agent# 创建记忆实例返回消息格式便于Agent处理memoryConversationBufferMemory(memory_keychat_history,# 必须与Agent预期key一致return_messagesTrue)# 初始化Agentagentinitialize_agent(tools[weather_tool],# 使用StructuredTool创建的toolllmllm,agentAgentType.CONVERSATIONAL_REACT_DESCRIPTION,# 支持对话的Agent类型memorymemory,verboseTrue# 打印思考过程便于调试)关键点memory_key必须设置为chat_history因为CONVERSATIONAL_REACT_DESCRIPTION类型的Agent默认从该变量获取历史。8.2 测试多轮对话# 第一轮询问天气response1agent.run(今天北京天气怎么样)print(AI:,response1)# 第二轮基于天气提问response2agent.run(那适合穿什么衣服)print(AI:,response2)九、进阶使用 ConversationSummaryMemory 节省Token如果对话轮次非常多可以将memory替换为ConversationSummaryMemory但需要注意它返回的是字符串而非消息列表因此需要调整return_messagesFalsesummary_memoryConversationSummaryMemory(llmllm,memory_keychat_history,return_messagesFalse# 返回字符串摘要)agent_summaryinitialize_agent(tools[weather_tool],llmllm,agentAgentType.CONVERSATIONAL_REACT_DESCRIPTION,memorysummary_memory,verboseTrue)十、常见问题与注意事项Agent类型选择CONVERSATIONAL_REACT_DESCRIPTION专为对话设计它会自动将历史作为Prompt的一部分。如果使用ZERO_SHOT_REACT_DESCRIPTION需要手动拼接历史。Memory Key匹配确保memory_key与Agent期望的变量名一致通常是chat_history。StructuredTool vs toolStructuredTool提供了更丰富的参数定义能力例如你可以通过args_schema指定输入参数的pydantic模型从而实现自动验证和文档生成。而tool装饰器更简洁适合快速开发。版本兼容LangChain 0.1.x 中initialize_agent仍可用更高版本可能推荐使用create_react_agent函数。千问模型配置如果遇到超时或API错误检查网络环境和API密钥有效性。十一、总结与展望今天我们学习了LangChain的Memory系统并成功为千问Agent添加了记忆能力使其能够进行上下文关联的多轮对话。主要收获ConversationBufferMemory直接存储对话历史简单直观。ConversationSummaryMemory通过摘要压缩记忆适合长对话。通过memory参数将记忆注入Agent实现状态保持。使用StructuredTool定义工具体验更灵活的工具定义方式。附录完整可运行代码importosfromlangchain.memoryimportConversationBufferMemoryfromlangchain.agentsimportinitialize_agent,AgentTypefromlangchain.toolsimportStructuredToolfromlangchain_community.chat_modelsimportChatTongyi# 设置API密钥os.environ[DASHSCOPE_API_KEY]your-dashscope-api-key# 定义工具函数defget_weather_func(city:str)-str:根据城市名返回天气信息模拟数据weather_data{北京:晴15-25℃,上海:多云18-22℃,广州:阵雨20-26℃,深圳:多云转阴22-28℃}returnweather_data.get(city,暂无该城市天气信息)# 使用StructuredTool创建工具weather_toolStructuredTool.from_function(funcget_weather_func,nameget_weather,description根据城市名查询当前天气)# 初始化模型和记忆llmChatTongyi(modelqwen-turbo,temperature0.7)memoryConversationBufferMemory(memory_keychat_history,return_messagesTrue)# 创建Agentagentinitialize_agent(tools[weather_tool],llmllm,agentAgentType.CONVERSATIONAL_REACT_DESCRIPTION,memorymemory,verboseTrue)# 多轮对话if__name____main__:print(开始对话输入 quit 退出)whileTrue:user_inputinput(\n用户)ifuser_input.lower()quit:breakresponseagent.run(user_input)print(fAI{response})运行结果开始对话输入 quit 退出 用户今天上海天气怎么样 Entering new AgentExecutor chain... Thought: Do I need to use a tool? Yes Action: get_weather Action Input: 上海 Observation: 多云18-22℃ Thought:AI: 今天上海天气多云气温在18到22摄氏度之间比较舒适。 Finished chain. AI今天上海天气多云气温在18到22摄氏度之间比较舒适。 用户今天我适合穿什么衣服 Entering new AgentExecutor chain... Thought: Do I need to use a tool? No AI: 今天上海天气多云气温在18到22摄氏度之间属于温和舒适的初秋天气。建议穿着长袖衬衫、薄针织衫、薄外套或风衣等轻便透气的衣物下装可选长裤或薄款裙子搭配打底袜更稳妥。早晚稍凉可备一件薄外套以防温差。整体以“叠穿”为宜方便根据室内外温度灵活增减。 Finished chain. AI今天上海天气多云气温在18到22摄氏度之间属于温和舒适的初秋天气。建议穿着长袖衬衫、薄针织衫、薄外套或风衣等轻便透气的衣物下装可选长裤或薄款裙子搭配打底袜更稳妥。早晚稍凉可备一件薄外套以防温差。整体以“叠穿”为宜方便根据室内外温度灵活增减。