
本文是「LangChain Agent开发实战系列」的第2篇系列文章包含第1篇如何快速搭建企业级Agent第2篇LangChain核心模块详解Memory、Tools与Agents深入剖析本文第3篇LangChain实战从零构建一个RAG智能问答系统第4篇LangChain进阶LangGraph工作流编排与多Agent协作一、前言在上一篇文章中我们介绍了如何快速搭建一个企业级Agent。但要真正用好LangChain深入理解其核心模块是必不可少的。LangChain的设计哲学是组合优于继承通过模块化的组件开发者可以灵活地构建各种复杂的Agent应用。本文将深入剖析LangChain的三大核心模块Memory记忆、Tools工具和Agents智能体帮助你理解它们的工作原理、使用场景和最佳实践。二、Memory模块详解2.1 为什么需要记忆大语言模型LLM本身是无状态的——每一次调用都是独立的模型不会记住之前的对话内容。但在实际应用中我们往往需要Agent能够记住上下文比如多轮对话中记住用户之前说过的话记住用户的偏好和历史行为在任务执行过程中保存中间结果这就是Memory模块的作用它为Agent提供了记忆能力让Agent能够基于历史信息进行推理和决策。2.2 常见的记忆类型LangChain提供了多种记忆类型适用于不同的场景1. ConversationBufferMemory对话缓冲记忆最简单的记忆类型直接保存所有的对话历史。fromlangchain.memoryimportConversationBufferMemoryfromlangchain.llmsimportOpenAIfromlangchain.chainsimportConversationChain llmOpenAI(temperature0)memoryConversationBufferMemory()conversationConversationChain(llmllm,memorymemory,verboseTrue)# 第一轮对话conversation.predict(input你好我叫张三)# 输出你好张三很高兴认识你有什么我可以帮助你的吗# 第二轮对话conversation.predict(input我叫什么名字)# 输出你叫张三。优点简单直接信息完整缺点对话越长Token消耗越大可能超出模型上下文限制2. ConversationBufferWindowMemory窗口缓冲记忆只保留最近的K轮对话避免上下文无限增长。fromlangchain.memoryimportConversationBufferWindowMemory memoryConversationBufferWindowMemory(k2)# 只保留最近2轮conversationConversationChain(llmllm,memorymemory,verboseTrue)conversation.predict(input第一轮我喜欢苹果)conversation.predict(input第二轮我喜欢香蕉)conversation.predict(input第三轮我喜欢橙子)conversation.predict(input我喜欢什么水果)# 只会记住香蕉和橙子苹果会被遗忘优点控制Token消耗适合长对话缺点早期信息会丢失3. ConversationSummaryMemory摘要记忆使用LLM对对话历史进行摘要保存摘要而不是原始对话。fromlangchain.memoryimportConversationSummaryMemory memoryConversationSummaryMemory(llmllm)conversationConversationChain(llmllm,memorymemory,verboseTrue)# 随着对话进行记忆会自动生成摘要conversation.predict(input我想了解一下Python的基础语法)conversation.predict(input能给我举个例子吗)优点大幅减少Token消耗适合非常长的对话缺点会丢失细节每次生成摘要需要额外调用LLM4. ConversationSummaryBufferMemory摘要缓冲记忆结合了窗口记忆和摘要记忆的优点保留最近的K轮原始对话更早的对话则生成摘要。fromlangchain.memoryimportConversationSummaryBufferMemory memoryConversationSummaryBufferMemory(llmllm,max_token_limit1000# 超过1000token就开始摘要)优点平衡了信息完整性和Token消耗缺点实现相对复杂2.3 向量数据库记忆对于需要长期记忆或知识检索的场景可以使用向量数据库作为记忆存储fromlangchain.embeddingsimportOpenAIEmbeddingsfromlangchain.vectorstoresimportChromafromlangchain.memoryimportVectorStoreRetrieverMemory# 创建向量数据库embeddingsOpenAIEmbeddings()vectorstoreChroma(embedding_functionembeddings,persist_directory./memory_db)# 创建基于向量检索的记忆retrievervectorstore.as_retriever(search_kwargsdict(k3))memoryVectorStoreRetrieverMemory(retrieverretriever)# 保存记忆memory.save_context({input:用户的生日是1990年5月15日},{output:好的我记住了})memory.save_context({input:用户喜欢吃川菜},{output:了解})# 检索相关记忆print(memory.load_memory_variables({prompt:用户喜欢吃什么}))2.4 记忆模块选型指南记忆类型适用场景Token消耗信息完整度ConversationBufferMemory短对话、简单应用高完整ConversationBufferWindowMemory长对话、聊天机器人中部分最近K轮ConversationSummaryMemory超长对话、客服场景低摘要级ConversationSummaryBufferMemory平衡型、通用场景中低近期完整远期摘要VectorStoreRetrieverMemory长期记忆、知识库低相关度高的三、Tools模块详解3.1 工具的本质工具是Agent与外部世界交互的桥梁。如果说LLM是Agent的大脑那么工具就是Agent的手脚。通过工具Agent可以获取实时信息搜索引擎、API操作业务系统数据库、CRM执行计算代码解释器、计算器处理文件读写文档、表格3.2 内置工具使用LangChain内置了大量常用工具可以直接使用fromlangchain.agentsimportload_toolsfromlangchain.llmsimportOpenAI llmOpenAI(temperature0)# 加载内置工具toolsload_tools([serpapi,llm-math,python_repl],llmllm,serpapi_api_keyyour-serpapi-key)# 查看工具信息fortoolintools:print(f工具名:{tool.name})print(f描述:{tool.description})print(---)常用的内置工具包括serpapiGoogle搜索引擎llm-math数学计算python_replPython代码执行器requestsHTTP请求terminal终端命令执行wolfram-alpha知识计算引擎3.3 自定义工具更多时候我们需要为Agent创建自定义工具比如调用企业内部的API、查询数据库等。方式一使用tool装饰器fromlangchain.toolsimporttooltooldefget_employee_info(employee_id:str)-str: 根据员工ID查询员工信息。 Args: employee_id: 员工ID格式为EMP开头的字符串如EMP001 Returns: 员工的详细信息包括姓名、部门、职位等 # 这里可以连接数据库或调用APIemployee_db{EMP001:张三技术部高级工程师,EMP002:李四产品部产品经理,}returnemployee_db.get(employee_id,未找到该员工)tooldefcalculate_salary(base_salary:float,performance_score:float)-float: 计算员工的月度工资。 Args: base_salary: 基本工资 performance_score: 绩效评分0-1.5之间 Returns: 月度工资总额 returnbase_salary*performance_score# 使用自定义工具tools[get_employee_info,calculate_salary]方式二使用StructuredTool对于需要多个参数的复杂工具可以使用StructuredToolfromlangchain.toolsimportStructuredToolfrompydanticimportBaseModel,FieldclassQuerySalesInput(BaseModel):start_date:strField(description开始日期格式YYYY-MM-DD)end_date:strField(description结束日期格式YYYY-MM-DD)department:strField(description部门名称)defquery_sales_data(start_date:str,end_date:str,department:str)-str:查询指定时间段、指定部门的销售数据# 实际业务逻辑returnf{department}部门在{start_date}至{end_date}期间的销售额为100万元sales_toolStructuredTool.from_function(funcquery_sales_data,namequery_sales,description查询销售数据,args_schemaQuerySalesInput)3.4 工具调用原理Agent调用工具的过程可以分为以下几步理解用户意图Agent分析用户的问题判断是否需要调用工具选择工具根据工具描述选择最合适的工具生成参数从用户问题中提取工具所需的参数执行工具调用工具并获取结果整合结果将工具返回的结果整合到回答中这个过程通常是通过ReActReasoning Acting模式实现的我们会在Agents模块详细介绍。3.5 工具选择策略工具的描述description非常重要它直接影响Agent是否能正确选择和使用工具。一个好的工具描述应该清晰说明工具的功能说明参数格式和要求说明返回结果的格式说明适用场景和限制# 不好的描述tooldefquery_data(id:str)-str:查询数据...# 好的描述tooldefquery_order_info(order_id:str)-str: 根据订单号查询订单详细信息包括订单状态、金额、下单时间、收货地址等。 只有当用户提供了明确的订单号时才能使用此工具。 订单号格式为ORD开头的10位字符串如ORD20240101。 ...四、Agents模块详解4.1 Agent的工作原理Agent是LangChain的核心概念它的本质是使用LLM作为决策引擎动态选择和调用工具来完成任务。与Chain固定执行流程不同Agent具有自主性——它会根据用户的问题自主决定是否需要调用工具调用哪个工具按什么顺序调用调用几次4.2 ReAct模式详解ReActReasoning Acting是目前最主流的Agent工作模式。它的核心思想是让LLM像人类一样先思考Reasoning再行动Acting循环往复直到完成任务。一个典型的ReAct过程Thought: 我需要先查询今天的天气才能回答用户的问题。 Action: WeatherSearch Action Input: 北京 Observation: 北京今天晴温度25-32度空气质量优。 Thought: 我已经知道了北京的天气可以回答用户了。 Final Answer: 北京今天天气晴朗气温25-32度空气质量优适合户外活动。ReAct模式的优势可解释性强可以看到Agent的思考过程容错性好可以根据观察结果调整策略灵活性高可以处理复杂的、多步骤的任务4.3 常见Agent类型对比LangChain提供了多种Agent类型适用于不同场景Agent类型特点适用场景zero-shot-react-description零样本根据工具描述选择工具通用场景工具描述清晰react-docstore基于文档存储的ReAct文档问答、知识库检索self-ask-with-search自问自答搜索复杂问题分解conversational-react-description对话型支持记忆聊天机器人、多轮对话openai-functions基于OpenAI Function Calling使用OpenAI模型时推荐OpenAI Functions Agent推荐如果你使用的是OpenAI的模型如gpt-3.5-turbo、gpt-4推荐使用OpenAI Functions Agent它的效果更好、更稳定fromlangchain.chat_modelsimportChatOpenAIfromlangchain.agentsimportinitialize_agent,AgentTypefromlangchain.toolsimporttooltooldefget_weather(city:str)-str:查询指定城市的天气returnf{city}今天晴25度llmChatOpenAI(modelgpt-3.5-turbo,temperature0)tools[get_weather]agentinitialize_agent(tools,llm,agentAgentType.OPENAI_FUNCTIONS,verboseTrue)agent.run(北京今天天气怎么样)4.4 Agent选型指南优先使用OPENAI_FUNCTIONS如果你用的是OpenAI模型这是首选效果最好对话场景用CONVERSATIONAL_REACT_DESCRIPTION需要记忆和多轮对话时简单场景用ZERO_SHOT_REACT_DESCRIPTION工具少、任务简单时复杂任务考虑自定义Agent标准Agent无法满足需求时五、三大模块协同工作理解了Memory、Tools、Agents各自的作用后我们来看它们是如何协同工作的用户输入 → Agent大脑 ↓ 思考需要什么工具 ↓ 选择工具 → 执行工具 → 获取结果 ↓ 思考还需要其他工具吗 ↓ 是 → 继续调用工具 否 → 生成最终回答 ↓ 保存到Memory记忆 ↓ 返回给用户5.1 完整示例让我们来看一个完整的例子展示三大模块如何协同工作fromlangchain.chat_modelsimportChatOpenAIfromlangchain.memoryimportConversationBufferMemoryfromlangchain.agentsimportinitialize_agent,AgentType,toolfromlangchain.chainsimportConversationChain# 1. 初始化LLMllmChatOpenAI(modelgpt-3.5-turbo,temperature0)# 2. 定义工具tooldefsearch_product(keyword:str)-str: 搜索商品信息输入关键词返回相关商品列表。 支持按名称、类别搜索。 products{手机:iPhone 15 Pro - 7999元\n华为Mate 60 - 6999元,电脑:MacBook Pro - 14999元\nThinkPad X1 - 12999元,}returnproducts.get(keyword,f未找到{keyword}相关商品)tooldefcheck_stock(product_name:str)-str: 查询商品库存输入商品名称返回库存状态。 stock{iPhone 15 Pro:有货预计次日送达,华为Mate 60:缺货预计7天后到货,}returnstock.get(product_name,f未查询到{product_name}的库存信息)# 3. 初始化记忆memoryConversationBufferMemory(memory_keychat_history,return_messagesTrue)# 4. 创建Agentagentinitialize_agent(tools[search_product,check_stock],llmllm,agentAgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,memorymemory,verboseTrue,agent_kwargs{system_message:你是一个电商客服助手帮助用户查询商品信息和库存。 你可以使用搜索商品工具查找商品使用查询库存工具确认库存状态。 如果用户问的问题你不确定先搜索再回答。})# 5. 使用Agentprint(用户你们有什么手机推荐吗)responseagent.run(你们有什么手机推荐吗)print(f助手{response})print(\n用户iPhone 15 Pro有货吗)responseagent.run(iPhone 15 Pro有货吗)print(f助手{response})print(\n用户我刚才问的是什么手机来着)responseagent.run(我刚才问的是什么手机来着)print(f助手{response})在这个例子中Tools提供了商品搜索和库存查询的能力Memory记住了用户之前问过的问题Agent作为大脑协调工具和记忆完成用户的请求5.2 最佳实践工具设计原则每个工具只做一件事保持单一职责工具描述要清晰、准确参数和返回值要有明确的格式说明记忆使用原则根据对话长度选择合适的记忆类型敏感信息不要存在记忆中定期清理无用的记忆Agent优化技巧精心设计System Prompt明确Agent的角色和能力提供好的工具描述这比你想象的更重要对于复杂任务考虑使用多Agent架构六、总结本文深入剖析了LangChain的三大核心模块Memory记忆为Agent提供上下文能力有多种类型可选需要根据场景权衡信息完整度和Token消耗Tools工具Agent与外部世界交互的桥梁可以使用内置工具或自定义工具工具描述的质量直接影响Agent效果Agents智能体LangChain的核心通过ReAct模式实现思考-行动的循环自主决策完成任务这三大模块不是孤立的而是协同工作的Agent作为大脑使用工具作为手脚依靠记忆来保持上下文共同构成了一个完整的智能体系统。在下一篇文章中我们将进入实战环节手把手教你从零构建一个RAG检索增强生成智能问答系统敬请期待