跳到主要内容

如何使用聊天模型调用工具

先决条件

工具调用 允许聊天模型通过“调用工具”来响应给定的提示。

请记住,虽然名称“工具调用”意味着模型正在直接执行某些操作,但这实际上并非如此!模型仅生成工具的参数,而实际运行工具(或不运行)取决于用户。

工具调用是一种通用技术,可从模型生成结构化输出,即使您不打算调用任何工具,也可以使用它。一个用例是从非结构化文本中提取信息

如果您想了解如何使用模型生成的工具调用来实际运行工具函数,请查看本指南

支持的模型

工具调用并非通用功能,但许多流行的 LLM 提供商都支持,包括 AnthropicCohereGoogleMistralOpenAI,甚至可以通过 Ollama 用于本地运行的模型。

您可以在此处找到支持工具调用的所有模型的列表

LangChain 实现了用于定义工具、将工具传递给 LLM 以及表示工具调用的标准接口。本指南将介绍如何将工具绑定到 LLM,然后调用 LLM 以生成这些参数。

LangChain 实现了用于定义工具、将工具传递给 LLM 以及表示工具调用的标准接口。本指南将向您展示如何使用它们。

将工具传递给聊天模型

支持工具调用功能的聊天模型实现了 .bindTools() 方法,该方法接收 LangChain 工具对象 的列表,并将它们以其预期的格式绑定到聊天模型。随后对聊天模型的调用将在其对 LLM 的调用中包含工具模式 (schema)。

注意

截至 @langchain/core 版本 0.2.9,所有具有工具调用功能的聊天模型现在都支持 OpenAI 格式的工具

让我们来看一个例子

选择您的聊天模型

安装依赖项

提示

请参阅 本节,了解有关安装集成包的通用说明.

yarn add @langchain/anthropic @langchain/core

添加环境变量

ANTHROPIC_API_KEY=your-api-key

实例化模型

import { ChatAnthropic } from "@langchain/anthropic";

const llm = new ChatAnthropic({
model: "claude-3-5-sonnet-20240620",
temperature: 0
});

我们可以使用 .bindTools() 方法来处理从 LangChain 工具到我们的模型提供商特定格式的转换,并将其绑定到模型(即,每次调用模型时都传递它)。许多模型实现了辅助方法,这些方法将负责格式化并将不同的类函数对象绑定到模型。让我们创建一个新的工具来实现 Zod 模式,然后将其绑定到模型

注意

tool 函数在 @langchain/core 版本 0.2.7 及更高版本中可用。

如果您使用的是旧版本的 core,则应实例化并使用 DynamicStructuredTool 代替。

import { tool } from "@langchain/core/tools";
import { z } from "zod";

/**
* Note that the descriptions here are crucial, as they will be passed along
* to the model along with the class name.
*/
const calculatorSchema = z.object({
operation: z
.enum(["add", "subtract", "multiply", "divide"])
.describe("The type of operation to execute."),
number1: z.number().describe("The first number to operate on."),
number2: z.number().describe("The second number to operate on."),
});

const calculatorTool = tool(
async ({ operation, number1, number2 }) => {
// Functions must return strings
if (operation === "add") {
return `${number1 + number2}`;
} else if (operation === "subtract") {
return `${number1 - number2}`;
} else if (operation === "multiply") {
return `${number1 * number2}`;
} else if (operation === "divide") {
return `${number1 / number2}`;
} else {
throw new Error("Invalid operation.");
}
},
{
name: "calculator",
description: "Can perform mathematical operations.",
schema: calculatorSchema,
}
);

const llmWithTools = llm.bindTools([calculatorTool]);

现在,让我们调用它!我们期望模型使用计算器来回答问题

const res = await llmWithTools.invoke("What is 3 * 12");

console.log(res);
AIMessage {
"id": "chatcmpl-9p1Ib4xfxV4yahv2ZWm1IRb1fRVD7",
"content": "",
"additional_kwargs": {
"tool_calls": [
{
"id": "call_CrZkMP0AvUrz7w9kim0splbl",
"type": "function",
"function": "[Object]"
}
]
},
"response_metadata": {
"tokenUsage": {
"completionTokens": 24,
"promptTokens": 93,
"totalTokens": 117
},
"finish_reason": "tool_calls",
"system_fingerprint": "fp_400f27fa1f"
},
"tool_calls": [
{
"name": "calculator",
"args": {
"operation": "multiply",
"number1": 3,
"number2": 12
},
"type": "tool_call",
"id": "call_CrZkMP0AvUrz7w9kim0splbl"
}
],
"invalid_tool_calls": [],
"usage_metadata": {
"input_tokens": 93,
"output_tokens": 24,
"total_tokens": 117
}
}

正如我们所见,我们的 LLM 生成了工具的参数!

注意:如果您发现模型没有为给定的提示调用所需的工具,您可以查看本指南,了解如何强制 LLM 调用工具,而不是让它自行决定。

提示

在此处查看上面 LangSmith 追踪

工具调用

如果 LLM 响应中包含工具调用,则它们将作为 messagemessage chunk 附加到相应的 tool call 对象列表中,位于 .tool_calls 属性中。

ToolCall 是一个类型化的字典,其中包含工具名称、参数值字典以及(可选的)标识符。没有工具调用的消息默认情况下此属性为空列表。

聊天模型可以一次调用多个工具。这是一个例子

const res = await llmWithTools.invoke("What is 3 * 12? Also, what is 11 + 49?");

res.tool_calls;
[
{
name: 'calculator',
args: { operation: 'multiply', number1: 3, number2: 12 },
type: 'tool_call',
id: 'call_01lvdk2COLV2hTjRUNAX8XWH'
},
{
name: 'calculator',
args: { operation: 'add', number1: 11, number2: 49 },
type: 'tool_call',
id: 'call_fB0vo8VC2HRojZcj120xIBxM'
}
]

.tool_calls 属性应包含有效的工具调用。请注意,有时模型提供商可能会输出格式错误的工具调用(例如,不是有效 JSON 的参数)。当这些情况下的解析失败时,InvalidToolCall 的实例将填充在 .invalid_tool_calls 属性中。InvalidToolCall 可以具有名称、字符串参数、标识符和错误消息。

绑定模型特定格式(高级)

提供商为格式化工具模式采用了不同的约定。例如,OpenAI 使用如下格式

  • type:工具的类型。在撰写本文时,这始终是“function”。
  • function:包含工具参数的对象。
  • function.name:要输出的模式的名称。
  • function.description:要输出的模式的高级描述。
  • function.parameters:您要提取的模式的嵌套详细信息,格式为 JSON 模式 对象。

如果需要,我们可以将此模型特定格式直接绑定到模型。这是一个例子

import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({ model: "gpt-4o" });

const modelWithTools = model.bind({
tools: [
{
type: "function",
function: {
name: "calculator",
description: "Can perform mathematical operations.",
parameters: {
type: "object",
properties: {
operation: {
type: "string",
description: "The type of operation to execute.",
enum: ["add", "subtract", "multiply", "divide"],
},
number1: { type: "number", description: "First integer" },
number2: { type: "number", description: "Second integer" },
},
required: ["number1", "number2"],
},
},
},
],
});

await modelWithTools.invoke(`Whats 119 times 8?`);
AIMessage {
"id": "chatcmpl-9p1IeP7mIp3jPn1wgsP92zxEfNo7k",
"content": "",
"additional_kwargs": {
"tool_calls": [
{
"id": "call_P5Xgyi0Y7IfisaUmyapZYT7d",
"type": "function",
"function": "[Object]"
}
]
},
"response_metadata": {
"tokenUsage": {
"completionTokens": 24,
"promptTokens": 85,
"totalTokens": 109
},
"finish_reason": "tool_calls",
"system_fingerprint": "fp_400f27fa1f"
},
"tool_calls": [
{
"name": "calculator",
"args": {
"operation": "multiply",
"number1": 119,
"number2": 8
},
"type": "tool_call",
"id": "call_P5Xgyi0Y7IfisaUmyapZYT7d"
}
],
"invalid_tool_calls": [],
"usage_metadata": {
"input_tokens": 85,
"output_tokens": 24,
"total_tokens": 109
}
}

这在功能上等同于上面的 bind_tools() 调用。

下一步

现在您已经学习了如何将工具模式绑定到聊天模型,并让模型调用该工具。

接下来,查看本指南,了解如何通过调用函数并将结果传递回模型来实际使用该工具

您还可以查看工具调用的一些更具体用法


此页面是否对您有帮助?


您也可以留下详细的反馈 在 GitHub 上.