如何处理工具错误
先决条件
本指南假设您熟悉以下概念
使用 LLM 调用工具并不完美。模型可能会尝试调用不存在的工具,或者无法返回与请求的模式匹配的参数。诸如保持模式简单、减少一次传递的工具数量以及拥有良好的名称和描述等策略可以帮助降低这种风险,但并非万无一失。
本指南介绍了一些将错误处理构建到链中的方法,以缓解这些故障模式。
链
假设我们有以下(虚拟)工具和工具调用链。我们将故意使工具变得复杂,以试图让模型出错。
import { z } from "zod";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
const llm = new ChatOpenAI({
model: "gpt-3.5-turbo-0125",
temperature: 0,
});
const complexTool = tool(
async (params) => {
return params.int_arg * params.float_arg;
},
{
name: "complex_tool",
description: "Do something complex with a complex tool.",
schema: z.object({
int_arg: z.number(),
float_arg: z.number(),
number_arg: z.object({}),
}),
}
);
const llmWithTools = llm.bindTools([complexTool]);
const chain = llmWithTools
.pipe((message) => message.tool_calls?.[0].args)
.pipe(complexTool);
我们可以看到,当我们尝试调用此链时,模型无法正确调用工具。
await chain.invoke("use complex tool. the args are 5, 2.1, potato");
Error: Received tool input did not match expected schema
尝试/异常工具调用
最简单的方法是尝试/异常工具调用步骤,并在发生错误时返回有用的消息。
const tryExceptToolWrapper = async (input, config) => {
try {
const result = await complexTool.invoke(input);
return result;
} catch (e) {
return `Calling tool with arguments:\n\n${JSON.stringify(
input
)}\n\nraised the following error:\n\n${e}`;
}
};
const chainWithTools = llmWithTools
.pipe((message) => message.tool_calls?.[0].args)
.pipe(tryExceptToolWrapper);
const res = await chainWithTools.invoke(
"use complex tool. the args are 5, 2.1, potato"
);
console.log(res);
Calling tool with arguments:
{"int_arg":5,"float_arg":2.1,"number_arg":"potato"}
raised the following error:
Error: Received tool input did not match expected schema
回退
我们还可以尝试在发生工具调用错误时回退到更好的模型。在这种情况下,我们将回退到一个使用gpt-4-1106-preview
而不是gpt-3.5-turbo
的相同链。
const badChain = llmWithTools
.pipe((message) => message.tool_calls?.[0].args)
.pipe(complexTool);
const betterModel = new ChatOpenAI({
model: "gpt-4-1106-preview",
temperature: 0,
}).bindTools([complexTool]);
const betterChain = betterModel
.pipe((message) => message.tool_calls?.[0].args)
.pipe(complexTool);
const chainWithFallback = badChain.withFallbacks([betterChain]);
await chainWithFallback.invoke("use complex tool. the args are 5, 2.1, potato");
10.5
查看此链运行的LangSmith 跟踪,我们可以看到第一个链调用如预期的那样失败,并且是回退成功。
下一步
现在您已经了解了一些处理工具调用错误的策略。接下来,您可以了解更多关于如何使用工具的信息
您还可以查看工具调用的一些更具体的用法
- 获取结构化输出从模型