工具调用
概述
许多AI应用直接与人类交互。在这些情况下,模型以自然语言回应是合适的。 但是,如果我们希望模型也直接与系统(如数据库或API)交互,该怎么办呢? 这些系统通常有特定的输入模式;例如,API经常有必需的负载结构。 这种需求促使了工具调用的概念。你可以使用工具调用来请求模型响应,以匹配特定的模式。
你有时会听到术语function calling
。我们与tool calling
互换使用这个术语。
关键概念
(1) 工具创建: 使用 @tool 装饰器创建一个 工具。工具是函数与其模式之间的关联。 (2) 工具绑定: 工具需要连接到支持工具调用的模型。这使得模型能够识别工具及其所需的输入模式。 (3) 工具调用: 在适当的时候,模型可以决定调用一个工具,并确保其响应符合工具的输入模式。 (4) 工具执行: 可以使用模型提供的参数执行工具。
推荐用法
这段伪代码展示了使用工具调用的推荐工作流程。
创建的工具作为列表传递给.bind_tools()
方法。
可以像往常一样调用此模型。如果进行了工具调用,模型的响应将包含工具调用的参数。
工具调用的参数可以直接传递给工具。
# Tool creation
tools = [my_tool]
# Tool binding
model_with_tools = model.bind_tools(tools)
# Tool calling
response = model_with_tools.invoke(user_input)
工具创建
推荐创建工具的方法是使用@tool
装饰器。
from langchain_core.tools import tool
@tool
def multiply(a: int, b: int) -> int:
"""Multiply a and b."""
return a * b
工具绑定
请参阅我们的模型集成页面,了解支持工具调用的提供商列表。
理解的核心概念是,LangChain 提供了一个标准化的接口,用于将工具连接到模型。
.bind_tools()
方法可用于指定模型可以调用哪些工具。
model_with_tools = model.bind_tools(tools_list)
作为一个具体的例子,我们以函数multiply
为例,并将其绑定为支持工具调用的模型的工具。
def multiply(a: int, b: int) -> int:
"""Multiply a and b.
Args:
a: first int
b: second int
"""
return a * b
llm_with_tools = tool_calling_model.bind_tools([multiply])
工具调用
工具调用的一个关键原则是,模型根据输入的相关性决定何时使用工具。模型并不总是需要调用工具。 例如,给定一个不相关的输入,模型不会调用工具:
result = llm_with_tools.invoke("Hello world!")
结果将是一个包含模型自然语言响应的AIMessage
(例如,“你好!”)。
然而,如果我们传递一个与工具相关的输入,模型应该选择调用它:
result = llm_with_tools.invoke("What is 2 multiplied by 3?")
和之前一样,输出 result
将是一个 AIMessage
。
但是,如果调用了工具,result
将具有一个 tool_calls
属性。
该属性包括执行工具所需的一切,包括工具名称和输入参数:
result.tool_calls
{'name': 'multiply', 'args': {'a': 2, 'b': 3}, 'id': 'xxx', 'type': 'tool_call'}
有关使用的更多详细信息,请参阅我们的操作指南!
工具执行
Tools 实现了 Runnable 接口,这意味着它们可以直接被调用(例如,tool.invoke(args)
)。
LangGraph 提供了预构建的组件(例如,ToolNode
),这些组件通常会代表用户调用工具。
- 查看我们的工具调用指南。
- 参见LangGraph文档中关于使用ToolNode的部分。
最佳实践
在设计工具供模型使用时,重要的是要记住以下几点:
- 具有明确工具调用API的模型在工具调用方面会比未经微调的模型表现得更好。
- 如果工具的名称和描述选择得当,模型的表现会更好。
- 简单、范围狭窄的工具比复杂工具更容易被模型使用。
- 要求模型从大量工具列表中进行选择对模型来说是一个挑战。