工具调用(也称为函数调用)是一种结构化方式, LLM 能够向调用它的应用发回请求。您 定义要提供给模型的工具,然后模型 必要时向您的应用发出工具请求,以完成您提供的提示。
工具调用的用例通常分为以下几个主题:
让 LLM 能够访问未经训练的信息
- 经常变化的信息,如餐馆的每日菜单或 商店的商品目录状态
- 您的应用网域特有的信息,例如产品信息。
请注意与检索增强生成 (RAG) 的重叠部分,RAG 也 一种让 LLM 将事实信息整合到其世代中的方法。RAG 是 最适合您的工作负载 或与提示最相关的信息模糊不清。已开启 另一方面,如果检索 LLM 所需的信息是一个简单的函数, 调用或数据库查询,工具调用更合适。
在 LLM 工作流中引入一定程度的确定性
- 执行 LLM 无法可靠地自行完成的计算。
- 强制 LLM 在特定情况下生成逐字文本,例如 。
在 LLM 发起某项操作后
- 使用 LLM 赋能的家居助理来开灯和关灯
- 在由 LLM 提供支持的餐厅代理中预订桌位
准备工作
如果您要运行此页面上的代码示例,请先完成 使用入门指南。所有示例都假定您 已经设置了安装了 Genkit 依赖项的项目。
本页面介绍了 Genkit 模型抽象的一个高级功能, generate() 函数,因此在深入了解之前,您应该先熟悉 使用 AI 模型生成内容页面上的内容。您应该 也熟悉 Genkit 系统,用于定义输入和输出架构, 有关详情,请参阅流页面。
工具调用概览
概括来讲,这是工具调用与 LLM 之间的典型交互。 如下所示:
- 发起调用的应用向 LLM 发出一个请求提示,并且还会向 LLM 发出一个请求, 列出 LLM 可用于生成回答的工具列表。
- LLM 生成完整回答或生成工具调用 特定格式的请求
- 如果调用方收到完整的响应,则请求已实现,且 互动结束;但是,如果调用方收到工具调用,它会执行 然后向 LLM 发送包含以下内容的新请求: 生成提示, 工具调用。
- LLM 会按照第 2 步中的说明处理新提示。
要实现此功能,需要满足以下几项要求:
- 模型必须经过训练,才能在需要时发出工具请求,以完成 提示。通过 Web API 提供的大多数大型模型,例如 Gemini 和 Claude 可以做到这一点,但规模更小、更专业的模型通常无法做到。 如果您尝试为无法提供工具的模型提供工具,Genkit 会报错 提供支持。
- 调用应用必须在 所需的格式
- 调用应用必须提示模型生成工具调用 请求采用应用预期的格式。
使用 Genkit 进行工具调用
Genkit 会提供一个接口,以便使用支持它的模型调用工具。
每个模型插件都会确保满足上述条件中的后两个条件,
generate()
函数会自动执行工具调用循环
。
模型支持
对工具调用的支持取决于模型、模型 API 和 Genkit 插件。 请查阅相关文档,确定是否可能会 支持。此外:
- 如果您尝试为无法提供工具的模型提供工具,Genkit 会报错 提供支持。
- 如果插件导出模型引用,
info.supports.tools
属性 会指明它是否支持工具调用。
定义工具
使用 defineTool()
函数编写工具定义:
const specialToolInputSchema = z.object({ meal: z.enum(["breakfast", "lunch", "dinner"]) });
const specialTool = defineTool(
{
name: "specialTool",
description: "Retrieves today's special for the given meal",
inputSchema: specialToolInputSchema,
outputSchema: z.string(),
},
async ({ meal }): Promise<string> => {
// Retrieve up-to-date information and return it. Here, we just return a
// fixed value.
return "Baked beans on toast";
}
);
此处的语法与 defineFlow()
语法类似;然而,
name
、description
、inputSchema
和 outputSchema
参数
必填字段。
在撰写工具定义时,请特别注意措辞和
这些参数的描述性,因为它们对于 LLM 而言至关重要
从而有效利用提供的工具
在提示中加入工具
定义完工具后,请在
generate()
:
const llmResponse = await generate({
model: gemini15Flash,
prompt,
tools: [specialTool],
});
您可以提供多种工具:LLM 会根据需要调用工具 以完成提示。
显式处理工具调用
默认情况下,Genkit 会反复调用 LLM,直到完成每个工具调用
已解决。如果您希望更好地控制此工具调用循环,例如
应用更复杂的逻辑,请将 returnToolRequests
参数设置为 true
。
现在,您有责任确保所有工具请求都得到满足:
let generateOptions: GenerateOptions = {
model: gemini15Flash,
prompt,
tools: [specialTool],
returnToolRequests: true,
};
let llmResponse;
while (true) {
llmResponse = await generate(generateOptions);
const toolRequests = llmResponse.toolRequests();
if (toolRequests.length < 1) {
break;
}
const toolResponses: ToolResponsePart[] = await Promise.all(
toolRequests.map(async (part) => {
switch (part.toolRequest.name) {
case "specialTool":
return {
toolResponse: {
name: part.toolRequest.name,
ref: part.toolRequest.ref,
output: await specialTool(specialToolInputSchema.parse(part.toolRequest?.input)),
},
};
default:
throw Error('Tool not found');
}
}));
generateOptions.history = llmResponse.toHistory();
generateOptions.prompt = toolResponses;
}