使用工具和外部环境的交互
在 LangChain 中,工具(Tools)是与外部环境交互的关键部分。通过工具,语言模型能够调用外部API、数据库、Web服务,甚至是执行本地的操作。这使得LangChain不仅仅是一个静态的文本生成引擎,更成为一个可以处理复杂任务的动态系统。
1. 什么是工具(Tools)?
工具是LangChain中的一个核心概念,负责将外部系统或服务封装为可以被模型调用的模块。工具可以是:
- API调用:访问外部的RESTful API。
- 数据库查询:执行SQL查询并获取结果。
- 计算服务:执行数学计算或其他业务逻辑。
- 本地操作:如文件读写或系统指令。
工具的目的是将复杂的外部操作以可控、可调试的方式集成到代理或链条中。
2. 创建自定义工具
自定义工具可以通过继承LangChain的BaseTool类来创建,并实现自己的逻辑。下面是一个简单的例子,展示如何创建一个查询天气的自定义工具:
from langchain.tools import BaseTool
import requests
class WeatherTool(BaseTool):
name = "weather_tool"
description = "查询指定城市的天气"
def _run(self, city: str):
api_key = "your_api_key_here"
url = f"http://api.weatherapi.com/v1/current.json?key={api_key}&q={city}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return f"{city}的天气是{data['current']['condition']['text']},气温为{data['current']['temp_c']}摄氏度。"
else:
return "天气服务不可用,请稍后再试。"
在这个例子中,WeatherTool 通过调用一个天气API查询指定城市的天气,并将结果返回给用户。
3. 工具的核心组件
工具的主要组成部分包括:
- 名称(name):工具的唯一标识符,用于在代理或链条中调用工具时进行区分。
- 描述(description):简单描述工具的用途,帮助代理理解何时应该使用该工具。
- _run方法:工具的核心逻辑,接收输入参数并执行外部操作(如API调用),然后返回结果。
4. 使用工具与外部API交互
工具可以用来和各种外部API进行交互,包括数据查询、支付处理、用户管理等场景。以下是一个调用GitHub API获取用户信息的示例工具:
class GitHubUserTool(BaseTool):
name = "github_user_tool"
description = "获取GitHub用户的信息"
def _run(self, username: str):
url = f"https://api.github.com/users/{username}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return f"{username}的GitHub用户名是{data['login']},公开仓库数量为{data['public_repos']}。"
else:
return "无法获取用户信息,请检查用户名是否正确。"
通过此工具,代理可以动态调用GitHub API获取用户数据,并返回结果给用户。
5. 在代理中使用工具
一旦定义了工具,可以将它们集成到代理中,让代理根据用户的输入动态调用工具来处理任务。
示例:代理调用工具
from langchain.agents import initialize_agent
from langchain.llms import OpenAI
llm = OpenAI(model_name="gpt-3.5-turbo")
# 定义工具列表
tools = [WeatherTool(), GitHubUserTool()]
# 初始化代理
agent = initialize_agent(llm=llm, tools=tools, agent_type="zero-shot")
# 使用代理查询天气
response = agent.run("查询上海的天气")
print(response)
# 使用代理获取GitHub用户信息
response = agent.run("获取GitHub用户octocat的信息")
print(response)
在这个例子中,代理会根据输入内容自动决定调用哪个工具来完成任务。比如,当用户询问天气时,代理会调用WeatherTool;当用户想查询GitHub信息时,代理会调用GitHubUserTool。
6. 与本地环境的交互
除了与API进行交互,工具还可以用于与本地环境交互。比如可以创建一个工具来执行本地文件读写操作:
class FileTool(BaseTool):
name = "file_tool"
description = "读取本地文件的内容"
def _run(self, filepath: str):
try:
with open(filepath, 'r') as file:
return file.read()
except FileNotFoundError:
return "文件未找到,请检查路径。"
此工具可以被代理调用,用于读取本地文件的内容并返回。
7. 多工具组合
LangChain中的代理可以集成多个工具,并根据任务需要调用不同的工具完成复杂的操作。例如,可以创建一个代理,既能够调用API查询数据,又能够读取本地文件,甚至执行一些逻辑计算。
示例:多工具组合
class CalculationTool(BaseTool):
name = "calculation_tool"
description = "进行简单的数学计算"
def _run(self, expression: str):
try:
result = eval(expression)
return f"结果是:{result}"
except:
return "表达式无效,请输入正确的数学表达式。"
tools = [WeatherTool(), GitHubUserTool(), FileTool(), CalculationTool()]
agent = initialize_agent(llm=llm, tools=tools, agent_type="zero-shot")
# 使用代理进行多工具组合
response = agent.run("查询上海的天气,然后计算5加上10的结果")
print(response)
在这个示例中,代理首先调用WeatherTool获取天气信息,然后调用CalculationTool进行数学计算,实现了多工具协同工作。
8. 异步工具交互
如果工具调用涉及耗时操作(如API请求或文件处理),可以使用异步工具来提升性能和响应速度。LangChain支持异步工具交互,通过async函数调用来实现并发操作。
示例:异步API调用
class AsyncWeatherTool(BaseTool):
name = "async_weather_tool"
description = "异步查询天气"
async def _run(self, city: str):
api_key = "your_api_key_here"
url = f"http://api.weatherapi.com/v1/current.json?key={api_key}&q={city}"
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
data = await response.json()
return f"{city}的天气是{data['current']['condition']['text']},气温为{data['current']['temp_c']}摄氏度。"
else:
return "天气服务不可用,请稍后再试。"
通过异步调用工具,可以同时发起多个请求,显著提升代理处理复杂任务的效率。
9. 总结
通过工具与外部环境的交互,LangChain可以大幅度扩展语言模型的功能,使其能够与外部API、本地环境、数据库等进行交互,从而实现更为复杂和动态的任务。开发者可以根据需求构建自定义工具,并将它们集成到代理中,处理多种任务和场景。
