LangChain使用AI工具赋能:解锁大语言模型无限潜力

1、Tool 的说明

没有工具的加持,再强大的AI都只是"思想上的巨人",借助工具才能让AI应用的能力真正达到无限的可能。Tools用于扩展大语言模型的能力,使其能够与外部系统、API或自定义函数进行交互,从而完成仅靠文本生成无法实现的任务。

LangChain拥有大量的第三方工具,工具集列表:

https://python.langchain.com/v0.2/docs/integrations/tools/

2、Tool 的要素

工具通常包含如下几个核心元素:

  • name:工具的名称;
  • description:工具的功能描述;
  • 工具输入的JSON模式;
  • 要调用的函数;
  • 与Agent相关:return_direct 是否将工具的结果直接给用户。

使用步骤:

  • 步骤一:将name、description与JSON模式作为上下文提供给LLM;
  • 步骤二:LLM根据提示词推断出要调用的工具,提出具体的参数调用信息;
  • 步骤三:用户需要根据返回的工具调用信息,自行触发工具的回调。

Tool的常用属性:

属性 类型 描述
name str 必须要,在提供给LLM或Agent的工具集中必须是唯一的
description str 描述工具的功能。LLM或Agent将使用此描述作为上下文,使用它确定工具的使用
args_schema Pydantic BaseModel 可用于提供更多信息(例如,few-shot示例) 或验证预期参数
return_direct bool 仅对Agent相关。当为True时,在调用给定工具后,Agent将停止并将结果直接返回给用户

3、自定义工具

3.1 使用@tool装饰器定义工具

说明:装饰器默认使用函数的名称作为工具名称 ,也可以通过参数 name_or_callable 来覆盖此设置;装饰器将使用函数的文档字符串作为工具的描述,因此必须给函数提供文档字符串

示例1:创建一个计算两数之和的工具

python 复制代码
from langchain_core.tools import tool
@tool
def add_num(a:int,b:int) -> int:
    """计算两数之和"""  #必须要有
    return a+b

print(f"name={add_num.name}") # 默认是函数名称
print(f"args={add_num.args}")
print(f"description={add_num.description}") # 默认是函数的说明信息
print(f"return_direct={add_num.return_direct}") # 默认值是false

示例2:手动设置一些默认的参数

python 复制代码
from langchain_core.tools import tool
@tool(name_or_callable = "add_two_number",description="add two number",return_direct = True)
def add_num(a:int,b:int) -> int:
    """计算两数之和"""  #必须要有
    return a+b

print(f"name={add_num.name}")
print(f"args={add_num.args}")
print(f"description={add_num.description}") # 默认是函数的说明信息
print(f"return_direct={add_num.return_direct}") # 默认值是false

工具的调用:

python 复制代码
# 调用工具
add_num.invoke({"a":10,"b":10}) #20

示例3:修改args参数

python 复制代码
from pydantic import Field,BaseModel
from langchain_core.tools import tool

class FieldInfo(BaseModel):
    a:int = Field(description="第1个整形参数")
    b:int = Field(description="第2个整形参数")

@tool(name_or_callable = "add_two_number",description="add two number",return_direct = True,args_schema=FieldInfo)
def add_num(a:int,b:int) -> int:
    """计算两数之和"""  #必须要有
    return a+b

print(f"name={add_num.name}")
print(f"args={add_num.args}")
print(f"description={add_num.description}") # 默认是函数的说明信息
print(f"return_direct={add_num.return_direct}") # 默认值是false

3.2 使用StructuredTool.from_function类方法

相比于第一种方式,这允许更多的配置和同步/异步实现的规范。

示例1:

python 复制代码
from langchain_core.tools import StructuredTool

# 声明一个函数
def search_google(query:str):
    return "最后查询的结果"

# 定义一个工具
search01 = StructuredTool.from_function(
    func = search_google,
    name="Search",
    description = "查询谷歌搜索引擎,并将结果返回"
)
print(f"name={search01.name}")
print(f"args={search01.args}")
print(f"description={search01.description}")
print(f"return_direct={search01.return_direct}")

示例2:修改args参数

python 复制代码
from langchain_core.tools import StructuredTool

# 声明一个函数
def search_google(query:str):
    return "最后查询的结果"

class FieldInfo(BaseModel):
    query:str = Field(description="检索的关键词")

# 定义一个工具
search02 = StructuredTool.from_function(
    func = search_google,
    name="Search",
    description = "查询谷歌搜索引擎,并将结果返回",
    return_direct = True,
    args_schema = FieldInfo
)
print(f"name={search02.name}")
print(f"args={search02.args}")
print(f"description={search02.description}")
print(f"return_direct={search02.return_direct}")

4、工具调用实例

4.1 大模型分析工具的调用

python 复制代码
# 1、获取大模型
#1.导入相关依赖
from langchain_community.tools import MoveFileTool
from langchain_core.messages import HumanMessage
from langchain_core.utils.function_calling import convert_to_openai_function
import os
import dotenv
dotenv.load_dotenv()
from langchain_openai import ChatOpenAI
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
# 定义LLM模型
chat_model =ChatOpenAI(model="gpt-4o-mini",temperature=0)

# 2、获取工具的列表
tools = [MoveFileTool()]
# 3、这里需要将工具转换为openai函数,后续再将函数传入模型调用
functions = [convert_to_openai_function(t) for t in tools]
# 4、获取消息列表
messages = [HumanMessage(content = "将当前目录下的a.txt文件移动到C:\\桌面")]
# 5、调用大模型(传入消息列表、工具列表)
response = chat_model.invoke(input=messages,functions=functions) # invoke调用要传入函数的列表
print(response)

最终的结果就是分析出了需要调用的工具:move_file

如果继续查询天气情况呢?

python 复制代码
functions = [convert_to_openai_function(t) for t in tools]
# 4、获取消息列表
messages = [HumanMessage(content = "明天天气怎么样")]
# 5、调用大模型(传入消息列表、工具列表)
response = chat_model.invoke(input=messages,functions=functions) # invoke调用要传入函数的列表
print(response)

# 输出:content='抱歉,我无法提供实时天气信息。建议您查看天气预报网站或使用天气应用程序获取最新的天气情况。
# additional_kwargs={'refusal': None} 

总结:根据上述代码可以发现AIMessage的核心属性

(1)如果分析出需要调用对应的工具时:

  • content:信息为空,因为大模型要调用工具,因此不会直接返回信息给用户;
  • additional_kwargs:包含function_call字段,指明了具体的函数调用参数和函数名;

(2)如果分析出不需要调用对应的工具:

  • content:信息不为空;
  • additional_kwargs:不包含调用字段;

4.2 如何调用具体大模型分析出来的工具

接着4.1的后续:

步骤一:分析出需要调用哪个工具或函数

python 复制代码
import json
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"])
    print(f"调用工具:{tool_name} \n 参数:{tool_args}")

else:
    print(f"模型回复:{response.content}")

# 输出:调用工具:move_file 
# 参数:{'source_path': 'a.txt', 'destination_path': 'C:\\桌面\\a.txt'}

步骤二:调用对应的工具

python 复制代码
if "move_file" in response.additional_kwargs["function_call"]["name"]:
    tool = MoveFileTool()
    result = tool.run(tool_args) #调用工具
    print(result)

# 输出:File moved successfully from a.txt to C:\桌面\a.txt.
相关推荐
大龄程序员狗哥10 分钟前
第47篇:使用Speech-to-Text API快速构建语音应用(操作教程)
人工智能
KKKlucifer10 分钟前
数据安全合规自动化:策略落地、审计追溯与风险闭环技术解析
人工智能·安全
RWKV元始智能22 分钟前
RWKV超并发项目教程,RWKV-LM训练提速40%
人工智能·rnn·深度学习·自然语言处理·开源
dyj09525 分钟前
Dify - (一)、本地部署Dify+聊天助手/Agent
人工智能·docker·容器
墨染天姬31 分钟前
【AI】Hermes的GEPA算法
人工智能·算法
小超同学你好33 分钟前
OpenClaw 深度解析系列 · 第8篇:Learning & Adaptation(学习与自适应)
人工智能·语言模型·chatgpt
紫微AI43 分钟前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
码途漫谈1 小时前
Easy-Vibe开发篇阅读笔记(四)——前端开发之结合 Agent Skills 美化界面
人工智能·笔记·ai·开源·ai编程
易连EDI—EasyLink1 小时前
易连EDI–EasyLink实现OCR智能数据采集
网络·人工智能·安全·汽车·ocr·edi
冬奇Lab1 小时前
RAG 系列(二):用 LangChain 搭建你的第一个 RAG Pipeline
人工智能·langchain·llm