news 2026/3/8 15:23:00

LangChain工具调用完全指南:从基础到实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangChain工具调用完全指南:从基础到实战

什么是LangChain工具?

在LangChain框架中,工具(Tools)是让大语言模型(LLM)能够与外部系统、API或函数进行交互的核心组件。通过工具,LLM可以执行计算、查询数据、调用外部服务等操作,从而突破纯文本生成的限制,实现更强大的功能。

2.1 创建工具

2.1.1 使用@tool装饰器创建工具

@tool装饰器是LangChain中创建工具的最简单方法。它通过装饰Python函数来定义工具,自动从函数名、类型提示和文档字符串中提取工具的相关属性。

from langchain_core.tools import tool @tool def multiply(a: int, b: int) -> int: """Multiply two integers. Args: a: First integer b: Second integer """ return a * b print(multiply.invoke({"a": 2, "b": 3})) # 输出:6 print(multiply.name) # 输出:multiply print(multiply.description) # 输出:Multiply two integers... print(multiply.args) # 输出:{'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}

关键特性:

  • 默认使用函数名称作为工具名称

  • 使用函数的文档字符串作为工具描述

  • 函数名、类型提示和文档字符串都是传递给工具Schema的重要组成部分

什么是Schema?

Schema是描述数据结构的声明格式,用于自动验证数据。在JSON Schema中,我们定义数据的类型、字段、格式等约束条件。

示例对比:

// 示例1:简单结构 { "name": "张小红", "birthday": "1732年2月22日", "address": "陕西省西安市雁塔区" } // 示例2:结构化结构 { "surname": "王", "given_name": "刚", "birthday": "1732-02-22", "address": { "district": "萧山区", "city": "杭州市", "province": "浙江省", "country": "中国" } }

对应的JSON Schema:

{ "type": "object", "properties": { "surname": { "type": "string" }, "given_name": { "type": "string" }, "birthday": { "type": "string", "format": "date" }, "address": { "type": "object", "properties": { "district": { "type": "string" }, "city": { "type": "string" }, "province": { "type": "string" }, "country": { "type": "string" } } } } }

Google风格文档字符串:

Google风格是Python文档字符串的一种写作规范,使用Args:Returns:等关键字,参数描述简洁明了:

def fetch_data(url, retries=3): """从给定的URL获取数据。 Args: url (str): 要从中获取数据的URL。 retries (int, optional): 失败时重试的次数。默认为3。 Returns: dict: 从URL解析的JSON响应。 """ # 函数实现

2.1.1.1 模式1:依赖Pydantic类

当函数没有提供文档字符串时,可以使用Pydantic类来定义工具Schema:

from langchain_core.tools import tool from pydantic import BaseModel, Field class AddInput(BaseModel): """Add two integers.""" a: int = Field(..., description="First integer") b: int = Field(..., description="Second integer") class MultiplyInput(BaseModel): """Multiply two integers.""" a: int = Field(..., description="First integer") b: int = Field(..., description="Second integer") @tool(args_schema=AddInput) def add(a: int, b: int) -> int: # 未提供描述 return a + b @tool(args_schema=MultiplyInput) def multiply(a: int, b: int) -> int: # 未提供描述 return a * b

注意:​ 除非提供默认值,否则所有字段都是required。

2.1.1.2 模式2:依赖Annotated

使用Annotated和文档字符串传递工具Schema:

from langchain_core.tools import tool from typing_extensions import Annotated @tool def add( a: Annotated[int, ..., "First integer"], b: Annotated[int, ..., "Second integer"] ) -> int: """Add two integers.""" return a + b @tool def multiply( a: Annotated[int, ..., "First integer"], b: Annotated[int, ..., "Second integer"] ) -> int: """Multiply two integers.""" return a * b

2.1.2 使用StructuredTool类创建工具

StructuredTool.from_function类方法通过给定的函数来创建并返回一个工具:

from langchain_core.tools import StructuredTool def multiply(a: int, b: int) -> int: """Multiply two numbers.""" return a * b calculator_tool = StructuredTool.from_function(func=multiply) print(calculator_tool.invoke({"a": 2, "b": 3})) # 输出:6

关键参数说明:

  • func:要设置的函数

  • name:工具名称,默认为函数名称

  • description:工具描述,默认为函数文档字符串

  • args_schema:工具输入参数的schema

  • response_format:工具响应格式,默认为"content"

2.1.2.2 加入配置,依赖Pydantic类

from langchain_core.tools import StructuredTool from pydantic import BaseModel, Field class CalculatorInput(BaseModel): a: int = Field(description="first number") b: int = Field(description="second number") def multiply(a: int, b: int) -> int: return a * b calculator_tool = StructuredTool.from_function( func=multiply, name="Calculator", description="两数相乘", args_schema=CalculatorInput, ) print(calculator_tool.invoke({"a": 2, "b": 3})) # 输出:6 print(calculator_tool.name) # 输出:Calculator print(calculator_tool.description) # 输出:两数相乘 print(calculator_tool.args) # 输出:{'a': {'description': 'first number', 'title': 'A', 'type': 'integer'}, 'b': {'description': 'second number', 'title': 'B', 'type': 'integer'}}

2.1.2.3 加入response_format配置

当需要区分消息内容(content)和其他工件(artifact)时,可以使用response_format="content_and_artifact"

from langchain_core.tools import StructuredTool from pydantic import BaseModel, Field from typing import List, Tuple class CalculatorInput(BaseModel): a: int = Field(description="first number") b: int = Field(description="second number") def multiply(a: int, b: int) -> Tuple[str, List[int]]: nums = [a, b] content = f"{nums}相乘的结果是{a * b}" return content, nums calculator_tool = StructuredTool.from_function( func=multiply, name="Calculator", description="两数相乘", args_schema=CalculatorInput, response_format="content_and_artifact" ) # 直接调用工具,只返回content print(calculator_tool.invoke({"a": 2, "b": 3})) # 输出:[2, 3]相乘的结果是6 # 模拟大模型调用,返回ToolMessage print(calculator_tool.invoke({ "name": "Calculator", "args": {"a": 2, "b": 3}, "id": "123", # 必须,工具调用标识符 "type": "tool_call", # 必须 }))

输出结果:

content='[2, 3]相乘的结果是6' name='Calculator' tool_call_id='123' artifact=[2, 3]

artifact的作用:

  • 保存原始结构化数据,供链中后续组件使用

  • 不适合直接塞给大模型

  • 可用于日志记录、数据分析、自定义处理等场景

2.2 绑定工具

使用聊天模型的.bind_tools()方法将工具绑定到模型:

from langchain_openai import ChatOpenAI # 定义大模型 model = ChatOpenAI(model="gpt-4o-mini") # 绑定工具,返回一个Runnable实例 tools = [add, multiply] model_with_tools = model.bind_tools(tools)

bind_tools()方法参数:

  • tools:绑定的工具定义列表

  • tool_choice:要求模型调用哪个工具

    • '<<tool_name>>':调用指定工具

    • 'auto':自动选择工具

    • 'none':不调用工具

    • 'any''required'True:强制调用至少一个工具

  • strict:是否严格验证输入输出

  • parallel_tool_calls:是否允许并行工具调用

2.3 工具调用

使用绑定的Runnable实例调用.invoke()方法完成工具调用:

from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage from langchain_core.tools import tool from typing_extensions import Annotated # 定义大模型 model = ChatOpenAI(model="gpt-4o-mini") @tool def add( a: Annotated[int, ..., "First integer"], b: Annotated[int, ..., "Second integer"] ) -> int: """Add two integers.""" return a + b @tool def multiply( a: Annotated[int, ..., "First integer"], b: Annotated[int, ..., "Second integer"] ) -> int: """Multiply two integers.""" return a * b # 绑定工具 tools = [add, multiply] model_with_tools = model.bind_tools(tools) # 调用工具 result = model_with_tools.invoke("9乘6等于多少?") print(result)

输出结果(AIMessage):

content='' additional_kwargs={'tool_calls': [{'id': 'call_mBnxNMY7vfAOrExEETcdEC6l', 'function': {'arguments': '{"a":9,"b":6}', 'name': 'multiply'}, 'type': 'function'}], 'refusal': None} response_metadata={'token_usage': {'completion_tokens': 17, 'prompt_tokens': 86, 'total_tokens': 103, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_560af6e559', 'id': 'chatcmpl-C6DSvbskJtwUl6YTkPILUaiDdDuEN', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None} id='run--1f43e942-d56b-4d6d-8d3f-145b7e5d0036-0' tool_calls=[{'name': 'multiply', 'args': {'a': 9, 'b': 6}, 'id': 'call_mBnxNMY7vfAOrExEETcdEC6l', 'type': 'tool_call'}] usage_metadata={'input_tokens': 86, 'output_tokens': 17, 'total_tokens': 103, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}

关键输出字段:

  • content:消息内容

  • additional_kwargs:工具调用信息

  • tool_calls:工具调用详情(名称、参数、ID)

  • finish_reason:完成原因(tool_calls表示调用了工具)

2.4 强制模型调用工具

通过设置tool_choice="any"强制模型调用至少一个工具:

model_with_tools = model.bind_tools(tools, tool_choice="any") result = model_with_tools.invoke("hello world!") print(result)

2.5 工具属性

如果调用了工具,result将具有tool_calls属性:

model_with_tools = model.bind_tools(tools, tool_choice="any") result = model_with_tools.invoke("9乘6等于多少?") print(result.tool_calls)

输出结果:

[{'name': 'multiply', 'args': {'a': 9, 'b': 6}, 'id': 'call_csFbMmYD4Dmz8yMja3ZWK1QW', 'type': 'tool_call'}]

总结

LangChain的工具系统提供了灵活的方式来扩展大语言模型的能力。通过@tool装饰器、StructuredTool类以及Pydantic模型,我们可以轻松定义各种工具,并将其绑定到聊天模型中。工具调用机制使得LLM能够与外部系统交互,实现更复杂的应用场景。

核心要点:

  • 工具定义需要函数名、类型提示和文档字符串

  • 可以使用Pydantic类或Annotated来定义Schema

  • 通过bind_tools()方法将工具绑定到模型

  • 工具调用返回AIMessage,包含工具调用信息

  • 可以强制模型调用工具或让模型自动选择

掌握这些工具调用技术,将为构建更强大的AI应用奠定坚实基础。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/8 14:12:27

无人机自主避障系统:视觉感知模型在嵌入式TensorRT运行

无人机自主避障系统&#xff1a;视觉感知模型在嵌入式TensorRT运行 在城市物流、电力巡检和应急救援等场景中&#xff0c;无人机正从“遥控飞行器”演变为真正意义上的“空中智能体”。而实现这一跃迁的关键&#xff0c;正是自主避障能力——它让无人机能在复杂环境中自行识别障…

作者头像 李华
网站建设 2026/3/8 10:58:35

ESP32固件库下载项目应用:构建WiFi客户端

用好ESP32固件库&#xff0c;轻松构建稳定Wi-Fi客户端 你有没有遇到过这样的场景&#xff1a;手里的ESP32板子通电后&#xff0c;Wi-Fi连不上、反复重试、IP获取失败&#xff0c;日志里一堆 WIFI_EVENT_STA_DISCONNECTED &#xff1f;调试半天&#xff0c;最后发现是配置少写…

作者头像 李华
网站建设 2026/3/8 3:54:03

企业级企业内管信息化系统管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】

摘要 随着数字化转型的加速推进&#xff0c;企业内管信息化系统成为提升管理效率、优化资源配置的重要工具。传统企业管理依赖人工操作和纸质文档&#xff0c;存在效率低下、数据易丢失、信息孤岛等问题。信息化系统的引入能够实现业务流程自动化、数据实时共享和决策科学化&am…

作者头像 李华
网站建设 2026/3/8 15:19:10

企业级热门网游推荐网站管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】

摘要 随着互联网技术的快速发展和网络游戏的普及&#xff0c;企业级网游市场呈现出蓬勃发展的态势。网游推荐网站作为连接玩家与游戏厂商的重要平台&#xff0c;其管理系统的开发需求日益增长。传统的手工管理方式效率低下&#xff0c;难以满足海量游戏数据的处理需求&#xff…

作者头像 李华
网站建设 2026/3/4 3:21:24

打造高性能AI中台:TensorRT镜像作为底层引擎的优势分析

打造高性能AI中台&#xff1a;TensorRT镜像作为底层引擎的优势分析 在当今的AI工程实践中&#xff0c;一个常见的尴尬场景是&#xff1a;模型在实验室里表现优异&#xff0c;准确率高达98%&#xff0c;推理延迟却高达上百毫秒——一旦接入真实业务系统&#xff0c;面对每秒数千…

作者头像 李华
网站建设 2026/3/5 3:11:28

一键加速你的AI项目:TensorRT镜像现已全面开放获取

一键加速你的AI项目&#xff1a;TensorRT镜像现已全面开放获取 在如今的AI部署现场&#xff0c;你是否也遇到过这样的窘境&#xff1f;训练好的模型放进生产环境&#xff0c;推理速度却卡在每秒几帧&#xff1b;想扩容&#xff0c;服务器成本翻倍&#xff1b;换成边缘设备跑&am…

作者头像 李华