工具呼叫 (也稱為函式呼叫) 是一種結構化方式,可讓大型語言模型向呼叫它的應用程式提出要求。您可以定義要提供給模型的工具,模型會視需要向應用程式提出工具要求,以便執行您提供的提示。
工具呼叫的用途通常可歸納為幾個主題:
讓大型語言模型存取未用於訓練的資訊
- 經常變更的資訊,例如股票價格或目前天氣。
- 應用程式網域專屬資訊,例如產品資訊或使用者個人資料。
請注意,這與檢索增強生成 (RAG) 重疊,後者也是讓 LLM 將事實資訊整合至生成內容的一種方式。RAG 是較為複雜的解決方案,最適合用於大量資訊,或是與提示最相關的資訊模糊不清的情況。另一方面,如果擷取 LLM 所需資訊的操作是簡單的函式呼叫或資料庫查詢,則呼叫工具會更適合。
在 LLM 工作流程中引入一定程度的確定性
- 執行 LLM 無法可靠完成的計算。
- 在特定情況下強制 LLM 產生逐字文字,例如在回覆有關應用程式服務條款的問題時。
在 LLM 啟動時執行動作
- 透過 LLM 技術輔助的家用助理開啟和關閉燈具
- 在 LLM 輔助的餐廳服務代理中預訂座位
事前準備
如果您想執行本頁的程式碼範例,請先完成「開始使用」指南中的步驟。所有範例都假設您已設定安裝 Genkit 依附元件的專案。
本頁將說明 Genkit 模型抽象化的進階功能之一,因此在深入探討之前,請先熟悉「使用 AI 模型產生內容」頁面中的內容。您也應熟悉 Genkit 的系統,以便定義輸入和輸出結構定義,相關資訊請參閱「流程」頁面。
工具呼叫總覽
大致來說,以下是工具呼叫與大型語言模型互動的典型情況:
- 呼叫應用程式會向 LLM 提示要求,並在提示中加入 LLM 可用於產生回應的工具清單。
- 大型語言模型會生成完整回應,或以特定格式生成工具呼叫要求。
- 如果呼叫端收到完整回應,系統就會執行要求,並結束互動;但如果呼叫端收到工具呼叫,則會執行適當的邏輯,並向 LLM 傳送新要求,其中包含原始提示或某些變化版本,以及工具呼叫的結果。
- LLM 會處理新的提示,如步驟 2 所述。
如要使用這項功能,您必須符合下列幾項條件:
- 模型必須經過訓練,才能在需要完成提示時提出工具要求。大多數透過網路 API 提供的大型模型 (例如 Gemini 和 Claude) 都能執行這項操作,但較小且較專門的模型通常無法執行。如果您嘗試為不支援的模型提供工具,Genkit 就會擲回錯誤。
- 呼叫端應用程式必須以模型預期的格式,向模型提供工具定義。
- 呼叫應用程式必須提示模型,以應用程式預期的格式產生工具呼叫要求。
使用 Genkit 呼叫工具
Genkit 提供單一介面,可讓工具呼叫支援的模型。每個模型外掛程式都會確保符合上述最後兩項條件,而 Genkit 例項的 generate()
函式會自動執行先前所述的工具呼叫迴圈。
模型支援
工具呼叫支援取決於模型、模型 API 和 Genkit 外掛程式。請參閱相關說明文件,判斷是否支援工具呼叫。此外:
- 如果您嘗試為不支援的模型提供工具,Genkit 就會擲回錯誤。
- 如果外掛程式匯出模型參照,
info.supports.tools
屬性會指出是否支援工具呼叫。
定義工具
使用 Genkit 例項的 defineTool()
函式編寫工具定義:
import { genkit, z } from 'genkit';
import { googleAI, gemini15Flash } from '@genkit-ai/google-ai';
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});
const getWeather = ai.defineTool(
{
name: 'getWeather',
description: 'Gets the current weather in a given location',
inputSchema: z.object({
location: z.string().describe('The location to get the current weather for')
}),
outputSchema: z.string(),
},
async (input) => {
// Here, we would typically make an API call or database query. For this
// example, we just return a fixed value.
return 'The current weather in ${input.location} is 63°F and sunny.';
}
);
這裡的語法與 defineFlow()
語法相似,但必須使用四個 name
、description
、inputSchema
和 outputSchema
參數。編寫工具定義時,請特別注意這些參數的措辭和描述性,因為這些參數對於大型語言模型有效運用可用的工具至關重要。
使用工具
在提示中加入定義的工具,以便產生內容。
產生
const response = await ai.generate({
prompt: 'What is the weather in Baltimore?',
tools: [getWeather],
});
definePrompt
const weatherPrompt = ai.definePrompt(
{
name: 'weatherPrompt',
tools: [getWeather],
},
'What is the weather in {{location}}?'
);
const response = await weatherPrompt({ location: 'Baltimore' });
提示檔案
---
system: "Answer questions using the tools you have."
tools: [getWeather]
input:
schema:
location: string
---
What is the weather in {{location}}?
接著,您可以在程式碼中執行提示,如下所示:
// assuming prompt file is named weatherPrompt.prompt
const weatherPrompt = ai.prompt('weatherPrompt');
const response = await weatherPrompt({ location: 'Baltimore' });
即時通訊
const chat = ai.chat({
system: 'Answer questions using the tools you have.',
tools: [getWeather],
});
const response = await chat.send('What is the weather in Baltimore?');
// Or, specify tools that are message-specific
const response = await chat.send({
prompt: 'What is the weather in Baltimore?',
tools: [getWeather],
});
如果 LLM 需要使用 getWeather
工具來回答提示,Genkit 會自動處理工具呼叫。
明確處理工具呼叫
根據預設,Genkit 會重複呼叫 LLM,直到每個工具呼叫都已解析為止。如要進一步控管這個工具的呼叫迴圈 (例如套用更複雜的邏輯),請將 returnToolRequests
參數設為 true
。您現在有責任確保所有工具要求都已滿足:
const getWeather = ai.defineTool(
{
// ... tool definition ...
},
async ({ location }) => {
// ... tool implementation ...
},
);
const generateOptions: GenerateOptions = {
prompt: "What's the weather like in Baltimore?",
tools: [getWeather],
returnToolRequests: true,
};
let llmResponse;
while (true) {
llmResponse = await ai.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 getWeather(part.toolRequest.input),
},
};
default:
throw Error('Tool not found');
}
})
);
generateOptions.messages = llmResponse.messages;
generateOptions.prompt = toolResponses;
}