Function Calling入門|LLMに"手足"を与える技術の全体像
LLMが外部APIを呼び出して実際にアクションを起こす「Function Calling」の仕組みと設計パターン、プロンプトチューニングの勘どころを実例付きで解説します。
Function Callingとは何か
ChatGPTやGeminiに「明日の天気を教えて」と聞くと、もっともらしい回答が返ってきます。しかし、それはあくまで 学習データに基づく「推測」 であり、リアルタイムの天気情報を取得しているわけではありません。
ではどうすれば、LLMに実際のデータを取得させたり、外部システムを操作させたりできるのか? その答えが Function Calling です。
Function Callingとは、LLMがユーザーの意図を解釈し、あらかじめ定義された関数を呼び出すための引数(構造化データ)を生成する仕組みです。
通常のLLMは「テキストを生成する」ものですが、Function Callingを使うと「JSONを生成する」モードに切り替わります。このJSONが、外部の関数やAPIを呼び出す橋渡しになります。
つまり、LLMに「手足」を与える技術です。チャットだけだった存在が、メールを送る、データベースを検索する、リマインドを設定するといったアクションを起こせるようになります。
動作の流れを理解する
Function Callingは、以下のステップで動きます。
① ユーザー: 「明日9時に進捗確認のリマインドして」
↓
② アプリ → LLM: ユーザーの発言 + ツール定義(使える関数の一覧)を送信
↓
③ LLM → アプリ: 「set_reminder を呼んでください」+ 引数JSON
{ "time": "2026-03-13T09:00:00", "message": "進捗確認" }
↓
④ アプリ: 実際に set_reminder 関数を実行
↓
⑤ アプリ → LLM: 関数の実行結果を返す
↓
⑥ LLM → ユーザー: 「明日9時にリマインドをセットしました!」
重要なのは、LLM自身が関数を実行するわけではないという点です。LLMの役割は「どの関数を、どんな引数で呼ぶべきか」を判断すること。実行はあくまでアプリケーション側が行います。
この設計のおかげで、セキュリティの制御もアプリ側で担保できます。
主要サービスの対応状況
2026年現在、主要なLLM APIはいずれもFunction Callingに対応しています。
| サービス | 機能名 | 特徴 |
|---|---|---|
| Gemini API | Function Calling | Google AI Studioの無料枠で試せる。GASとの親和性が高い |
| OpenAI API | Function Calling / Tools | 最も早くから提供。エコシステムが充実 |
| Claude API | Tool Use | XMLベースの定義も可能。精度に定評あり |
概念はどのサービスも同じです。「ツール定義をJSONで渡し、LLMが呼び出し判断をする」という基本構造は共通しています。API仕様の細かな違いはあるものの、一つのサービスで理解すれば他にも応用が効きます。
本記事では、私が実際に使った Gemini API を中心に解説します。
設計パターン
Function Callingの使い方は、大きく3つのパターンに分けられます。
パターン1: 単一ツール呼び出し
最もシンプルな形です。ツールを一つだけ定義し、ユーザーの発言に応じてそのツールを呼ぶかどうかをLLMが判断します。
const tools = [{
function_declarations: [{
name: "get_weather",
description: "指定された都市の現在の天気を取得します",
parameters: {
type: "OBJECT",
properties: {
city: { type: "STRING", description: "都市名(例: 東京, 大阪)" }
},
required: ["city"]
}
}]
}];「東京の天気は?」→ ツール呼び出し。「元気?」→ 通常のテキスト応答。この振り分けをLLMが自動で行います。
パターン2: 複数ツールの切り替え
実用的なアプリでは、複数のツールを定義することが多くなります。
const tools = [{
function_declarations: [
{
name: "search_database",
description: "社内データベースから情報を検索します",
parameters: { /* ... */ }
},
{
name: "send_email",
description: "指定された宛先にメールを送信します",
parameters: { /* ... */ }
},
{
name: "create_ticket",
description: "タスク管理ツールにチケットを作成します",
parameters: { /* ... */ }
}
]
}];「先月の売上データを調べて」→ search_database、「田中さんに報告メール送って」→ send_email。LLMが文脈からどのツールを使うべきかを判断します。
ここで重要になるのが、各ツールのdescriptionの書き分けです。曖昧だとLLMが誤ったツールを選択します。これについては次のセクションで詳しく触れます。
パターン3: ツールチェーン
一つのツールの実行結果を踏まえて、次のツールを呼び出すパターンです。
ユーザー: 「先月の売上が目標を下回った部署にアラートメールを送って」
→ ① search_database で売上データを取得
→ ② 結果を見てLLMが判断
→ ③ send_email で該当部署にメール送信
ここまで来ると、LLMは単なるチャットボットではなくエージェントと呼べる存在になります。
チューニングの肝|プロンプト設計
Function Callingで最も時間を使うのは、コードの実装ではなくプロンプトのチューニングです。
ツール定義のdescriptionが精度を左右する
LLMはdescriptionを読んで「このツールを使うべきか」を判断します。ここが雑だと、意図しないツールが呼ばれたり、本来呼ぶべき場面でスルーされたりします。
悪い例:
description: "データを取得します"
良い例:
description: "社内の売上管理データベースから、指定された期間・部署の売上実績を検索して返します。日付はYYYY-MM-DD形式で指定してください。"
ポイントは3つです。
- 何のデータかを具体的に書く
- どういう条件で使うかを明示する
- パラメータの形式を例とともに示す
禁止事項のプロンプトが不可欠
実際に運用してみて気づいたのが、「やってはいけないこと」を明示的に伝える必要があるという点です。
開発中に遭遇したケースとして、LLMが実際には関数を呼び出していないのに、あたかも呼び出して結果を得たかのような応答を生成することがありました。ユーザーから見ると正常に動いているように見えるため、発見が遅れると厄介なバグになります。
これを防ぐには、システムプロンプトに禁止事項を明記します。
あなたはツールを使って情報を取得できます。
ただし、以下のルールを必ず守ってください。
- ツールを実行せずに、推測で結果を返さないでください
- 情報が不足している場合は、ユーザーに確認してください
- ツールの実行結果のみに基づいて回答してください
「何をすべきか」の定義と同じくらい、「何をしてはいけないか」の定義が重要です。この両面からプロンプトを設計することで、Function Callingの信頼性は大きく向上します。
まとめ
Function Callingは、LLMを「賢いチャット相手」から「実際に仕事をこなすエージェント」に変える技術です。
押さえるべきポイントを振り返ります。
- 仕組み: LLMが関数を実行するのではなく、「何を呼ぶか」を判断する。実行はアプリ側
- 設計パターン: 単一ツール → 複数切り替え → チェーンと段階的に複雑さが増す
- チューニング: ツール定義の
descriptionと禁止事項プロンプトの両面が肝
概念自体はどのLLMサービスでも共通なので、一度理解すれば応用が広がります。まずは一つのツールを定義して動かすところから始めてみてください。