LangChain使用之Tools
文章摘要: 本文介绍了LangChain中Tools的概念与使用方法。Tools用于扩展大语言模型(LLM)的能力,使其能与外部系统交互。Tools由名称、描述、参数模式等属性组成。文章详细展示了两种自定义Tools的方式:使用@tool装饰器和StructuredTool.from_function()方法,并提供了完整的代码示例。最后,文章演示了如何实现大模型调用工具的过程,包括判断调用时机、
0 关于Tools
Tools 用于扩展大语言模型(LLM)的能力,使其能够与外部系统、API 或自定义函数交互,从而完成仅靠文本生成无法实现的任务(如搜索、计算、数据库查询等)。
即大模型本质上相当于一个大脑,单纯靠大脑是做不成事的,还需要“手臂”等“身体器官”组合才能完成一个现实中的人物,单纯的大模型我们称为LLM,而加上工具调用后即可称为Agent了
1 Tools的组成
Tool由几个常用属性组成:
| 属性 | 类型 | 描述 |
|---|---|---|
| name | str | 必选,工具名,在提供给LLM或Agent的工具集中必须是唯一的 |
| description | str | 可选,描述工具的功能。LLM或Agent将使用此描述作 为上下文,使用它确定工具的使用 |
| args_schema | Pydantic BaseModel | 可选,用于描述参数的类型以及作用描述 |
| return_direct | boolean | 仅对Agent相关。当为True时,在调用给定工具后,Agent将 停止并将结果直接返回给用户。 |
2 自定义Tools方式
一共有两种,一个是使用**@Tool装饰器的方式,另一个是使用构造器类方法StructuredTool.from_function**的方式。
2.1 使用@Tool装饰器的方式
装饰器默认使用函数名称作为工具名称,但可以通过参数name_or_callable来覆盖此设置。 同时,装饰器将使用函数的文档字符串作为工具的描述 ,因此函数必须提供文档字符串。
2.1.1 示例代码1
示例使用装饰器方式构造了一个两数之和的工具,本质是一个函数,其中函数的文档字符串会作为工具的描述
from langchain.tools import tool
@tool
def add_two_numbers(number1:int, number2:int)->int:
"""两个整数相加"""
return number1 + number2
print(f"name={add_two_numbers.name}")
print(f"args={add_two_numbers.args}")
print(f"description={add_two_numbers.description}")
print(f"return_direct={add_two_numbers.return_direct}")
result = add_two_numbers.invoke(({"number1": 1, "number2": 2}))
print(f"result={result}")
2.1.2 运行效果1
输出构造出的工具的各个属性以及工具被运行正确输出两数之和
2.1.3 示例代码2
以下示例代码是在原来的装饰器方式的基础上修改其参数(工具名、描述、参数模板等)
from langchain.tools import tool
from pydantic import BaseModel, Field
class FieldInfo(BaseModel):
number1: int = Field(description="第一个参数")
number2: int = Field(description="第二个参数")
@tool(name_or_callable="add_two_numbers", description="计算两数之和", args_schema=FieldInfo)
def add_two_numbers(number1:int, number2:int)->int:
return number1 + number2
print(f"name={add_two_numbers.name}")
print(f"args={add_two_numbers.args}")
print(f"description={add_two_numbers.description}")
print(f"return_direct={add_two_numbers.return_direct}")
result = add_two_numbers.invoke(({"number1": 1, "number2": 2}))
print(f"result={result}")
2.1.4 运行效果2
根据修改的参数输出工具各个属性
2.2 使用StructuredTool的from_function()
StructuredTool.from_function 类方法提供了比 @tool 装饰器更多的可配置性,而无需太多额外的代码。
2.2.1 示例代码
from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field
class FieldInfo(BaseModel):
number1: int = Field(description="第一个参数")
number2: int = Field(description="第二个参数")
def add_two_numbers(number1, number2):
return number1 + number2
addTool = StructuredTool.from_function(
func=add_two_numbers,
name="add_two_numbers",
description="add two numbers",
args_schema=FieldInfo
)
print(f"name={addTool.name}")
print(f"args={addTool.args}")
print(f"description={addTool.description}")
print(f"return_direct={addTool.return_direct}")
result = addTool.invoke(({"number1": 1, "number2": 2}))
print(f"result={result}")
2.2.2 运行效果
运行效果和上面的@tool方式的效果一致就不截图了
3 实现大模型调用工具
3.1 大模型判断是否要调用工具及输出格式
普通模型调用,即不没有在大模型上加入functions或者大模型判断没有可以调用的工具时输出格式如下,即不出现function_call 字段
# 模型调用
response = chat_model.invoke(
input=[HumanMessage(content="1加6等于多少呀")],
# functions=functions
)
运行效果如下:
如果大模型选择调用工具则输出格式如下,此时content为空,出现function_call字段,里面包含工具名以及参数
3.2 大模型调用工具
上述已经得到大模型调用工具时的输出,此时只需要在大模型需要调用工具时调用对应的工具,将大模型判断得到的参数填入该工具函数中即可,完整代码示例如下,该示例提问大模型一个两数相加问题,大模型会自主调用两数相加工具。
import json
from langchain.tools import tool
from langchain_core.messages import HumanMessage
from langchain_core.utils.function_calling import convert_to_openai_function
from pydantic import BaseModel, Field
import os
import dotenv
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
os.environ["OPENAI_BASE_URL"] = os.getenv("QWEN_BASE_URL")
os.environ["OPENAI_API_KEY"] = os.getenv("QWEN_API_KEY")
# 获取对话模型
chat_model = ChatOpenAI(
model="qwen-plus"
)
# 参数模板
class FieldInfo(BaseModel):
number1: int = Field(description="第一个参数")
number2: int = Field(description="第二个参数")
# 工具定义
@tool(name_or_callable="add_two_numbers", description="计算两数之和", args_schema=FieldInfo)
def add_two_numbers(number1:int, number2:int)->int:
return number1 + number2
# 加入工具列表
tools = [add_two_numbers]
# 工具转openai函数
functions = [convert_to_openai_function(t) for t in tools]
# 模型调用
response = chat_model.invoke(
input=[HumanMessage(content="1加6等于多少呀")],
functions=functions
)
print(response)
if "function_call" in response.additional_kwargs:
tool_name = response.additional_kwargs["function_call"]["name"]
tool_args = json.loads(response.additional_kwargs["function_call"]["arguments"])
if tool_name == "add_two_numbers":
result = add_two_numbers.invoke(tool_args)
print("工具执行结果", result)
else:
print("模型回复", response.content)
运行效果:
大模型进行工具调用最后执行工具对提问的两数之和进行了计算得到正确答案
更多推荐

所有评论(0)