Function Calling
Function Calling ・ ふぁんくしょんこーりんぐ
LLMが構造化された形式で外部関数の呼び出しを指示する仕組み。
概要
Function Calling(ツール呼び出し、Tool Useとも)は、LLMに「呼び出せる関数の一覧」をあらかじめ教えておき、モデルが必要と判断したときに「この関数を、この引数で呼んでほしい」という指示を構造化されたJSONで出力させる仕組みです。天気APIの呼び出し、データベース検索、メール送信など、モデル単体ではできない処理を外部の関数に委ね、その結果を会話に取り込めるようになります。
最大の誤解ポイントを先に押さえておくと、名前に反して「モデルが関数を実行する」わけではありません。モデルが出力するのはあくまで「呼び出しの依頼書」で、実際に関数を実行するのは開発者側のアプリケーションです。モデルは依頼書を書き、アプリが実行し、結果をモデルに返す — この役割分担が仕組みの核心であり、LLMを外部の世界と接続するすべての応用(AIエージェントなど)の土台になっています。
なぜ生まれたか
LLMは訓練データに含まれない情報 — 今日の天気、社内データベースの中身、最新のニュース — を知らず、尋ねられるともっともらしい誤答を作ってしまうハルシネーションの問題を抱えていました。外部のAPIに聞けば正確に分かることを、モデルの記憶だけで答えさせるのは筋が悪い。そこで「モデルに直接答えさせず、外部の関数を呼ぶよう出力させる」アイデアが生まれましたが、初期はプロンプトで「この形式で出力して」と頼み込む方法しかなく、モデルは平気で形式を崩し、出力の解析が失敗する不安定さと隣り合わせでした。
これを解決したのが、2023年にOpenAIが導入し各社が追随したFunction Callingです。関数の宣言をAPIの正式なパラメータとして受け取り、呼び出し指示を決まったスキーマの構造化データとして返すことをモデルの訓練とAPI仕様の両面で保証したことで、「LLMの出力をプログラムで確実に処理する」ことが初めて実用的な信頼性で可能になりました。自由なテキストと厳密なプログラムの世界を繋ぐ変換器が標準装備された、と言えます。
詳細
往復のフローを順に追う
Function Callingは「宣言→指示→実行→結果返却→最終回答」という往復で動きます。全体像を図で押さえましょう。
まず(1)アプリは、ユーザーの質問と一緒に「使える関数の一覧」をLLMに渡します。各関数は名前・何をするかの説明・引数の型を、JSON Schemaという形式で宣言します。(2)モデルは質問を読み、手持ちの知識で答えるか関数を使うかを判断します。関数が必要なら、通常のテキストの代わりに「関数名と引数」の構造化データを返します。(3)アプリはその指示を受け取り、対応する実処理 — 外部APIの呼び出しやデータベース検索 — を自分で実行します。(4)実行結果を「関数の返り値」として会話履歴に追加し、もう一度モデルに送ると、(5)モデルは結果を踏まえた自然な回答文を生成します。1回のやり取りに最低2回のモデル呼び出しが必要になる点も、コストとレイテンシを考えるうえで重要です。
スキーマ設計がすべてを決める
モデルが関数を適切に選び、正しい引数を組み立てられるかは、宣言したスキーマの質にほぼ依存します。関数の説明文は「いつ使うべきか・いつ使うべきでないか」まで書き、引数名は自明に、選択肢は列挙型で縛る — スキーマは人間向けのAPIドキュメントであると同時に、モデルへの指示文でもあるのです。この意味で、スキーマ設計はプロンプトエンジニアリングの一分野と言えます。関数の数が増えすぎると選択精度が落ち、定義自体がコンテキストウィンドウを圧迫するため、タスクに必要な関数だけを渡すのが定石です。
構造化出力という副産物
Function Callingの「決まったスキーマに従うJSONを確実に出力させる」能力は、関数を呼ばない場面でも重宝します。たとえば請求書のテキストから金額・日付・宛先を抽出したいとき、抽出結果を受け取るダミーの関数を宣言すれば、モデルの出力を必ずパース可能な構造化データとして得られます。この用途は現在では「構造化出力(Structured Outputs)」として独立した機能に発展し、出力がスキーマに厳密に一致することを文法レベルで強制できるAPIも各社が提供しています。自由記述のテキストから型のあるデータへの変換は、LLMを既存システムに組み込む際の最頻出パターンです。
実務での落とし穴
モデルの指示はあくまで「確率的に生成された依頼書」であり、無条件に信頼してはいけません。存在しない関数名や不正な引数を返すことがあるため、実行前の検証(バリデーション)は必須です。また、モデルに渡す関数は「ユーザーの発話ひとつで実行されうる操作」だと考え、削除や送金のような取り返しのつかない処理は直接関数にせず、確認ステップを挟む設計にします。外部APIは失敗するものなので、エラーをモデルに返して言い直させるか、リトライするかの方針も決めておく必要があります。同じ指示が重複実行されても安全なように冪等性を意識しておくと、エージェント的な繰り返し実行にも耐える設計になります。なお、この関数宣言と呼び出しの形式はモデル提供者ごとに微妙に異なっており、その差を吸収して接続を標準化する試みが MCP です。
