在 LangChain 中,工具(Tools) 是为语言模型(LLM)或代理(Agents)提供外部功能或数据的接口,扩展了模型的能力,使其能够执行复杂任务,例如搜索、计算、数据库查询或与 API 交互。工具是 LangChain 生态中实现交互性和动态推理的关键组件,尤其在代理架构中,用于处理需要外部资源或特定操作的任务。
以下是对 LangChain 工具的详细介绍,涵盖其定义、类型、工作原理、实现方式、应用场景、代码示例、优化建议以及与生态系统的结合。
1. 什么是 LangChain 的工具?
工具是 LangChain 中的模块化组件,允许代理或链调用外部服务、执行操作或访问数据。工具的核心功能是:
- 输入:接收代理或用户的指令(通常是字符串或结构化数据)。
- 执行:调用外部功能(如 API、数据库、计算逻辑)。
- 输出:返回结果(通常是字符串或结构化数据),供代理或链进一步处理。
工具在以下场景中扮演重要角色:
- 增强模型能力:弥补语言模型在数学、实时数据或特定领域知识上的不足。
- 动态交互:让代理根据任务选择和调用合适的工具。
- 自动化工作流:实现复杂任务的分步执行(如搜索后总结)。
工具通常与 代理(Agents) 结合,通过 ReAct(推理+行动)或其他推理框架动态选择和调用。
2. 工具的工作原理
工具的工作流程如下:
- 定义工具:指定工具的名称、描述和执行逻辑(函数或类)。
- 注册工具:将工具提供给代理或链,代理根据任务描述选择工具。
- 调用工具:代理生成工具调用的指令(包括输入参数),工具执行并返回结果。
- 处理结果:代理或链将工具输出整合到工作流中,生成最终响应。
工具的核心依赖:
- 工具描述:帮助代理理解工具的功能和适用场景。
- 输入解析:确保工具能正确处理代理提供的输入。
- 输出格式:工具返回的结果应与代理或链的期望兼容。
3. LangChain 工具的类型
LangChain 提供了多种内置工具,同时支持自定义工具。以下是主要工具类型的详细介绍:
(1) 内置工具
LangChain 提供了一系列开箱即用的工具,通常在 langchain_community.tools
或特定集成包中。
(a) SerpAPI
- 功能:通过 SerpAPI 调用 Google 搜索,获取实时网页结果。
- 特点:
- 适合获取最新信息(如新闻、趋势)。
- 返回结构化搜索结果。
- 适用场景:
- 实时问答。
- 研究或信息收集。
- 安装:
pip install langchain-community google-search-results
- 示例:
from langchain_community.tools import SerpAPIWrapper import os os.environ["SERPAPI_API_KEY"] = "your-serpapi-key" search = SerpAPIWrapper() result = search.run("量子计算的最新进展") print(result)
(b) Wikipedia
- 功能:查询 Wikipedia 的内容。
- 特点:
- 适合获取百科知识。
- 返回简洁的页面摘要或全文。
- 适用场景:
- 通用知识查询。
- 教育或背景研究。
- 安装:
pip install wikipedia
- 示例:
from langchain_community.tools import WikipediaQueryRun from langchain_community.utilities import WikipediaAPIWrapper wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()) result = wikipedia.run("量子计算") print(result)
(c) Arxiv
- 功能:查询 Arxiv 学术论文。
- 特点:
- 返回论文摘要、标题等信息。
- 适合学术研究。
- 适用场景:
- 检索最新研究成果。
- 学术问答。
- 安装:
pip install arxiv
- 示例:
from langchain_community.tools import ArxivQueryRun arxiv = ArxivQueryRun() result = arxiv.run("quantum computing") print(result)
(d) PythonREPL
- 功能:执行 Python 代码,适合计算或编程任务。
- 特点:
- 在安全沙箱中运行代码。
- 返回代码执行结果。
- 适用场景:
- 数学计算。
- 数据处理。
- 示例:
from langchain_community.tools import PythonREPLTool python_repl = PythonREPLTool() result = python_repl.run("print(2 + 2)") print(result)
(e) DuckDuckGoSearch
- 功能:通过 DuckDuckGo 搜索引擎获取网页结果。
- 特点:
- 隐私友好,无需 API 密钥。
- 返回简洁的搜索结果。
- 适用场景:
- 替代 Google 搜索。
- 快速信息检索。
- 安装:
pip install duckduckgo-search
- 示例:
from langchain_community.tools import DuckDuckGoSearchRun search = DuckDuckGoSearchRun() result = search.run("量子计算") print(result)
(f) Other Built-in Tools
- Wolfram Alpha:数学和科学计算。
- Zapier:自动化工作流集成。
- Tavily Search:优化的研究搜索。
- File System Tools:读写本地文件。
- SQL Database Tools:查询数据库。
- 安装示例:
pip install wolframalpha zapier
(2) 工具包(Toolkits)
工具包是针对特定领域的工具集合,包含多个相关工具。
(a) SQLDatabaseToolkit
- 功能:提供数据库操作工具(如查询、表描述)。
- 适用场景:从数据库中检索结构化数据。
- 示例:
from langchain_community.agent_toolkits import SQLDatabaseToolkit from langchain_community.utilities import SQLDatabase from langchain_openai import ChatOpenAI db = SQLDatabase.from_uri("sqlite:///example.db") llm = ChatOpenAI(api_key="your-openai-key") toolkit = SQLDatabaseToolkit(db=db, llm=llm) tools = toolkit.get_tools() print([tool.name for tool in tools]) # 列出工具
(b) JsonToolkit
- 功能:操作 JSON 数据(如查询、修改)。
- 适用场景:处理 API 返回的 JSON 数据。
- 示例:
from langchain_community.agent_toolkits import JsonToolkit from langchain_community.tools.json.tool import JsonSpec json_data = {"name": "Alice", "age": 30} json_spec = JsonSpec(dict_=json_data) toolkit = JsonToolkit(spec=json_spec) tools = toolkit.get_tools()
(c) Other Toolkits
- OpenAPIToolkit:调用 OpenAPI 规范的 API。
- ZapierToolkit:集成 Zapier 自动化。
- VectorStoreToolkit:操作向量存储。
(3) 自定义工具
开发者可以通过 Tool
类或 @tool
装饰器创建自定义工具。
(a) 使用 Tool 类
- 示例:
from langchain_core.tools import Tool def calculator(expression: str) -> str: return str(eval(expression)) calc_tool = Tool( name="Calculator", func=calculator, description="执行数学计算,输入为数学表达式(如 '2 + 2')。" ) result = calc_tool.run("2 + 2") print(result) # 输出:4
(b) 使用 @tool 装饰器
- 示例:
from langchain_core.tools import tool @tool def calculator(expression: str) -> str: """执行数学计算,输入为数学表达式(如 '2 + 2')。""" return str(eval(expression)) result = calculator.run("2 + 2") print(result) # 输出:4
© 结构化工具
- 功能:支持结构化输入(如 JSON Schema),适合复杂任务。
- 示例:
from langchain_core.tools import StructuredTool from pydantic import BaseModel class CalcInput(BaseModel): a: float b: float def add_numbers(input: CalcInput) -> float: return input.a + input.b calc_tool = StructuredTool.from_function( func=add_numbers, name="Adder", description="将两个数字相加。" ) result = calc_tool.run({"a": 2, "b": 3}) print(result) # 输出:5
4. 工具的应用场景
工具在以下场景中广泛应用:
- 实时信息检索:
- 使用
SerpAPI
或DuckDuckGoSearch
获取最新数据。 - 示例:回答“今天的天气”。
- 使用
- 数学与计算:
- 使用
PythonREPL
或Wolfram Alpha
执行计算。 - 示例:解决复杂数学问题。
- 使用
- 数据库查询:
- 使用
SQLDatabaseToolkit
从数据库提取数据。 - 示例:查询销售记录。
- 使用
- 自动化工作流:
- 使用
ZapierToolkit
触发外部动作。 - 示例:发送邮件或更新 CRM。
- 使用
- 学术研究:
- 使用
Arxiv
或Wikipedia
获取知识。 - 示例:查询最新论文。
- 使用
- 文件操作:
- 使用文件系统工具读写文件。
- 示例:分析日志文件。
- 自定义任务:
- 使用自定义工具实现特定功能。
- 示例:调用公司内部 API。
5. 工具的实现与代码示例
综合示例:代理使用多种工具
以下是一个代理结合搜索和计算工具的示例:
from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent, AgentType
from langchain_core.tools import Tool
from langchain_community.tools import DuckDuckGoSearchRun
# 定义自定义工具
def calculator(expression: str) -> str:
return str(eval(expression))
calc_tool = Tool(
name="Calculator",
func=calculator,
description="执行数学计算,输入为数学表达(如 '2 + 2')。"
)
# 初始化内置工具
search_tool = DuckDuckGoSearchRun()
# 工具列表
tools = [calc_tool, search_tool]
# 初始化代理
llm = ChatOpenAI(api_key="your-openai-key")
agent = initialize_agent(
tools=tools,
llm=llm,
agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# 执行任务
result = agent.invoke("计算 5 + 3 并搜索量子计算的最新进展")
print(result)
输出:
[AgentExecutor] 正在执行...
[Tool: Calculator] 输入:5 + 3
[Tool Output] 8
[Tool: DuckDuckGoSearch] 输入:量子计算的最新进展
[Tool Output] 量子计算的最新研究...
[Final Answer] 计算结果为 8,量子计算的最新进展包括...
6. 工具的优化建议
(1) 提高工具选择准确性
- 清晰的描述:
- 工具描述应明确功能和输入格式。
- 示例:
description="搜索网页,返回最新信息。输入为查询字符串。"
。
- 结构化输入:
- 使用
StructuredTool
确保输入格式正确。 - 示例:定义 Pydantic 模型验证输入。
- 使用
- 工具数量:
- 限制工具数量(通常少于 10 个),避免代理选择困难。
(2) 提高性能
- 缓存工具结果:
- 使用 LangChain 的缓存机制。
from langchain.globals import set_llm_cache from langchain.cache import SQLiteCache set_llm_cache(SQLiteCache(database_path="cache.db"))
- 异步工具:
- 实现异步工具以支持高并发。
@tool async def async_search(query: str) -> str: import aiohttp async with aiohttp.ClientSession() as session: async with session.get(f"https://api.example.com?q={query}") as resp: return await resp.text()
- 批量处理:
- 批量调用工具,减少开销。
(3) 错误处理
- 回退机制:
- 为工具配置回退。
from langchain_core.runnables import RunnableWithFallbacks search_tool_with_fallback = search_tool.with_fallbacks([DuckDuckGoSearchRun()])
- 异常捕获:
- 在工具逻辑中处理异常。
@tool def safe_calculator(expression: str) -> str: try: return str(eval(expression)) except Exception as e: return f"计算错误:{e}"
(4) 监控与调试
- 回调:
- 使用回调记录工具调用。
from langchain_core.callbacks import BaseCallbackHandler class ToolCallback(BaseCallbackHandler): def on_tool_start(self, serialized, input_str, **kwargs): print(f"工具 {serialized['name']} 开始,输入:{input_str}")
- LangSmith:
- 分析工具的使用频率和性能。
from langsmith import Client agent.invoke(input, config={"callbacks": [Client(api_key="your-langsmith-key")]})
7. 注意事项
- 工具描述:
- 描述不清晰可能导致代理误选工具。
- 确保描述简洁且明确适用场景。
- 安全性:
- 避免在工具中执行不安全的代码(如
eval
)。 - 使用沙箱环境(如
PythonREPL
的安全模式)。
- 避免在工具中执行不安全的代码(如
- 性能:
- 工具调用可能增加延迟,需优化 API 请求或计算逻辑。
- 缓存高频工具结果。
- 兼容性:
- 确保工具输出与代理或链的期望格式一致。
- 使用
OutputParser
规范化输出。
- 成本:
- 外部 API(如 SerpAPI)可能产生费用,需监控使用量。
- 优先使用免费或低成本工具(如 DuckDuckGo)。
8. 与其他模块的结合
- 代理(Agents):
- 工具是代理的核心组件,通过 ReAct 推理选择工具。
agent = initialize_agent(tools, llm, agent_type="zero-shot-react-description")
- 链(Chains):
- 工具可以嵌入链中,作为工作流的一部分。
from langchain.chains import LLMChain chain = LLMChain(llm=llm, prompt=prompt, tools=[search_tool])
- 回调(Callbacks):
- 监控工具调用过程。
- 缓存(Cache):
- 缓存工具结果,减少重复调用。
- LangSmith:
- 分析工具的性能和选择准确性。
9. 学习资源
- 官方文档:https://python.langchain.com/docs/modules/tools
- GitHub 示例:https://github.com/langchain-ai/langchain
- LangSmith:用于调试工具调用(https://smith.langchain.com)。
- 社区教程:LangChain 官方博客、YouTube 视频。
10. 总结
- 定义:工具是为代理或链提供外部功能的接口,扩展语言模型能力。
- 类型:
- 内置工具:
SerpAPI
,Wikipedia
,Arxiv
,PythonREPL
,DuckDuckGoSearch
等。 - 工具包:
SQLDatabaseToolkit
,JsonToolkit
,OpenAPIToolkit
等。 - 自定义工具:
Tool
,@tool
,StructuredTool
。
- 内置工具:
- 工作原理:定义 → 注册 → 调用 → 处理结果。
- 应用场景:信息检索、计算、数据库查询、自动化、研究、自定义任务。
- 优化点:描述准确性、性能、错误处理、监控。
- 注意事项:描述、安全性、性能、兼容性、成本。