ツール呼び出し(関数呼び出し)は、LLM に呼び出し元のアプリケーションにリクエストを返す機能を提供する構造化された方法です。モデルで使用できるようにするツールを定義すると、モデルは、指定したプロンプトを実行するために必要に応じてアプリにツール リクエストを送信します。
ツール呼び出しのユースケースは、一般的に次のテーマに分類されます。
LLM に、トレーニングに使用しなかった情報へのアクセス権を付与する
- 株価や現在の天気など、頻繁に変更される情報。
- アプリのドメインに固有の情報(商品情報やユーザー プロフィールなど)。
検索拡張生成(RAG)との重複に注意してください。これは、LLM が事実情報を生成に統合できるようにする方法でもあります。RAG はより負荷の高いソリューションであり、大量の情報がある場合や、プロンプトに最も関連性の高い情報があいまいな場合に最適です。一方、LLM に必要な情報を取得するのが単純な関数呼び出しやデータベース ルックアップである場合は、ツールの呼び出しの方が適しています。
LLM ワークフローに一定の決定論を導入する
- LLM が確実に完了できない計算を実行する。
- アプリの利用規約に関する質問に回答する場合など、特定の状況下で LLM に文字通りのテキストを生成させる。
LLM によって開始されたときにアクションを実行する
- LLM を活用したスマートホーム アシスタントで照明をオンまたはオフにする
- LLM を搭載したレストラン エージェントでのテーブル予約
始める前に
このページのコードサンプルを実行する場合は、まずスタートガイドの手順を完了してください。すべての例では、Genkit の依存関係がインストールされたプロジェクトがすでに設定されていることを前提としています。
このページでは、Genkit モデルの抽象化の高度な機能の 1 つについて説明します。詳しく説明する前に、AI モデルによるコンテンツの生成のページの内容を理解しておく必要があります。また、入力スキーマと出力スキーマを定義する Genkit のシステムについても理解しておく必要があります。これは、フローのページで説明しています。
ツール呼び出しの概要
LLM との一般的なツール呼び出しのやり取りは、大まかに次のようになります。
- 呼び出し元のアプリケーションは、リクエストで LLM にプロンプトを送信し、LLM がレスポンスの生成に使用できるツールのリストをプロンプトに含めます。
- LLM は、完全なレスポンスを生成するか、特定の形式でツール呼び出しリクエストを生成します。
- 呼び出し元が完全なレスポンスを受信すると、リクエストは処理され、インタラクションは終了します。呼び出し元がツール呼び出しを受信した場合は、適切なロジックを実行し、元のプロンプトまたはそのバリエーションとツール呼び出しの結果を含む新しいリクエストを LLM に送信します。
- LLM は、ステップ 2 と同様に新しいプロンプトを処理します。
そのためには、いくつかの要件を満たす必要があります。
- プロンプトの完了に必要なときにツール リクエストを行うようにモデルをトレーニングする必要があります。Gemini や Claude など、ウェブ API で提供される大規模なモデルのほとんどはこれを実行できますが、小規模でより特殊化されたモデルではできないことがよくあります。ツールをサポートしていないモデルにツールを指定しようとすると、Genkit はエラーをスローします。
- 呼び出し元のアプリケーションは、モデルが想定する形式でツール定義をモデルに提供する必要があります。
- 呼び出し元のアプリケーションは、アプリケーションが想定する形式でツール呼び出しリクエストを生成するようにモデルに指示する必要があります。
Genkit を使用したツールの呼び出し
Genkit は、サポートするモデルでツールを呼び出すための単一のインターフェースを提供します。各モデル プラグインは、上記の最後の 2 つの条件が満たされていることを確認します。また、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
の 4 つのパラメータがすべて必要です。ツール定義を作成する際は、これらのパラメータの文言と記述性に特に注意してください。これらのパラメータは、LLM が利用可能なツールを効果的に使用するために不可欠です。
ツールの使用
定義済みのツールをプロンプトに含めてコンテンツを生成します。
生成
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;
}