如何处理工具错误
预备知识
本指南假定您熟悉以下概念:
使用 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
Try/except 工具调用
更优雅地处理错误的最简单方法是尝试/捕获工具调用步骤,并在出错时返回有用的提示信息:
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 跟踪,我们可以看到第一个链调用按预期失败,而备用链调用成功。
下一步
现在你已经了解了一些处理工具调用错误的策略。接下来,你可以学习更多关于如何使用工具的内容:
你还可以查看一些更具体的工具调用用例:
- 从模型中获取结构化输出