尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

LangChain 工具调用(Tool Calling)实战指南

LangChain 工具调用(Tool Calling)实战指南 1. 引言在构建大语言模型LLM应用时模型本身无法执行实时查询、调用外部 API 或操作数据库。工具调用Tool Calling / Function Calling正是为了解决这一痛点而生的机制它让模型在对话过程中识别出需要外部能力才能回答的问题并结构化地输出一个“调用请求”由我们的应用代码去真正执行对应的函数再把结果回传给模型从而生成最终答案。本文将基于 LangChain 0.3 系列从零开始讲解工具调用的核心概念、定义方式、绑定与执行流程并通过可运行的代码示例带你快速上手。2. 什么是工具调用工具调用是 LLM 的一种能力模型在生成回复时可以输出一个结构化的“工具调用指令”而不是直接给出最终文本。这个指令通常包含工具名称tool name传给该工具的参数argumentsJSON 格式应用侧拿到这个指令后负责真正执行对应的函数并把执行结果作为新的消息返回给模型模型再基于结果继续推理最终给出面向用户的回答。需要特别注意的是模型本身并不执行工具它只负责“决定调用哪个工具、传什么参数”。真正的执行逻辑始终由我们的代码完成。3. 环境准备在开始之前请确保你的环境中已安装 LangChain 及对应模型的依赖包pipinstalllangchain langchain-openai如果你使用 OpenAI 兼容接口如国内大模型服务通常还需要配置 API Key 和 Base URLimportos os.environ[OPENAI_API_KEY]your-api-keyos.environ[OPENAI_BASE_URL]https://your-endpoint/v14. 定义一个工具在 LangChain 中最推荐的方式是使用tool装饰器把一个普通的 Python 函数声明为可供模型调用的工具。fromlangchain_core.toolsimporttooltooldefget_weather(city:str)-str:查询指定城市的当前天气。 参数: city: 城市名称例如 北京、上海。 返回: 该城市的天气描述字符串。 # 这里仅作演示实际可替换为真实天气 API 调用returnf{city}今天晴气温 26℃微风。要点说明函数的**文档字符串docstring**会被 LangChain 自动提取作为模型判断“何时调用该工具”的依据务必写清楚用途和参数含义。函数的类型注解如city: str会被转换为工具的参数 schema模型据此生成合法的参数 JSON。函数返回值会被作为工具执行结果回传给模型。docstring 的写法与作用docstring文档字符串是写在函数定义第一行的三引号字符串它不仅是给开发者看的注释更是 LangChain 生成工具描述的核心依据。模型正是通过 docstring 来理解“这个工具是做什么的、什么时候该调用它”。一个规范的 docstring 通常包含三部分功能描述一句话说明工具的作用例如“查询指定城市的当前天气”。参数说明逐个列出参数的含义、类型和取值范围帮助模型生成合法的参数 JSON。返回值说明说明函数返回什么内容让模型知道拿到结果后该如何使用。tooldefget_weather(city:str)-str:查询指定城市的当前天气。 参数: city: 城市名称例如 北京、上海。 返回: 该城市的天气描述字符串。 returnf{city}今天晴气温 26℃微风。docstring 的书写质量直接影响模型调用工具的准确率描述越具体模型判断越准。如果只写“查询天气”模型可能不清楚该传什么参数写清楚“城市名称例如北京、上海”后模型就能正确生成{city: 北京}这样的参数。参数说明要与类型注解一致。docstring 里说明的参数名必须和函数签名中的参数名完全一致否则 LangChain 生成的 schema 会与 docstring 描述不一致可能导致模型传错参数。避免歧义和冗余。docstring 应简洁明确不要写与工具功能无关的内容以免干扰模型的判断。5. 绑定工具到模型定义好工具后需要把它“绑定”到聊天模型上模型才会在推理时知道有这个工具可用。fromlangchain_openaiimportChatOpenAI llmChatOpenAI(modelgpt-4o-mini,temperature0)# 将工具绑定到模型llm_with_toolsllm.bind_tools([get_weather])bind_tools接收一个工具列表可以一次绑定多个工具。绑定后模型在需要时就会输出工具调用指令。6. 执行工具调用下面是一个完整的调用流程示例用户提问 → 模型决定调用工具 → 我们执行工具 → 把结果回传给模型 → 模型给出最终回答。fromlangchain_core.messagesimportHumanMessage,ToolMessage# 第一步用户提问messages[HumanMessage(content北京今天天气怎么样)]# 第二步模型决定调用工具responsellm_with_tools.invoke(messages)print(模型输出:,response)# 第三步检查是否有工具调用请求ifresponse.tool_calls:tool_callresponse.tool_calls[0]print(f需要调用工具:{tool_call[name]})print(f参数:{tool_call[args]})# 第四步真正执行工具函数tool_resultget_weather.invoke(tool_call[args])# 第五步把工具执行结果作为 ToolMessage 追加到消息列表messages.append(response)messages.append(ToolMessage(contenttool_result,tool_call_idtool_call[id]))# 第六步让模型基于工具结果生成最终回答final_responsellm_with_tools.invoke(messages)print(最终回答:,final_response.content)执行流程可以概括为下图否是用户提问模型推理是否需要调用工具?直接返回回答模型输出工具调用指令应用代码执行工具函数将结果回传给模型调用流程7. 多工具与参数校验实际项目中往往需要同时提供多个工具。LangChain 支持一次绑定多个工具模型会根据问题自动选择合适的那个。tooldefget_time(city:str)-str:查询指定城市的当前时间。 参数: city: 城市名称。 返回: 该城市的当前时间字符串。 returnf{city}当前时间为 14:30llm_with_toolsllm.bind_tools([get_weather,get_time])此外LangChain 会自动根据函数的类型注解和 docstring 生成 JSON Schema并在调用时对模型生成的参数做校验。如果参数不合法会抛出异常便于我们及时发现并处理。下面是一个更完整的示例定义两个工具查询天气、查询时间绑定到模型并演示模型如何根据问题自动选择工具、以及参数校验失败时的处理。fromlangchain_core.toolsimporttoolfromlangchain_core.messagesimportHumanMessage,ToolMessagetooldefget_weather(city:str)-str:查询指定城市的当前天气。 参数: city: 城市名称例如 北京、上海。 返回: 该城市的天气描述字符串。 returnf{city}今天晴气温 26℃微风。tooldefget_time(city:str)-str:查询指定城市的当前时间。 参数: city: 城市名称。 返回: 该城市的当前时间字符串。 returnf{city}当前时间为 14:30# 一次绑定多个工具llm_with_toolsllm.bind_tools([get_weather,get_time])# 模型会根据问题自动选择合适的工具messages[HumanMessage(content北京现在几点了)]responsellm_with_tools.invoke(messages)ifresponse.tool_calls:tool_callresponse.tool_calls[0]print(f模型选择了工具:{tool_call[name]})print(f参数:{tool_call[args]})# 根据工具名动态执行对应的函数tool_map{get_weather:get_weather,get_time:get_time}selected_tooltool_map[tool_call[name]]tool_resultselected_tool.invoke(tool_call[args])messages.append(response)messages.append(ToolMessage(contenttool_result,tool_call_idtool_call[id]))final_responsellm_with_tools.invoke(messages)print(最终回答:,final_response.content)关于参数校验LangChain 会根据函数的类型注解自动生成 JSON Schema。例如get_weather(city: str)会生成一个要求city为字符串的 schema。如果模型生成的参数不符合要求例如缺少必填字段、类型错误调用时会抛出异常# 模拟参数校验失败缺少必填参数 citytry:get_weather.invoke({})exceptExceptionase:print(参数校验失败:,e)通过这种方式我们可以在开发阶段尽早发现模型生成的参数问题从而及时修正 docstring 或类型注解提升工具调用的稳定性。8. 总结本文介绍了 LangChain 工具调用的完整流程使用tool装饰器定义工具docstring 和类型注解是模型理解工具的关键。通过bind_tools把工具绑定到模型。模型输出tool_calls后由应用代码真正执行工具并通过ToolMessage回传结果。支持一次绑定多个工具模型会自动选择。工具调用是构建 Agent、RAG 查询增强、自动化工作流等高级应用的基础能力。掌握它之后你就可以让大模型“动手做事”而不仅仅是“动嘴说话”了。
返回列表