跳至主要内容

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

先决条件

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

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

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

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

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

支持的模型

工具调用并非普遍适用,但许多流行的 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参数)。当这些情况下解析失败时,.invalid_tool_calls属性中将填充InvalidToolCall的实例。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上.