LangChain v1.0+ Tools模块全解析:构建智能、强大的大模型应用
LangChain v1.0+的Tools模块是连接大模型与外部世界的桥梁,本文深入解析其核心功能,包括Tool、StructuredTool和Toolkit的使用方法,以及与Agent的集成技巧。通过完整的代码示例和最佳实践,展示如何开发自定义工具、实现参数验证、优化性能和处理错误,帮助开发者构建更加智能、实用的大模型应用,突破模型本身的能力限制。本文还详细对比了v1.0前后的工具开发差异,介绍
【个人主页:玄同765】
大语言模型(LLM)开发工程师|中国传媒大学·数字媒体技术(智能交互与游戏设计)
深耕领域:大语言模型开发 / RAG知识库 / AI Agent落地 / 模型微调
技术栈:Python / LangChain/RAG(Dify+Redis+Milvus)| SQL/NumPy | FastAPI+Docker ️
工程能力:专注模型工程化部署、知识库构建与优化,擅长全流程解决方案
「让AI交互更智能,让技术落地更高效」
欢迎技术探讨/项目合作! 关注我,解锁大模型与智能交互的无限可能!
当你开发大模型应用时,是否曾遇到这些挑战:
- 如何让模型与外部系统进行交互?
- 如何管理和组织各种工具函数?
- 如何让模型智能地选择和使用工具?
- 如何处理工具调用的错误和异常?
LangChain v1.0+的tools模块为这些问题提供了优雅的解决方案。本文将全面解析LangChain v1.0+中tools模块的核心功能、使用方法和最佳实践,帮助你构建更加智能、强大的大模型应用。
一、LangChain v1.0+ Tools模块核心概念
1. Tool:工具的基本抽象
核心用途:Tool是LangChain中工具的基本抽象,它封装了一个可执行函数,并提供了名称、描述和参数等元数据,使模型能够理解和使用这个工具。
代码示例:
from langchain_core.tools import Tool
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
weather_data = {
"北京": "晴,25℃",
"上海": "多云,23℃",
"广州": "阴,28℃"
}
return weather_data.get(city, "未知城市")
# 创建工具实例
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息,参数为城市名称"
)
适用场景:封装各种外部功能,如API调用、数据库查询、文件操作等,使模型能够使用这些功能。
2. StructuredTool:结构化工具
核心用途:StructuredTool是Tool的扩展,它支持结构化的输入参数,使用Pydantic模型来定义参数结构,使工具调用更加类型安全。
代码示例:
from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field
# 定义参数结构
class WeatherRequest(BaseModel):
city: str = Field(description="要查询天气的城市名称")
days: int = Field(default=1, description="要查询的天数")
def get_weather_detailed(city: str, days: int = 1) -> str:
"""获取指定城市的详细天气信息"""
weather_data = {
"北京": ["晴,25℃", "多云,23℃", "阴,22℃"],
"上海": ["多云,23℃", "阴,22℃", "小雨,20℃"],
"广州": ["阴,28℃", "小雨,26℃", "多云,27℃"]
}
if city in weather_data:
return "\n".join(weather_data[city][:days])
return "未知城市"
# 创建结构化工具
weather_tool = StructuredTool.from_function(
func=get_weather_detailed,
name="get_weather_detailed",
description="获取指定城市的详细天气信息",
args_schema=WeatherRequest
)
适用场景:需要复杂参数结构的工具,如多参数API调用、数据库查询等。
3. Toolkit:工具集合
核心用途:Toolkit是一组相关工具的集合,它提供了一种组织和管理多个工具的方式,使工具的使用更加模块化和可维护。
代码示例:
from langchain_core.tools import Toolkit
from langchain_community.tools import YouTubeSearchTool, WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
class InformationToolkit(Toolkit):
"""信息查询工具集合"""
def __init__(self):
self.youtube_tool = YouTubeSearchTool()
self.wikipedia_tool = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
def get_tools(self):
"""获取工具列表"""
return [self.youtube_tool, self.wikipedia_tool]
# 使用工具集合
toolkit = InformationToolkit()
tools = toolkit.get_tools()
适用场景:组织相关的工具,如信息查询工具集、数据分析工具集等,使工具的管理更加清晰。
二、LangChain v1.0前后工具开发对比
1. v1.0之前的工具开发
在LangChain v1.0之前,工具的开发和使用方式与现在有较大差异:
核心差异:
- 模块结构:工具类分布在不同模块,导入路径复杂
- 接口设计:没有统一的Runnable接口,工具调用方式不一致
- 参数处理:参数验证机制不够完善,类型安全不足
- 集成方式:与Agent的集成较为复杂,需要更多样板代码
v1.0之前的代码示例:
# v1.0之前的工具开发
from langchain.tools import Tool
from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
# 定义工具函数
def get_weather(city):
"""获取天气信息"""
return f"{city}的天气是晴天"
# 创建工具
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息"
)
# 初始化Agent
llm = ChatOpenAI(temperature=0)
agent = initialize_agent(
tools=[weather_tool],
llm=llm,
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# 执行
result = agent.run("北京的天气怎么样?")
2. v1.0之后的工具开发
LangChain v1.0+引入了全新的架构和接口,使工具开发更加简洁、灵活和类型安全:
核心改进:
- 统一接口:所有组件实现Runnable接口,支持invoke、batch、stream等统一方法
- 模块化设计:工具类集中在langchain_core.tools模块,导入路径清晰
- 结构化参数:StructuredTool支持Pydantic模型,提供类型安全的参数处理
- 简化集成:与Agent的集成更加简化,支持工具绑定和自动调用
- 异步支持:原生支持异步工具和并发执行
v1.0之后的代码示例:
# v1.0之后的工具开发
from langchain_core.tools import Tool
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
# 定义工具函数
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
return f"{city}的天气是晴天"
# 创建工具
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息,参数为城市名称"
)
# 初始化模型
llm = ChatOpenAI(model="gpt-4o-mini")
# 创建Agent(推荐方式)
agent = create_agent(
model=llm,
tools=[weather_tool],
system_prompt="你是一个助手,需要根据用户请求选择合适的工具来完成任务。"
)
# 执行(使用消息列表格式)
result = agent.invoke({
"messages": [("human", "北京的天气怎么样?")]
})
print("最终结果:", result["messages"][-1].content)
三、Tools模块核心功能实现
1. 工具调用机制
核心用途:LangChain的工具调用机制允许模型根据用户输入智能地选择和使用工具,实现模型与外部系统的交互。
代码示例:
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
from langchain_core.tools import Tool
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
weather_data = {
"北京": "晴,25℃",
"上海": "多云,23℃",
"广州": "阴,28℃"
}
return weather_data.get(city, "未知城市")
def calculate(expression: str) -> str:
"""计算数学表达式,如'1+1'、'2*3'等"""
try:
result = eval(expression)
return f"计算结果:{result}"
except:
return "计算错误"
# 创建工具列表
tools = [
Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息,参数为城市名称"
),
Tool(
name="calculate",
func=calculate,
description="计算数学表达式,参数为数学表达式字符串"
)
]
# 初始化模型
llm = ChatOpenAI(model="gpt-4o-mini")
# 构建带工具调用的链
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个助手,需要根据用户请求选择合适的工具来完成任务。"),
("human", "{input}")
])
# 绑定工具到模型
tool_llm = llm.bind_tools(tools)
# 构建完整链
chain = prompt | tool_llm
# 执行
response = chain.invoke({"input": "北京今天的天气怎么样?"})
print(response)
适用场景:需要模型根据上下文智能选择工具的场景,如智能助手、客服系统等。
2. Agent与Tools集成
核心用途:将Tools模块与Agent框架集成,使Agent能够根据任务需求智能地使用工具。
推荐方法(1.0+):使用create_agent
代码示例:
from langchain.agents import create_agent
from langchain_core.tools import Tool
from langchain_openai import ChatOpenAI
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
weather_data = {
"北京": "晴,25℃",
"上海": "多云,23℃",
"广州": "阴,28℃"
}
return weather_data.get(city, "未知城市")
def calculate(expression: str) -> str:
"""计算数学表达式,如'1+1'、'2*3'等"""
try:
result = eval(expression)
return f"计算结果:{result}"
except:
return "计算错误"
# 创建工具列表
tools = [
Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息,参数为城市名称"
),
Tool(
name="calculate",
func=calculate,
description="计算数学表达式,参数为数学表达式字符串"
)
]
# 初始化模型
llm = ChatOpenAI(model="gpt-4o-mini")
# 创建Agent(推荐方式)
agent = create_agent(
model=llm,
tools=tools,
system_prompt="你是一个助手,需要根据用户请求选择合适的工具来完成任务。"
)
# 执行(使用消息列表格式)
result = agent.invoke({
"messages": [("human", "北京今天的天气怎么样?另外,请计算3+5*2的结果。")]
})
print("最终结果:", result["messages"][-1].content)
传统方法:使用create_tool_calling_agent和AgentExecutor
代码示例:
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import Tool
from langchain_openai import ChatOpenAI
# 定义工具函数(同上)
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
weather_data = {
"北京": "晴,25℃",
"上海": "多云,23℃",
"广州": "阴,28℃"
}
return weather_data.get(city, "未知城市")
# 创建工具列表(同上)
tools = [
Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息,参数为城市名称"
)
]
# 初始化模型
llm = ChatOpenAI(model="gpt-4o-mini")
# 定义Agent提示词
agent_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个助手,需要根据用户请求选择合适的工具来完成任务。"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
# 创建Agent
agent = create_tool_calling_agent(llm, tools, agent_prompt)
# 创建Agent执行器
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 执行
result = agent_executor.invoke({"input": "北京今天的天气怎么样?"})
print("最终结果:", result["output"])
适用场景:复杂任务需要多个工具协作完成的场景,如多步骤信息查询、综合分析等。
3. 自定义工具开发
核心用途:开发自定义工具,封装特定领域的功能,满足特定业务需求。
代码示例:
from langchain_core.tools import Tool
import requests
def search_wikipedia(query: str) -> str:
"""搜索维基百科获取信息"""
try:
url = f"https://zh.wikipedia.org/api/rest_v1/page/summary/{query}"
response = requests.get(url, headers={"Accept": "application/json"})
if response.status_code == 200:
data = response.json()
return data.get("extract", "未找到相关信息")
return "搜索失败"
except Exception as e:
return f"错误:{str(e)}"
# 创建自定义工具
wikipedia_tool = Tool(
name="search_wikipedia",
func=search_wikipedia,
description="搜索维基百科获取指定主题的信息,参数为搜索关键词"
)
# 使用工具
result = wikipedia_tool.run("LangChain")
print(result)
适用场景:特定领域的功能需求,如特定API调用、内部系统集成等。
四、LangChain内置工具集
LangChain提供了丰富的内置工具,涵盖了各种常见的功能需求。这些工具可以直接使用,大大减少了开发工作量。
1. 常用内置工具
信息查询工具:
- WikipediaQueryRun:搜索维基百科获取信息
- YouTubeSearchTool:搜索YouTube视频
- DuckDuckGoSearchRun:使用DuckDuckGo搜索引擎
文件操作工具:
- ReadFileTool:读取文件内容
- WriteFileTool:写入文件内容
- ListDirectoryTool:列出目录内容
数据处理工具:
- PythonREPLTool:执行Python代码
- CalculatorTool:执行数学计算
- JSONTool:处理JSON数据
API集成工具:
- RequestsTool:发送HTTP请求
- ShellTool:执行Shell命令
2. 如何使用内置工具
代码示例:
from langchain_community.tools import WikipediaQueryRun, DuckDuckGoSearchRun
from langchain_community.utilities import WikipediaAPIWrapper
# 初始化维基百科工具
wikipedia_tool = WikipediaQueryRun(
api_wrapper=WikipediaAPIWrapper(lang="zh")
)
# 初始化搜索引擎工具
search_tool = DuckDuckGoSearchRun()
# 使用工具
wiki_result = wikipedia_tool.run("LangChain")
search_result = search_tool.run("LangChain 最新特性")
print("维基百科结果:", wiki_result)
print("\n搜索结果:", search_result)
3. 查找更多内置工具
要查找LangChain提供的更多内置工具,可以通过以下方式:
- 官方文档:访问 LangChain官方文档 查看完整的工具列表和使用示例
- GitHub仓库:浏览 LangChain GitHub仓库 中的
libs/community/tools目录,了解所有社区贡献的工具 - Python包索引:使用
pip list | grep langchain查看已安装的LangChain相关包,然后通过python -c "from langchain_community.tools import *; print(dir())"查看可用的工具类 - 集成指南:访问 LangChain Integrations 页面,了解与各种服务和API的集成工具
五、Tools模块高级特性
1. 工具参数验证
核心用途:使用Pydantic模型对工具参数进行验证,确保参数的类型和格式正确,减少错误。
代码示例:
from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field, field_validator
# 定义带验证的参数模型
class CalculateRequest(BaseModel):
expression: str = Field(description="要计算的数学表达式")
@field_validator('expression')
def validate_expression(cls, v):
# 简单的表达式验证
allowed_chars = set("0123456789+-*/() ")
if not all(c in allowed_chars for c in v):
raise ValueError("表达式只能包含数字、运算符和括号")
return v
def calculate(expression: str) -> str:
"""计算数学表达式"""
try:
result = eval(expression)
return f"计算结果:{result}"
except Exception as e:
return f"计算错误:{str(e)}"
# 创建结构化工具
calculate_tool = StructuredTool.from_function(
func=calculate,
args_schema=CalculateRequest,
description="计算数学表达式"
)
适用场景:需要确保工具参数正确性的场景,如金融计算、数据处理等。
2. 工具调用缓存
核心用途:缓存工具调用的结果,减少重复计算,提高系统性能。
代码示例:
from langchain_core.tools import Tool
from functools import lru_cache
# 使用lru_cache缓存函数结果
@lru_cache(maxsize=128)
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
print(f"调用天气API获取{city}的天气")
weather_data = {
"北京": "晴,25℃",
"上海": "多云,23℃",
"广州": "阴,28℃"
}
return weather_data.get(city, "未知城市")
# 创建工具
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息,参数为城市名称"
)
# 第一次调用(会执行函数)
print(weather_tool.run("北京"))
# 第二次调用(会使用缓存)
print(weather_tool.run("北京"))
适用场景:工具调用开销较大的场景,如API调用、复杂计算等。
3. 异步工具
核心用途:开发异步工具,支持异步执行,提高系统的并发处理能力。
代码示例:
from langchain_core.tools import Tool
import asyncio
import aiohttp
async def async_get_weather(city: str) -> str:
"""异步获取指定城市的天气信息"""
async with aiohttp.ClientSession() as session:
# 模拟异步API调用
await asyncio.sleep(0.5)
weather_data = {
"北京": "晴,25℃",
"上海": "多云,23℃",
"广州": "阴,28℃"
}
return weather_data.get(city, "未知城市")
# 创建异步工具
async_weather_tool = Tool(
name="async_get_weather",
func=async_get_weather,
description="异步获取指定城市的天气信息,参数为城市名称"
)
# 异步执行
async def main():
result = await async_weather_tool.arun("北京")
print(result)
asyncio.run(main())
适用场景:高并发场景,如多个工具调用并行执行、Web应用等。
六、MCP工具与LangChain工具的区别
1. 概念与定位
LangChain工具:
- 是LangChain框架的核心组件之一,专为大模型应用设计
- 提供了统一的工具接口和调用机制
- 与LangChain的其他组件(如Agent、Chain)深度集成
- 支持结构化参数、异步执行、缓存等高级特性
MCP工具:
- MCP (Model Context Protocol) 工具是一种更通用的模型工具协议
- 专注于定义模型与工具交互的标准接口
- 不依赖于特定框架,可跨框架使用
- 更注重工具的标准化和互操作性
2. 使用方法对比
LangChain工具使用:
from langchain_core.tools import Tool
from langchain_openai import ChatOpenAI
# 定义工具函数
def get_weather(city: str) -> str:
"""获取天气信息"""
return f"{city}的天气是晴天"
# 创建工具
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息"
)
# 绑定工具到模型
llm = ChatOpenAI(model="gpt-4o-mini")
tool_llm = llm.bind_tools([weather_tool])
# 执行
response = tool_llm.invoke("北京的天气怎么样?")
MCP工具使用:
from mcp import Tool
from mcp.server import Server
# 定义工具函数
def get_weather(city: str) -> str:
"""获取天气信息"""
return f"{city}的天气是晴天"
# 创建工具
weather_tool = Tool(
name="get_weather",
description="获取指定城市的天气信息",
parameters={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
)
# 注册工具
server = Server()
server.register_tool(weather_tool, get_weather)
# 启动服务器
server.start()
3. 撰写方法对比
LangChain工具撰写:
- 使用Python类和函数定义工具
- 支持装饰器和Pydantic模型
- 工具描述使用自然语言,注重模型理解
- 集成到LangChain的工作流中
MCP工具撰写:
- 使用JSON Schema定义工具参数
- 更注重工具的标准化描述
- 支持远程调用和跨平台使用
- 独立于特定框架运行
4. 适用场景对比
LangChain工具:
- 适用于构建基于LangChain的大模型应用
- 适合需要与LangChain其他组件深度集成的场景
- 适合快速开发和原型设计
MCP工具:
- 适用于需要跨框架、跨平台工具调用的场景
- 适合构建标准化的工具服务
- 适合企业级应用和多系统集成
七、Tools模块最佳实践
1. 工具描述编写
核心用途:编写清晰、准确的工具描述,使模型能够正确理解和使用工具。
最佳实践:
- 描述工具的功能和用途
- 说明参数的含义和格式
- 提供使用示例
- 说明返回值的格式和含义
示例:
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息。参数:city(城市名称,如'北京'、'上海')。返回值:天气描述字符串,如'晴,25℃'。示例:get_weather('北京')"
)
2. 错误处理
核心用途:为工具添加错误处理机制,确保工具调用失败时能够优雅地处理,提供有用的错误信息。
最佳实践:
- 使用try-except捕获异常
- 提供清晰的错误信息
- 避免工具调用崩溃整个系统
示例:
def safe_calculate(expression: str) -> str:
"""安全计算数学表达式"""
try:
# 验证表达式安全性
if any(c in expression for c in ["__", "import", "exec", "eval"]):
return "表达式不安全"
result = eval(expression)
return f"计算结果:{result}"
except Exception as e:
return f"计算错误:{str(e)}"
3. 工具模块化
核心用途:将工具组织成模块化的结构,提高代码的可维护性和可重用性。
最佳实践:
- 使用类和模块组织相关工具
- 为工具提供清晰的接口
- 避免工具之间的紧耦合
示例:
class WeatherTools:
"""天气相关工具集合"""
@staticmethod
def get_current_weather(city: str) -> str:
"""获取当前天气"""
pass
@staticmethod
def get_weather_forecast(city: str, days: int) -> str:
"""获取天气预报"""
pass
@classmethod
def get_tools(cls):
"""获取工具列表"""
return [
Tool(
name="get_current_weather",
func=cls.get_current_weather,
description="获取指定城市的当前天气"
),
Tool(
name="get_weather_forecast",
func=cls.get_weather_forecast,
description="获取指定城市的天气预报"
)
]
八、常见问题与解决方案
1. 工具调用失败
问题:模型调用工具失败,可能是因为工具描述不清楚或参数格式不正确。
解决方案:
- 编写更清晰、详细的工具描述
- 使用结构化工具和Pydantic模型定义参数
- 提供工具使用示例
示例:
# 改进前
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取天气"
)
# 改进后
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的天气信息。参数:city(城市名称,字符串类型)。返回值:天气描述字符串。示例:get_weather('北京')"
)
2. 工具参数错误
问题:工具参数类型错误或格式不正确,导致工具执行失败。
解决方案:
- 使用StructuredTool和Pydantic模型进行参数验证
- 在工具函数中添加参数检查
- 提供明确的参数格式说明
示例:
from pydantic import BaseModel, Field
class WeatherRequest(BaseModel):
city: str = Field(..., description="城市名称,不能为空")
days: int = Field(1, ge=1, le=7, description="预报天数,1-7天")
weather_tool = StructuredTool.from_function(
func=get_weather,
args_schema=WeatherRequest,
description="获取天气信息"
)
3. 工具调用性能问题
问题:工具调用开销较大,影响系统性能。
解决方案:
- 使用缓存减少重复调用
- 开发异步工具提高并发能力
- 优化工具函数的执行效率
示例:
from functools import lru_cache
@lru_cache(maxsize=100)
def expensive_tool(query: str) -> str:
# 复杂计算或API调用
import time
time.sleep(1) # 模拟耗时操作
return f"结果:{query}"
九、总结:LangChain v1.0+ Tools模块的价值
LangChain v1.0+的Tools模块为大模型应用开发带来了以下价值:
- 扩展模型能力:通过工具集成,使模型能够使用外部功能,突破模型本身的能力限制。
- 标准化接口:提供了统一的工具接口和调用机制,简化了工具的开发和使用。
- 类型安全:通过StructuredTool和Pydantic模型,实现了类型安全的工具调用。
- 模块化设计:支持工具的模块化组织,提高了代码的可维护性和可重用性。
- 智能集成:与Agent框架无缝集成,使模型能够智能地选择和使用工具。
- 丰富的内置工具:提供了大量开箱即用的工具,涵盖信息查询、文件操作、数据处理等多个领域。
- 版本兼容性:v1.0+的架构设计更加现代化,提供了更好的开发者体验和更强大的功能。
- 最佳实践:提供了丰富的最佳实践,如工具描述编写、错误处理、性能优化等。
LangChain v1.0+的Tools模块不仅是一个工具管理系统,更是大模型应用与外部世界交互的桥梁。通过掌握Tools模块的使用,你可以构建更加智能、强大、实用的大模型应用,将AI的能力真正落地到实际业务中。
无论你是开发简单的信息查询工具,还是复杂的多Agent系统,LangChain v1.0+的Tools模块都能为你提供强大的支持。现在就开始使用这些功能,开启你的大模型应用开发之旅吧!
参考链接:
更多推荐




所有评论(0)