LangChain实战(十二):自定义Tools扩展Agent能力
本文是《LangChain实战课》系列的第十二篇,将深入探讨如何通过自定义Tools来扩展LangChain Agent的能力。你将学习如何创建自己的Tool函数,让Agent能够调用外部API、查询数据库或执行任何自定义逻辑,从而极大扩展AI应用的能力边界。
前言
在前一篇文章中,我们学习了如何使用LangChain的Agents和内置工具来让LLM自主使用工具。然而,内置工具的功能是有限的,真正的强大之处在于能够根据特定需求创建自定义工具。今天,我们将学习如何编写自定义Tools,让Agent能够与外部世界进行交互,执行各种 specialized 的任务。
自定义Tool的基本结构
在LangChain中,一个自定义Tool通常包括以下要素:
-
name: 工具的名称,Agent通过名称来识别工具
-
description: 工具的描述,用于帮助LLM理解工具的功能和何时使用它
-
args_schema (可选): 定义输入参数的格式,有助于LLM生成正确的参数
-
_run 方法: 同步执行工具的主要逻辑
-
_arun 方法 (可选): 异步执行工具的主要逻辑
创建第一个自定义Tool
让我们从一个简单的例子开始,创建一个查询天气的自定义Tool。
from langchain.tools import BaseTool
from typing import Type
from pydantic import BaseModel, Field
import requests# 定义输入参数的模型
class WeatherCheckInput(BaseModel):location: str = Field(description="需要查询天气的城市名称")class WeatherTool(BaseTool):name = "weather_check"description = "查询指定城市的当前天气情况,包括温度、湿度和天气状况"args_schema: Type[BaseModel] = WeatherCheckInputdef _run(self, location: str):# 这里我们使用一个模拟的天气数据,实际应用中你可以调用天气API# 例如OpenWeatherMap、WeatherAPI等weather_data = {"beijing": "北京: 晴天, 22°C, 湿度45%","shanghai": "上海: 多云, 25°C, 湿度60%","guangzhou": "广州: 阵雨, 28°C, 湿度75%","shenzhen": "深圳: 晴天, 27°C, 湿度65%"}# 获取天气信息,如果城市不存在则返回错误信息weather_info = weather_data.get(location.lower())if weather_info:return weather_infoelse:return f"抱歉,找不到城市 {location} 的天气信息"async def _arun(self, location: str):# 异步实现,这里我们直接调用同步方法return self._run(location)# 使用自定义Tool
weather_tool = WeatherTool()
print(weather_tool.run("beijing"))
集成外部API:创建一个真实的天气查询Tool
现在让我们创建一个真正调用外部API的天气查询Tool。我们将使用OpenWeatherMap API(你需要注册获取API密钥)。
import os
from langchain.tools import BaseTool
from typing import Type
from pydantic import BaseModel, Field
import requests# 设置OpenWeatherMap API密钥
os.environ["OPENWEATHER_API_KEY"] = "your_api_key_here"class RealWeatherCheckInput(BaseModel):location: str = Field(description="需要查询天气的城市名称")class RealWeatherTool(BaseTool):name = "real_weather_check"description = "查询指定城市的真实天气情况,包括温度、湿度、天气状况和风速"args_schema: Type[BaseModel] = RealWeatherCheckInputdef _run(self, location: str):api_key = os.getenv("OPENWEATHER_API_KEY")if not api_key:return "请设置OPENWEATHER_API_KEY环境变量"# 调用OpenWeatherMap APIbase_url = "http://api.openweathermap.org/data/2.5/weather"params = {"q": location,"appid": api_key,"units": "metric", # 使用摄氏度"lang": "zh_cn" # 中文描述}try:response = requests.get(base_url, params=params)data = response.json()if response.status_code == 200:# 解析天气数据weather = data