LangChain - Tool Calling 工具调用

文章目录

    • 介绍
    • 组件
      • 1、`ChatModel.bind_tools(...)`
      • 2、`AIMessage.tool_calls`
      • 3、`create_tool_calling_agent()`
    • 三、LangGraph
      • `with_structured_output`
    • 四、结论


本文翻译整理自:Tool Calling with LangChain
https://blog.langchain.dev/tool-calling-with-langchain/


TLDR:我们正在引入一个 AIMessage 的新tool_calls属性。 越来越多的 LLM 提供商正在公开 API 以实现可靠的工具调用。新属性的目标是提供一个与工具调用交互的标准接口。

它完全向后兼容,并且支持所有具有本机工具调用支持的模型。
为了访问这些最新功能,您需要升级您的langchain_core和合作伙伴的软件包版本。

YouTube 演练 : https://youtu.be/zCwuAlpQKTM?ref=blog.langchain.dev


Python:

  • 显示工具调用能力状态的聊天模型列表 : https://python.langchain.com/docs/integrations/chat
  • 工具调用讲解新的工具调用接口 : https://python.langchain.com/docs/modules/model_io/chat/function_calling
  • 工具调用代理展示了如何创建使用标准化工具调用接口的代理 : https://python.langchain.com/docs/modules/agents/agent_types/tool_calling
  • LangGraph notebook展示了如何创建使用标准化工具调用接口的LangGraph代理 : https://github.com/langchain-ai/langchain/blob/master/cookbook/tool_call_messages.ipynb

JS:

  • 显示工具调用能力状态的聊天模型列表
  • 工具调用讲解新的工具调用接口
  • 工具调用代理展示了如何创建使用标准化工具调用接口的代理

介绍

大型语言模型 (LLM) 可以通过工具调用功能与外部数据源交互。
工具调用是一种强大的技术,允许开发人员构建复杂的应用程序,这些应用程序可以利用 LLM 来访问、交互和操作数据库、文件和 API 等外部资源。

提供商已经将本机工具调用功能引入到他们的模型中。
在实践中,当 LLM 为提示提供自动完成功能时,除了纯文本之外,它还可以返回工具调用列表。
大约一年前,OpenAI 率先发布了“函数调用”,并在 11 月份迅速演变为“工具调用”。
此后,其他模型提供商也紧随其后:Gemini(12 月)、Mistral(2 月)、Fireworks(3 月)、Together(3 月)、Groq(4 月)、Cohere(4 月)和 Anthropic(4 月) 。

所有这些提供商都暴露了略有不同的接口(特别是:OpenAI、Anthropic 和 Gemini,这三个性能最高的模型是不兼容的)。
我们听到社区希望有一个用于工具调用的标准化接口,以便在这些提供程序之间轻松切换,我们很高兴今天发布该接口。

标准接口包括:

  • ChatModel.bind_tools():将工具定义附加到模型调用的方法。

  • AIMessage.tool_calls:从模型返回的属性AIMessage,用于轻松访问模型决定进行的工具调用。

  • create_tool_calling_agent()``bind_tools:一个代理构造函数,可与实现 bind_tools 并返回 的任何模型一起使用tool_calls

让我们看一下每个组件。



组件


1、ChatModel.bind_tools(...)

为了允许模型使用工具,我们需要告诉它哪些工具可用。
我们通过指定将工具定义列表传递给模型来实现此目的,其中包括工具参数的架构。
工具定义的确切格式取决于模型提供者 - OpenAI 需要一个包含 “name”, “description”, 和 “parameters” 键的字典,而 Anthropic 需要 “name”, “description”, 和 “input_schema”.。

ChatModel.bind_tools提供由所有工具调用模型实现的标准接口,使您可以指定模型可以使用哪些工具。
您不仅可以传入原始工具定义(字典),还可以传入从中派生工具定义的对象:即 Pydantic 类、LangChain 工具和任意函数。
这使得创建可与任何工具调用模型一起使用的通用工具定义变得很容易:

from langchain_anthropic import ChatAnthropic
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_core.tools import tool# ✅ Pydantic class
class multiply(BaseModel):"""Return product of 'x' and 'y'."""x: float = Field(..., description="First factor")y: float = Field(..., description="Second factor")# ✅ LangChain tool
@tool
def exponentiate(x: float, y: float) -> float:"""Raise 'x' to the 'y'."""return x**y# ✅ Functiondef subtract(x: float, y: float) -> float:"""Subtract 'x' from 'y'."""return y-x# ✅ OpenAI-format dict
# Could also pass in a JSON schema with "title" and "description" 
add = {"name": "add","description": "Add 'x' and 'y'.","parameters": {"type": "object","properties": {"x": {"type": "number", "description": "First number to add"},"y": {"type": "number", "description": "Second number to add"}},"required": ["x", "y"]}
}llm = ChatAnthropic(model="claude-3-sonnet-20240229", temperature=0)# Whenever we invoke `llm_with_tool`, all three of these tool definitions
# are passed to the model.
llm_with_tools = llm.bind_tools([multiply, exponentiate, add, subtract])

如果我们想使用不同的工具调用模型,我们的代码看起来非常相似:

from langchain_openai import ChatOpenAIllm = ChatOpenAI(model="gpt-4-turbo", temperature=0)
llm_with_tools = llm.bind_tools([multiply, exponentiate, add, subtract])

那么,呼叫是什么llm_with_tools样子的呢?这就是问题AIMessage.tool_calls所在。


2、AIMessage.tool_calls

在使用工具调用模型之前,模型返回的任何工具调用都可以在 AIMessage.additional_kwargsAIMessage.content 中找到,具体取决于模型提供者的 API,并遵循提供者特定的格式。
也就是说,您需要自定义逻辑来从不同模型的输出中提取工具调用。
现在,AIMessage.tool_calls提供了用于获取模型工具调用的标准化接口。
因此,在使用绑定工具调用模型后,您将获得以下形式的输出:

llm_with_tools.invoke([("system", "You're a helpful assistant"), ("human", "what's 5 raised to the 2.743"),
])# 👀 Notice the tool_calls attribute 👀# -> AIMessage(
# 	  content=..., 
# 	  additional_kwargs={...},
# 	  tool_calls=[{'name': 'exponentiate', 'args': {'y': 2.743, 'x': 5.0}, 'id': '54c166b2-f81a-481a-9289-eea68fc84e4f'}]
# 	  response_metadata={...}, 
# 	  id='...'
#   )

其中AIMessage具有一个tool_calls: List[ToolCall]属性,如果有任何工具调用,该属性将被填充,并且将遵循工具调用的标准接口:

class ToolCall(TypedDict):name: strargs: Dict[str, Any]id: Optional[str]

也就是说,无论您是调用 Anthropic、OpenAI、Gemini 等,只要有工具调用,它就会在AIMessage.tool_calls 作为 ToolCall

我们添加了一些其他属性来处理流式工具调用块和无效工具调用。
在此处阅读工具调用文档中的更多信息。


3、create_tool_calling_agent()

LLM 工具调用能力最强大、最明显的用途之一是构建代理。
LangChain 已经有一个create_openai_tools_agent()构造函数,可以轻松构建具有遵循 OpenAI 工具调用 API 的工具调用模型的代理,但这不适用于 Anthropic 和 Gemini 等模型。
由于有了新的bind_tools()tool_calls接口,我们添加了一个create_tool_calling_agent()可与任何工具调用模型一起使用的工具。

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import ConfigurableField
from langchain_core.tools import tool
from langchain.agents import create_tool_calling_agent, AgentExecutor@tool
def multiply(x: float, y: float) -> float:"""Multiply 'x' times 'y'."""return x * y@tool
def exponentiate(x: float, y: float) -> float:"""Raise 'x' to the 'y'."""return x**y@tool
def add(x: float, y: float) -> float:"""Add 'x' and 'y'."""return x + yprompt = ChatPromptTemplate.from_messages([("system", "you're a helpful assistant"), ("human", "{input}"), ("placeholder", "{agent_scratchpad}"),
])tools = [multiply, exponentiate, add]llm = ChatAnthropic(model="claude-3-sonnet-20240229", temperature=0)agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)agent_executor.invoke({"input": "what's 3 plus 5 raised to the 2.743. also what's 17.24 - 918.1241", })

我们可以使用 VertexAI 代替

from langchain_google_vertexai import ChatVertexAIllm = ChatVertexAI(model="gemini-pro", temperature=0, convert_system_message_to_human=True
)
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)agent_executor.invoke({"input": "what's 3 plus 5 raised to the 2.743. also what's 17.24 - 918.1241", })

或者OpenAI

llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)agent_executor.invoke({"input": "what's 3 plus 5 raised to the 2.743. also what's 17.24 - 918.1241", })

有关新代理的完整文档,请参阅 https://python.langchain.com/docs/modules/agents/agent_types/tool_calling/。 s


三、LangGraph

如果您还没有检查过LangGraph,那么您绝对应该检查一下。
它是 LangChain 的扩展,可以轻松构建任意代理和多代理流。
正如您可以想象的那样,使用新tool_calls界面还可以使构建 LangGraph 代理或流时的工作变得更加简单。
查看此处的笔记本,了解如何tool_calls在 LangGraph 代理中使用的详细演练。


with_structured_output

我们最近发布了ChatModel.with_structured_output()用于从模型获取结构化输出的接口,这是非常相关的。
虽然确切的实现因模型提供者而异,但对于支持它的大多数模型来说with_structured_output 是建立在工具调用之上的
在底层,with_structured_output 使用 bind_tools将给定的结构化输出模式传递给模型。

那么什么时候应该使用with_structured_output绑定工具和直接读取工具调用呢?

with_structured_output始终返回您指定的架构中的结构化输出。
当您想强制 LLM 输出与特定架构匹配的信息时,这很有用。这对于信息提取任务很有用。

bind_tools更通用,可以选择特定工具 - 或没有工具,或多个工具!当您希望 LLM 在如何响应方面具有更大的灵活性时,这非常有用 - 例如,在代理应用程序中,您需要选择要调用的工具,但也需要响应用户。


四、结论

我们预计,将本机工具调用功能引入 LLM 的趋势未来将持续下去。
我们希望标准化的工具调用接口能够帮助LangChain用户节省时间和精力,让他们更轻松地在不同的LLM提供商之间切换。

请记住更新您langchain_core和合作伙伴的软件包版本以利用新界面!

我们很乐意听到您的任何反馈!


2024-05-22(三)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汽车液态锂电池过充时,有怎样的表现,或者对电池有怎样的危害?

标签: 汽车液态锂电池过充的表现与危害; 电池过充; 汽车液态锂电池过充的表现与危害 液态锂电池在过充状态下,会出现一系列不良表现,并且对电池本身以及使用安全造成严重危害。以下是详细的分析: 1. 过充的表现 电压升高:在过充过程中,电池电压会超过其设计的最大电…

【MySQL精通之路】MySQL-环境变量

本节列出了MySQL直接或间接使用的环境变量。 其中大部分也可以在本手册的其他地方找到。 命令行上的选项优先于选项文件和环境变量中指定的值,选项文件中的值优先于环境变量中的值。 在许多情况下,最好使用配置文件而不是环境变量来修改MySQL的行为。…

虚拟机使用的是此版本 VMware Workstation 不支持的硬件版本。 模块“Upgrade”启动失败。 未能启动虚拟机。

问题: 虚拟机使用的是此版本 VMware Workstation 不支持的硬件版本。 模块“Upgrade”启动失败。 未能启动虚拟机。 分析: 该虚拟机环境之前使用的VMware版本与你所使用的VMware版本不一致。大概率你使用的是刚从别人电脑里拷过来的虚拟机环境。 解决&…

开发需要知道的敏捷开发理念

敏捷宣言和原则 敏捷软件开发宣言 敏捷软件开发宣言(Agile Manifesto)是敏捷开发方法的核心指导原则,由17位软件开发专家在2001年共同起草。该宣言强调了在软件开发过程中对某些价值观的优先级: 个体和互动高于流程和工具&#…

游戏后台开发技术全面解析

在这个数字时代,游戏产业已经成为全球最受欢迎的娱乐方式之一。从简单的手机游戏到复杂的大型多人在线角色扮演游戏(MMORPG),游戏的世界正变得越来越丰富和多样化。而这一切的背后,都离不开强大的游戏后台技术支持。在…

项目日记(3) boost搜索引擎

目录 1. 准备工作 2. 搜索初始化 3. 搜索部分 4. 对content部分处理 5. 服务器编写 前言: 上次在项目日记(2)写了index索引, 这次就可以进行search搜索了. 不多说快看. 先点个一键三联. 蟹蟹!!! 1. 准备工作 后面需要倒排索引的结构体, 先准备好. words是后面一个文档里面…

三丰云云服务器测评

三丰云是一家知名的云计算服务提供商,提供免费虚拟主机和免费云服务器等多种云计算服务。这些服务深受广大用户的喜爱,因为它们可以帮助用户轻松地搭建网站、应用程序等,同时无需购买昂贵的硬件设备。 对于初学者来说,使用三丰云…

Java重写

方法重写的意义 在java中,子类可以继承父类中的方法,而不需要重新编写相同的方法,但是有时子类并不想原封不动的继承父类方法,需要做一定的修改,这时候就需要使用方法重写 方法重写的定义 在继承的前提下 子类可以根据…

UI面试手册

UI面试手册 薪资:6~9k 高级:8~15k 岗位职责: 负责公司品牌形象及产品相关海报、宣传画等创意设计工作;负责公司日常宣传、营销广告、策划设计制作、产品设计和包装设计等工作;配合国内外广告投放物料设计,按进度要求…

Python使用连接池操作MySQL

测试环境说明:Python版本是 3.8.10 ,DBUtils版本是3.1.0 ,pymysql版本是1.0.3 首先安装指定版本的连接池库DBUtils 、还有pymysql pip install DBUtils3.1.0 pip install pymysql1.0.3创建文件 sqlConfig.py # sqlConfig.pyimport pymysql…

Math类

类 Math 包含执行基本数值运算的方法,例如基本指数、对数、平方根和三角函数。下面是我写代码时用到的一些字段和方法,归纳如下。 字段 修饰符和类型 Field描述static final double Edouble 值比任何其他值都更接近e, 自然对数的底…

YOLOv10论文解读:实时端到端的目标检测模型

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

618购物节快递量激增,EasyCVR视频智能分析助力快递网点智能升级

随着网络618购物节的到来,物流仓储与快递行业也迎来业务量暴增的情况。驿站网点和快递门店作为物流体系的重要组成部分,其安全性和运营效率日益受到关注。为了提升这些场所的安全防范能力和服务水平,实施视频智能监控方案显得尤为重要。 一、…

蓝桥杯嵌入式国赛笔记(2):拓展板按键程序设计

目录 1、前言 2、电路原理 3、代码编写 3.1 读取Btn电压 3.2 检索按键 3.3 main文件编写 3.3.1 进行变量定义 3.3.2 AD_Key函数 3.3.3 LCD函数 3.3.4 main函数 3.3.5 完整代码 4、测试 5、总结 1、前言 本文进行拓展板按键程序设计,拓展板的按键是通…

人生苦短,我学python之数据类型(下)

个人主页:星纭-CSDN博客 系列文章专栏:Python 踏上取经路,比抵达灵山更重要!一起努力一起进步! 目录 一.集合 1.1子集与超集 1.2交集,并集,补集,差集 1.intersection(英文&a…

webman使用summernote富文本编辑器

前言 Summernote富文本编辑器功能强大,可以直接从word直接复制内容过来而不破坏原有的文档格式,非常适合做商品详情等内容的编辑工具。本文将展示如何在php高性能框架webman中使用summernote编辑器。 下载 去Bootstrap 中文网、Summernote、jQuery官网…

【设计模式】JAVA Design Patterns——Converter(转换器模式)

🔍目的 转换器模式的目的是提供相应类型之间双向转换的通用方法,允许进行干净的实现,而类型之间无需相互了解。此外,Converter模式引入了双向集合映射,从而将样板代码减少到最少 🔍解释 真实世界例子 在真实…

低代码开发:拖拽式可视化构建工业物联网系统

什么是低代码? 低代码(Low Code)是一种可视化的软件开发方法,通过最少的手动编码可以更快地交付应用程序。低代码平台的图形用户界面和拖放功能可自动执行开发过程的各个方面,从而消除对传统计算机编程方法的依赖。 什么是低代码平台&#…

Pandas 创建层次化索引

1.创建多层次索引 1.1 隐式构造 最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组 # 导入pandasimport numpy as npimport pandas as pd​data np.random.randint(0,100,size(6,6))​# 行索引index [ ["1班","1班","1班&qu…

如何合理设置Java线程池大小

如何合理设置Java线程池大小:依据任务类型定制策略 Java线程池的合理配置直接关系到系统性能和资源利用率。根据任务性质的不同,合理的线程池大小设置策略也有所区别,主要包括CPU密集型、IO密集型及混合型任务。 1. CPU密集型任务 特点&am…