跳至主要内容

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

先决条件

本指南假定您熟悉以下概念

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

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

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

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

支持的模型

工具调用并非普遍存在,但许多流行的 LLM 提供商都支持,包括 AnthropicCohereGoogleMistralOpenAI,甚至通过 Ollama 支持本地运行的模型。

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

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

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

将工具传递给聊天模型

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

注意

@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 响应中,则它们将附加到相应的 消息消息块 中,作为 工具调用 对象列表,位于.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 上.