07 工具调用实战一、什么是工具调用工具调用Tool Calling让 LLM 能够调用外部函数获取实时信息或执行操作。场景工具示例作用查询天气get_weather(city)获取实时天气搜索网页search_web(query)获取最新信息计算数学calculator(expression)精确计算数据库查询query_db(sql)查询业务数据发送邮件send_email(to, content)执行操作二、工具定义方式2.1 使用 tool 装饰器推荐 tool 装饰器定义工具 运行方式python 07_tool装饰器.py fromlangchain_core.toolsimporttooltooldefget_weather(city:str)-str:获取指定城市的天气信息 Args: city: 城市名称如北京、上海 # 模拟天气查询weather_data{北京:晴天25°C,上海:多云28°C,深圳:阵雨30°C}returnweather_data.get(city,f未找到{city}的天气信息)tooldefcalculator(expression:str)-str:计算数学表达式 Args: expression: 数学表达式如23*4 try:resulteval(expression)returnf计算结果:{expression}{result}exceptExceptionase:returnf计算错误:{str(e)}# 查看工具信息print(f工具名称:{get_weather.name})print(f工具描述:{get_weather.description})print(f参数模式:{get_weather.args_schema.model_json_schema()})# 直接调用工具resultget_weather.invoke({city:北京})print(f调用结果:{result})2.2 使用 StructuredTool StructuredTool 定义复杂工具 运行方式python 07_structured_tool.py fromlangchain_core.toolsimportStructuredToolfrompydanticimportBaseModel,Field# 定义参数模式classSearchInput(BaseModel):query:strField(description搜索关键词)max_results:intField(default5,description最大结果数)# 创建工具函数defsearch_web(query:str,max_results:int5)-str:搜索网页获取信息# 模拟搜索results[f结果{i}: 关于{query}的内容foriinrange(1,max_results1)]return\n.join(results)# 创建 StructuredToolsearch_toolStructuredTool.from_function(funcsearch_web,nameweb_search,description搜索网页获取最新信息,args_schemaSearchInput,return_directTrue# 直接返回结果不经过 LLM 处理)# 调用resultsearch_tool.invoke({query:LangChain教程,max_results:3})print(result)2.3 从函数自动创建工具 从函数自动创建工具 运行方式python 07_自动创建工具.py fromlangchain_core.toolsimportcreate_retriever_toolfromlangchain_community.vectorstoresimportFAISSfromlangchain_openaiimportOpenAIEmbeddings# 假设已有向量数据库vectorstoreFAISS.from_texts([LangChain是大模型应用框架,LangGraph用于构建Agent],OpenAIEmbeddings())# 自动创建检索工具retriever_toolcreate_retriever_tool(vectorstore.as_retriever(),namesearch_knowledge_base,description搜索知识库获取相关信息)print(retriever_tool.name)print(retriever_tool.description)三、Agent Tools 完整流程 Agent Tools 完整示例 运行方式python 07_agent_tools.py fromlangchain_openaiimportChatOpenAIfromlangchain_core.toolsimporttoolfromlangchain.agentsimportAgentExecutor,create_tool_calling_agentfromlangchain_core.promptsimportChatPromptTemplate# 1. 定义工具tooldefsearch_database(query:str)-str:搜索产品数据库 Args: query: 搜索关键词 # 模拟数据库查询products{手机:iPhone 15, 华为Mate 60, 小米14,电脑:MacBook Pro, ThinkPad X1, Dell XPS,耳机:AirPods Pro, Sony WH-1000XM5, Bose QC45}forkey,valueinproducts.items():ifkeyinquery:returnf找到相关产品:{value}return未找到相关产品tooldefget_price(product_name:str)-str:获取产品价格 Args: product_name: 产品名称 prices{iPhone 15:7999元,华为Mate 60:6999元,MacBook Pro:14999元}returnprices.get(product_name,价格未知)# 2. 创建提示词promptChatPromptTemplate.from_messages([(system,你是一个产品查询助手可以帮助用户查询产品信息和价格。),(human,{input}),(placeholder,{agent_scratchpad})# Agent 中间思考过程])# 3. 创建 LLMllmChatOpenAI(modelqwen-plus,temperature0)# 4. 创建 Agenttools[search_database,get_price]agentcreate_tool_calling_agent(llm,tools,prompt)# 5. 创建 AgentExecutoragent_executorAgentExecutor(agentagent,toolstools,verboseTrue,# 打印执行过程handle_parsing_errorsTrue# 处理解析错误)# 6. 运行responseagent_executor.invoke({input:有哪些手机价格多少})print(f最终回答:{response[output]})四、错误处理最佳实践 工具调用错误处理 运行方式python 07_错误处理.py fromlangchain_core.toolsimporttoolfromlangchain.agentsimportAgentExecutor,create_tool_calling_agentfromlangchain_openaiimportChatOpenAIfromlangchain_core.promptsimportChatPromptTemplatetooldefrisky_api_call(query:str)-str:调用可能失败的外部API Args: query: 查询参数 try:# 模拟可能失败的 API 调用iferrorinquery.lower():raiseValueError(API 返回错误)returnf查询成功:{query}exceptExceptionase:# 返回友好的错误信息让 LLM 理解发生了什么returnf查询失败:{str(e)}。请告知用户该服务暂时不可用。# 创建带重试的 AgentExecutorpromptChatPromptTemplate.from_messages([(system,你是一个助手。 如果工具调用失败请 1. 解释发生了什么错误 2. 建议用户稍后重试 3. 提供替代方案如果有的话),(human,{input}),(placeholder,{agent_scratchpad})])llmChatOpenAI(modelqwen-plus)agentcreate_tool_calling_agent(llm,[risky_api_call],prompt)agent_executorAgentExecutor(agentagent,tools[risky_api_call],verboseTrue,handle_parsing_errorsTrue,# 自动处理解析错误max_iterations3,# 最多重试 3 次early_stopping_methodgenerate# 提前停止时生成总结)# 测试错误场景responseagent_executor.invoke({input:查询 error test})print(f回答:{response[output]})五、并行工具调用 并行工具调用 运行方式python 07_并行调用.py fromlangchain_openaiimportChatOpenAIfromlangchain_core.toolsimporttoolfromlangchain.agentsimportAgentExecutor,create_tool_calling_agentfromlangchain_core.promptsimportChatPromptTemplatetooldefget_weather(city:str)-str:获取天气returnf{city}: 晴天 25°Ctooldefget_news(topic:str)-str:获取新闻returnf{topic}最新消息: 无重大新闻tooldefget_stock(symbol:str)-str:获取股价returnf{symbol}当前价格: ¥150.00# 创建支持并行调用的 LLMllmChatOpenAI(modelqwen-plus,temperature0)promptChatPromptTemplate.from_messages([(system,你可以同时查询多个信息。),(human,{input}),(placeholder,{agent_scratchpad})])agentcreate_tool_calling_agent(llm,[get_weather,get_news,get_stock],prompt)agent_executorAgentExecutor(agentagent,tools[get_weather,get_news,get_stock],verboseTrue,max_iterations5)# LLM 可能会并行调用多个工具responseagent_executor.invoke({input:请同时告诉我北京天气、科技新闻和茅台股价})print(f回答:{response[output]})六、自定义 Agent 类型Agent 类型特点适用场景create_tool_calling_agent支持原生工具调用OpenAI、通义千问等create_react_agentReAct 推理框架需要详细推理过程create_structured_chat_agent结构化输出复杂参数传递 ReAct Agent 示例 运行方式python 07_react_agent.py fromlangchain.agentsimportcreate_react_agent,AgentExecutorfromlangchain_openaiimportChatOpenAIfromlangchain_core.toolsimporttoolfromlangchain_core.promptsimportChatPromptTemplatetooldefsearch(query:str)-str:搜索信息returnf搜索结果:{query}的相关信息# ReAct 提示词模板react_promptChatPromptTemplate.from_template( Answer the following questions as best you can. You have access to the following tools: {tools} Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{tool_names}] Action Input: the input to the action Observation: the result of the action ... (this Thought/Action/Action Input/Observation can repeat N times) Thought: I now know the final answer Final Answer: the final answer to the original input question Begin! Question: {input} Thought:{agent_scratchpad} )llmChatOpenAI(modelqwen-plus)agentcreate_react_agent(llm,[search],react_prompt)agent_executorAgentExecutor(agentagent,tools[search],verboseTrue,handle_parsing_errorsTrue)responseagent_executor.invoke({input:什么是LangGraph})print(f回答:{response[output]})七、工具调用 vs 直接调用维度工具调用直接调用灵活性LLM 自动决定何时调用代码中硬编码调用时机参数LLM 自动提取参数手动解析参数适用场景用户输入多变、需要智能判断固定流程、确定性调用可靠性可能调用错误工具100% 确定调用哪个工具调试需要打印中间过程代码流程清晰最佳实践简单场景用直接调用用户输入多变用工具调用关键操作用直接调用 人工确认八、常见问题Q1: 工具调用失败怎么办agent_executorAgentExecutor(agentagent,toolstools,handle_parsing_errorsTrue,# 自动处理解析错误max_iterations3,# 限制重试次数early_stopping_methodgenerate# 提前停止时生成总结)Q2: 如何防止 LLM 误调用危险工具工具命名清晰用search_xxx而不是do_something描述准确在 description 中明确说明用途和限制权限控制敏感操作需要人工确认Human-in-the-loopQ3: 如何优化工具调用性能减少工具数量只提供必要的工具描述精简避免冗长的工具描述缓存结果相同参数返回缓存结果相关笔记[[05-Agents智能体]] · [[06-多轮对话记忆]] · [[11-LangGraph/01-LangGraph概述与快速入门|LangGraph]]
07 工具调用实战
07 工具调用实战一、什么是工具调用工具调用Tool Calling让 LLM 能够调用外部函数获取实时信息或执行操作。场景工具示例作用查询天气get_weather(city)获取实时天气搜索网页search_web(query)获取最新信息计算数学calculator(expression)精确计算数据库查询query_db(sql)查询业务数据发送邮件send_email(to, content)执行操作二、工具定义方式2.1 使用 tool 装饰器推荐 tool 装饰器定义工具 运行方式python 07_tool装饰器.py fromlangchain_core.toolsimporttooltooldefget_weather(city:str)-str:获取指定城市的天气信息 Args: city: 城市名称如北京、上海 # 模拟天气查询weather_data{北京:晴天25°C,上海:多云28°C,深圳:阵雨30°C}returnweather_data.get(city,f未找到{city}的天气信息)tooldefcalculator(expression:str)-str:计算数学表达式 Args: expression: 数学表达式如23*4 try:resulteval(expression)returnf计算结果:{expression}{result}exceptExceptionase:returnf计算错误:{str(e)}# 查看工具信息print(f工具名称:{get_weather.name})print(f工具描述:{get_weather.description})print(f参数模式:{get_weather.args_schema.model_json_schema()})# 直接调用工具resultget_weather.invoke({city:北京})print(f调用结果:{result})2.2 使用 StructuredTool StructuredTool 定义复杂工具 运行方式python 07_structured_tool.py fromlangchain_core.toolsimportStructuredToolfrompydanticimportBaseModel,Field# 定义参数模式classSearchInput(BaseModel):query:strField(description搜索关键词)max_results:intField(default5,description最大结果数)# 创建工具函数defsearch_web(query:str,max_results:int5)-str:搜索网页获取信息# 模拟搜索results[f结果{i}: 关于{query}的内容foriinrange(1,max_results1)]return\n.join(results)# 创建 StructuredToolsearch_toolStructuredTool.from_function(funcsearch_web,nameweb_search,description搜索网页获取最新信息,args_schemaSearchInput,return_directTrue# 直接返回结果不经过 LLM 处理)# 调用resultsearch_tool.invoke({query:LangChain教程,max_results:3})print(result)2.3 从函数自动创建工具 从函数自动创建工具 运行方式python 07_自动创建工具.py fromlangchain_core.toolsimportcreate_retriever_toolfromlangchain_community.vectorstoresimportFAISSfromlangchain_openaiimportOpenAIEmbeddings# 假设已有向量数据库vectorstoreFAISS.from_texts([LangChain是大模型应用框架,LangGraph用于构建Agent],OpenAIEmbeddings())# 自动创建检索工具retriever_toolcreate_retriever_tool(vectorstore.as_retriever(),namesearch_knowledge_base,description搜索知识库获取相关信息)print(retriever_tool.name)print(retriever_tool.description)三、Agent Tools 完整流程 Agent Tools 完整示例 运行方式python 07_agent_tools.py fromlangchain_openaiimportChatOpenAIfromlangchain_core.toolsimporttoolfromlangchain.agentsimportAgentExecutor,create_tool_calling_agentfromlangchain_core.promptsimportChatPromptTemplate# 1. 定义工具tooldefsearch_database(query:str)-str:搜索产品数据库 Args: query: 搜索关键词 # 模拟数据库查询products{手机:iPhone 15, 华为Mate 60, 小米14,电脑:MacBook Pro, ThinkPad X1, Dell XPS,耳机:AirPods Pro, Sony WH-1000XM5, Bose QC45}forkey,valueinproducts.items():ifkeyinquery:returnf找到相关产品:{value}return未找到相关产品tooldefget_price(product_name:str)-str:获取产品价格 Args: product_name: 产品名称 prices{iPhone 15:7999元,华为Mate 60:6999元,MacBook Pro:14999元}returnprices.get(product_name,价格未知)# 2. 创建提示词promptChatPromptTemplate.from_messages([(system,你是一个产品查询助手可以帮助用户查询产品信息和价格。),(human,{input}),(placeholder,{agent_scratchpad})# Agent 中间思考过程])# 3. 创建 LLMllmChatOpenAI(modelqwen-plus,temperature0)# 4. 创建 Agenttools[search_database,get_price]agentcreate_tool_calling_agent(llm,tools,prompt)# 5. 创建 AgentExecutoragent_executorAgentExecutor(agentagent,toolstools,verboseTrue,# 打印执行过程handle_parsing_errorsTrue# 处理解析错误)# 6. 运行responseagent_executor.invoke({input:有哪些手机价格多少})print(f最终回答:{response[output]})四、错误处理最佳实践 工具调用错误处理 运行方式python 07_错误处理.py fromlangchain_core.toolsimporttoolfromlangchain.agentsimportAgentExecutor,create_tool_calling_agentfromlangchain_openaiimportChatOpenAIfromlangchain_core.promptsimportChatPromptTemplatetooldefrisky_api_call(query:str)-str:调用可能失败的外部API Args: query: 查询参数 try:# 模拟可能失败的 API 调用iferrorinquery.lower():raiseValueError(API 返回错误)returnf查询成功:{query}exceptExceptionase:# 返回友好的错误信息让 LLM 理解发生了什么returnf查询失败:{str(e)}。请告知用户该服务暂时不可用。# 创建带重试的 AgentExecutorpromptChatPromptTemplate.from_messages([(system,你是一个助手。 如果工具调用失败请 1. 解释发生了什么错误 2. 建议用户稍后重试 3. 提供替代方案如果有的话),(human,{input}),(placeholder,{agent_scratchpad})])llmChatOpenAI(modelqwen-plus)agentcreate_tool_calling_agent(llm,[risky_api_call],prompt)agent_executorAgentExecutor(agentagent,tools[risky_api_call],verboseTrue,handle_parsing_errorsTrue,# 自动处理解析错误max_iterations3,# 最多重试 3 次early_stopping_methodgenerate# 提前停止时生成总结)# 测试错误场景responseagent_executor.invoke({input:查询 error test})print(f回答:{response[output]})五、并行工具调用 并行工具调用 运行方式python 07_并行调用.py fromlangchain_openaiimportChatOpenAIfromlangchain_core.toolsimporttoolfromlangchain.agentsimportAgentExecutor,create_tool_calling_agentfromlangchain_core.promptsimportChatPromptTemplatetooldefget_weather(city:str)-str:获取天气returnf{city}: 晴天 25°Ctooldefget_news(topic:str)-str:获取新闻returnf{topic}最新消息: 无重大新闻tooldefget_stock(symbol:str)-str:获取股价returnf{symbol}当前价格: ¥150.00# 创建支持并行调用的 LLMllmChatOpenAI(modelqwen-plus,temperature0)promptChatPromptTemplate.from_messages([(system,你可以同时查询多个信息。),(human,{input}),(placeholder,{agent_scratchpad})])agentcreate_tool_calling_agent(llm,[get_weather,get_news,get_stock],prompt)agent_executorAgentExecutor(agentagent,tools[get_weather,get_news,get_stock],verboseTrue,max_iterations5)# LLM 可能会并行调用多个工具responseagent_executor.invoke({input:请同时告诉我北京天气、科技新闻和茅台股价})print(f回答:{response[output]})六、自定义 Agent 类型Agent 类型特点适用场景create_tool_calling_agent支持原生工具调用OpenAI、通义千问等create_react_agentReAct 推理框架需要详细推理过程create_structured_chat_agent结构化输出复杂参数传递 ReAct Agent 示例 运行方式python 07_react_agent.py fromlangchain.agentsimportcreate_react_agent,AgentExecutorfromlangchain_openaiimportChatOpenAIfromlangchain_core.toolsimporttoolfromlangchain_core.promptsimportChatPromptTemplatetooldefsearch(query:str)-str:搜索信息returnf搜索结果:{query}的相关信息# ReAct 提示词模板react_promptChatPromptTemplate.from_template( Answer the following questions as best you can. You have access to the following tools: {tools} Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{tool_names}] Action Input: the input to the action Observation: the result of the action ... (this Thought/Action/Action Input/Observation can repeat N times) Thought: I now know the final answer Final Answer: the final answer to the original input question Begin! Question: {input} Thought:{agent_scratchpad} )llmChatOpenAI(modelqwen-plus)agentcreate_react_agent(llm,[search],react_prompt)agent_executorAgentExecutor(agentagent,tools[search],verboseTrue,handle_parsing_errorsTrue)responseagent_executor.invoke({input:什么是LangGraph})print(f回答:{response[output]})七、工具调用 vs 直接调用维度工具调用直接调用灵活性LLM 自动决定何时调用代码中硬编码调用时机参数LLM 自动提取参数手动解析参数适用场景用户输入多变、需要智能判断固定流程、确定性调用可靠性可能调用错误工具100% 确定调用哪个工具调试需要打印中间过程代码流程清晰最佳实践简单场景用直接调用用户输入多变用工具调用关键操作用直接调用 人工确认八、常见问题Q1: 工具调用失败怎么办agent_executorAgentExecutor(agentagent,toolstools,handle_parsing_errorsTrue,# 自动处理解析错误max_iterations3,# 限制重试次数early_stopping_methodgenerate# 提前停止时生成总结)Q2: 如何防止 LLM 误调用危险工具工具命名清晰用search_xxx而不是do_something描述准确在 description 中明确说明用途和限制权限控制敏感操作需要人工确认Human-in-the-loopQ3: 如何优化工具调用性能减少工具数量只提供必要的工具描述精简避免冗长的工具描述缓存结果相同参数返回缓存结果相关笔记[[05-Agents智能体]] · [[06-多轮对话记忆]] · [[11-LangGraph/01-LangGraph概述与快速入门|LangGraph]]