LangChain组件------Tool
LangChain 的 tools 组件是一个灵活且强大的机制,它通过标准化接口将任意 Python 函数封装成 AI 模型可以理解和调用的"外接能力",通过使用Tool组件,Agent不仅能与人交互对话,更能执行具体操作,比如:实时搜索、查询数据库、执行代码等,从而扩展了应用的能力边界。
工具的五大要素
| 核心要素 | 说明 |
|---|---|
| 函数签名 | 定义工具的名称、输入参数和输出类型 |
| 工具描述 | 告诉模型这个工具的用途、需要的参数以及使用时机等 |
| 参数定义 | 定义工具输入参数的数据结构、类型和校验规则,确保调用格式正确 |
| 返回值处理 | 规定工具执行后如何将结果返回给模型 |
关于参数定义,想要大模型更好的理解有哪些参数、如何构造调用参数并自动验证参数,可以使用args_schema:一个 Pydantic BaseModel,用于定义函数所需的输入参数,包括参数名、类型和描述。
如何自己创建工具?
方式一:@Tool装饰器
@Tool装饰器适用于大多数场景,大模型从函数签名和docstring生成工具定义,这是当前主流创建方式,后面的两个案例也都是使用@Tool装饰器创建的。
方式二:StructuredTool数据类
通过实例化Tool类实现,将现成的函数包装成一个工具。比如想将一个已经存在的函数转换成工具,但是又无法或者不想为它添加@tool装饰器时。
方式三:继承BaseTool类
定义心累,创建一种新的、可复用的工具类型。适用于需要复杂逻辑、状态管理的场景,比如:工具需要维护状态或者执行复杂的初始化。
案例一:查询天气
python
from langchain.agents import create_agent
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os
# 1. 环境
load_dotenv()
API_KEY = os.getenv("API_KEY")
BASE_URL = os.getenv("BASE_URL")
MODEL_NAME = os.getenv("MODEL_NAME")
print("API_KEY=",API_KEY,'\nBASE_URL=',BASE_URL,'\nMODEL_NAME=',MODEL_NAME)
# 初始化LLM模型
llm = ChatOpenAI(api_key=API_KEY, base_url=BASE_URL, model=MODEL_NAME, temperature=0.3)
# 2. 工具
@tool
def weather_query(city: str) -> str:
"""查询指定城市天气"""
weather_data = {
"北京": "北京今日天气:晴,-2~8℃",
"上海": "上海今日天气:多云,5~12℃",
"广州": "广州今日天气:小雨,18~25℃",
}
return weather_data.get(city, f"暂无 {city} 数据")
tools = [weather_query]
# 3. 创建 Agent(开启 debug)
agent = create_agent(
model=llm,
tools=tools,
debug=True, # 👈 打开过程打印
)
# 4. 运行
response = agent.invoke({
"messages": [
{"role": "user", "content": "北京今天的天气怎么样?"}
]
})
print("\n最终回答:")
print(response["messages"][-1].content)
核心代码解释
定义工具
- @tool 装饰器将函数 weather_query 转换为 LangChain 工具。工具的名称默认为函数名,描述取自函数的docstring("""查询指定城市天气""")。
- 函数内部使用硬编码字典模拟天气数据,仅支持北京、上海、广州三座城市。
- 若传入的城市在字典中,返回对应天气字符串;否则返回 "暂无 {city} 数据"。
- tools = [weather_query]是将所有可用工具放入列表,后续传给 Agent。
创建Agent
create_agent:这是一个假设的函数(LangChain 中类似的是 create_react_agent、create_openai_tools_agent 或自定义的 Agent 构建器)。它的作用是:
- 将 LLM、工具列表、系统提示组合成一个可执行的 Agent。
- 内部会构建一个 ReAct 风格的推理循环(或使用 OpenAI 的 Function Calling 机制):接收用户输入 → LLM 思考是否需要调用工具 → 如果需要,生成工具名称和参数 → 执行工具 → 将结果返回给 LLM → LLM 生成最终答案。
- 参数:
model:LLM 实例。
tools:可用工具列表。
system_prompt:系统级指令。
debug=True:开启调试模式,会在控制台打印 Agent 的详细思考过程、工具调用记录、中间步骤等,便于观察和调试。
运行Agent
- agent.invoke(...):执行 Agent,传入符合 LangChain 消息格式的输入(一个包含 role 和 content
的消息列表)。 - 返回值 response:是一个字典,通常包含 "messages" 键,对应整个对话历史(包括用户消息、Agent
的中间思考、工具调用及结果、最终回答)。 - 提取最终结果:response["messages"][-1].content 获取最后一条消息的内容,即 Agent 的最终输出。
最终回答
response["messages"] 是执行过程中所有消息(用户、AI、工具)的列表。
-1\].content 取最后一条消息的内容,即模型生成的最终回答。 #### 案例二:温度转换工具 ```python from langchain.agents import create_agent from langchain_core.tools import tool from langchain_openai import ChatOpenAI from pydantic import BaseModel, Field from dotenv import load_dotenv import os # ====================== # 1. 环境变量 # ====================== load_dotenv() API_KEY = os.getenv("API_KEY") BASE_URL = os.getenv("BASE_URL") MODEL_NAME = os.getenv("MODEL_NAME") print("API_KEY=",API_KEY,"\nBASE_URL=",BASE_URL,"\nMODEL_NAME=",MODEL_NAME) llm = ChatOpenAI(api_key=API_KEY, base_url=BASE_URL, model=MODEL_NAME, temperature=0.3) # ====================== # 2. 参数模型 # ====================== class TemperatureConvertInput(BaseModel): temperature: float = Field(description="需要转换的温度值,例如37.0") from_unit: str = Field(description="原始温度单位,只能是celsius或fahrenheit") # ====================== # 3. 工具 # ====================== @tool(args_schema=TemperatureConvertInput) def temperature_converter(temperature: float, from_unit: str) -> str: """温度单位转换工具""" if from_unit not in ["celsius", "fahrenheit"]: return f"错误:单位'{from_unit}'不合法" if from_unit == "celsius": fahrenheit = temperature * 9 / 5 + 32 return f"{temperature}摄氏度 = {fahrenheit:.2f}华氏度" else: celsius = (temperature - 32) * 5 / 9 return f"{temperature}华氏度 = {celsius:.2f}摄氏度" tools = [temperature_converter] system_prompt = """ 你是一名专业温度转换助手,只能使用temperature_converter工具完成计算。 """ # ====================== # 4. 创建 Agent # ====================== agent = create_agent( model=llm, tools=tools, system_prompt=system_prompt, debug=True ) # ====================== # 5. 运行 # ====================== if __name__ == "__main__": query = "将37摄氏度转换为华氏度" response = agent.invoke({ "messages": [{"role": "user", "content": query}] }) print("\n最终结果:") print(response["messages"][-1].content) ``` ##### 核心代码解释 ###### 定义参数模型 作用:为工具 temperature_converter 定义输入参数的 schema(结构、类型、描述)。继承自 BaseModel(Pydantic 模型,在[介绍LangChain核心组件输出格式](https://blog.csdn.net/qq_41181787/article/details/160171171)的时候也有这种定义),提供自动校验、类型转换和文档生成功能。 字段: temperature:浮点数,温度值。 from_unit:字符串,只能是 "celsius" 或 "fahrenheit"。 Field(description=...):提供字段说明,这些描述会被传递给 LLM,帮助模型理解何时以及如何填充参数。 ###### 定义工具 * @tool 装饰器:将普通 Python 函数转换为 LangChain 工具对象,使其能被 Agent 识别和调用。 * args_schema 参数:绑定之前定义的 TemperatureConvertInput 模型,用于告诉 LLM 调用该工具时需要提供哪些参数、参数类型及描述,自动校验传入参数是否符合要求(类型、取值范围等)。 * 文档字符串:"""温度单位转换工具""" 会被 LLM 读取,作为工具功能的自然语言描述。 ###### 工具列表 ```python tools = [temperature_converter] ``` 将定义好的工具放入列表,后续交给 Agent 使用。Agent 可以拥有多个工具(例如搜索、计算器、数据库查询等),这里只包含一个温度转换工具。 其余的和上面的天气查询工具类似。 ### LangChain内置工具 LangChain 预置了丰富的工具包(Toolkit),它们是为特定任务(如 SQL 查询、GitHub 操作、办公自动化)设计的一系列工具的集合。这些工具包使得开发者,无需从零构建,核心的内置工具有 1. 信息检索类 核心作用:获取实时或特定领域的信息,弥补LLM知识库的局限。常见工具有Tavily Search, SerpAPI, Arxiv等 2. 数据处理类 核心作用:处理精确计算、执行代码逻辑,补充LLM的数值和逻辑短板,常见工具有:Python REPL, SQL Database等 当然,除了上面列举出的之外,还有开发者工具、办公自动化、系统交互等丰富工具。 #### 如何调用工具包 所有工具包都开箱即用地提供一个 get_tools() 方法,能把一组工具直接"打包"交给智能体(Agent)。通用的工作流程如下: 1. 安装与准备:根据所选工具包,安装相关的 Python 包并设置好 API 密钥等环境变量。 2. 初始化模型:实例化一个聊天模型。 3. 加载工具包:创建工具包实例,并通过 get_tools() 获取工具列表。 4. 绑定并创建 Agent:将模型和工具传入 create_agent 等函数,构建智能体并执行任务。 ##### 示例 下面的示例是调用"创建文件"的工具包 ```python from langchain.agents import create_agent from langchain_openai import ChatOpenAI from langchain_community.agent_toolkits import FileManagementToolkit from dotenv import load_dotenv import os # ------------------- # 1. 初始化环境 # ------------------- load_dotenv() API_KEY = os.getenv("API_KEY") BASE_URL = os.getenv("BASE_URL") llm = ChatOpenAI( api_key=API_KEY, base_url=BASE_URL, model="deepseek-chat", temperature=0.3, ) # ------------------- # 2. 创建文件管理工具 # ------------------- toolkit = FileManagementToolkit(root_dir=".") tools = toolkit.get_tools() # ------------------- # 3. 创建 Agent(最新版) # ------------------- agent = create_agent( model=llm, tools=tools, debug=True, # 打开调试,显示模型思考和工具调用过程 ) # ------------------- # 4. 执行任务 # ------------------- response = agent.invoke({ "messages": [ {"role": "user", "content": "请创建一个名为 llm诗词.txt 的文件,并在文件中写入一首原创七言绝句,主题围绕科技与人文的融合。"} ] }) print("\n任务执行完成!文件已写入。") print("Agent最终输出:\n", response["messages"][-1].content) ``` 本文代码来源:[datawhale](https://github.com/datawhalechina/easy-langent/blob/main/docs/guide/chapter3.md#33-%E7%BB%BC%E5%90%88%E5%AE%9E%E8%B7%B5%E6%8A%8Amemory%E5%92%8Ctool%E7%BB%84%E5%90%88%E8%B5%B7%E6%9D%A5)