ユーザーのメッセージを GPT API に渡すと、自然言語での回答の代わりに、どの関数をどの引数で呼び出すべきかを正確に示す構造化 JSON オブジェクトが返ってきます。これが関数呼び出しであり、LLM で構築できるアプリケーションの在り方を変えます。
多くの開発者は「関数呼び出し」と聞くと、モデルが代わりにコードを実行していると考えますが、そうではありません。
関数呼び出しを使う場合、LLM 自体は関数を実行しません。代わりに、適切な関数を特定し、必要なパラメータをすべて集め、それらを構造化 JSON 形式で提示します。
実際のロジックを実行する責任は、引き続きあなたのアプリケーション側にあります。モデルは、何をどの入力で実行すべきかをあなたに伝えているだけです。
この違いは見た目以上に重要で、統合のアーキテクチャからセキュリティの考え方に至るまで、あらゆるものに影響します。
関数呼び出しの正体 — よくある誤解
関数呼び出し(tool calling とも呼ばれます)は、OpenAI モデルが外部システムと連携し、学習データの外側にあるデータへアクセスするための強力で柔軟な手段を提供します。
名前がまず誤解の元です。モデルが何かを実行していると人は考えがちですが、実際には違います。
関数呼び出しには様々な名称や説明がありますが、要するに「関数呼び出しとは、LLM の構造化出力の一形態である」という一点に尽きます。LLM 自身が関数を呼ぶことはなく、あなたがプロンプトで提供した事前定義の関数群から、どれを使うべきかを提案するにすぎません。
2 つ目の誤解は、古い API サーフェスに関するものです。
functions と function_call パラメータは 2023-12-01-preview バージョンの API リリースに伴い非推奨になりました。functions の代わりは tools パラメータです。
もし古い functions パラメータを使ったチュートリアルに従っているなら、すでに非推奨の文法を使っていることになります。代わりに tools と tool_choice を使いましょう。
関数はツールの一種で、JSON スキーマで定義されます。関数定義によって、モデルはデータをあなたのアプリケーションへ渡し、あなたのコードがデータへアクセスしたり、モデルが提案したアクションを実行したりできるようになります。
このスキーマこそが、関数呼び出しを単なるプロンプティングより信頼できるものにする理由です。モデルが正しく整形して出力するのを期待するのではなく、API レベルで構造を強制できるからです。
OpenAI API における関数呼び出しの仕組み — ステップごとに解説
ツール呼び出しは、OpenAI API を介してあなたのアプリケーションとモデルがやり取りする多段の会話です。高レベルでは 5 つのステップがあります:モデルが呼び出せるツール群を添えてリクエストを送り…
以下では、それぞれのステップが実際にどう見えるかを示します。
Step 1: 関数スキーマを定義する。 各関数は、tools パラメータ内の JSON オブジェクトとして記述します。スキーマには関数名、モデルがいつその関数を呼ぶべきか判断するための自然言語での説明、そして JSON Schema に従う parameters ブロックを含めます。
description は、どの状況で関数を呼ぶのかを具体的に書くほど効果的です。ただし、関数説明はプロンプトの一部であり、トークンを消費する点に注意してください。
Step 2: リクエストを送る。 ユーザーのメッセージと tools の一覧を添えて Chat Completions API を呼び出します。モデルは両方を見ます。
Step 3: モデルが関数を呼ぶかどうかを決める。
関数呼び出しは、モデルがプロンプトを検討した結果、指示に従うには提示されたツールのいずれかを使う必要があると判断したときに発生する特別なタイプの応答です。例えば、「パリの天気は?」というプロンプトに対し、モデルは get_weather ツールを、場所引数にパリを指定して呼び出すよう提案する可能性があります。
Step 4: あなたのコードが関数を実行する。 モデルの応答をパースし、関数名と引数を抽出して、あなたの実行環境で実際のコードを動かします。API は構造化 JSON を返しただけで、何をするかはあなたが決めます。
Step 5: 結果を返す。
ツール定義、元のプロンプト、モデルのツールコール、ツールコールの出力をすべてモデルに送り返し、最終的にテキスト応答を受け取ります
— 例えば「今日のパリの天気は 25°C です」のように。
多くのチュートリアルが触れない重要な点が 1 つあります。
strict: true を関数定義で設定すると、Structured Outputs により、モデルがその関数呼び出しで生成する引数が、あなたが提供した JSON Schema と完全に一致することが保証されます。
strict を true にすることで、関数呼び出しはベストエフォートではなく、スキーマに確実に準拠するようになります。OpenAI は常に strict モードを有効にすることを推奨しています。
本当に、常に。そうしない理由はありません。
また、並列関数呼び出しについても知っておくべきことがあります。
ユーザーの問いに応じて、2023 年 11 月 6 日以降にリリースされた最新モデルを使う場合、モデルは並列関数呼び出しを行います。
つまり、「ロンドンと東京の天気は?」のような 1 回のリクエストで、逐次ではなく 2 つのツールコールを同時にトリガーできるということです。
関数呼び出しの実運用ユースケース
天気の例は至るところにありますが、それは扱いやすいからです。実運用のユースケースはもっと複雑で、むしろ面白いものです。
最新データを使うカスタマーサポートのパイプライン
関数呼び出しは多くの用途で有用です。例えば、AI アシスタントがユーザーから「最近の注文は?」と聞かれたとき、最新の顧客データを内部システムから取得してから回答を生成するようなケースです。
モデルは意図を把握し、コンテキストから顧客 ID を抽出し、あなたの CRM の内部 API を呼び出します。もろい正規表現も、コンマ 1 つで壊れるようなプロンプトテンプレートも不要です。
スケールする構造化データ抽出
生データのテキストを取得し、構造化データへ変換してデータベースに保存する抽出パイプラインも好適です。文書タイプごとにパースロジックを手書きで調整しなくても、数千の文書にわたり一貫したスキーマを得られます。
自然言語から API への変換
LLM を用いた抽出・タグ付け、自然言語から API コールや有効なデータベースクエリへ変換するアプリケーション、ナレッジベースと対話する会話型検索などは、いずれも関数呼び出しが提供する出力形式の保証によって恩恵を受けます。出力が下流のシステムを駆動する必要があるなら、変動性は許容できません。
複数ツールを使うエージェント的ワークフロー
開発者にとって、関数呼び出しは、ライブな株価や天気、最近のデータベースエントリといったリアルタイムデータへのアクセスを可能にし、学習カットオフを補完します。さらに、メール送信、CRM 更新、コードのデプロイなど、状態を変更するアクションの実行も可能にします。
単なるチャットボットとの決定的な違いは、モデルがテキストを生成するだけでなく、あなたのシステム横断で実際のオペレーションをオーケストレーションする点にあります。
ベストプラクティス — 開発者が陥りがちな落とし穴
このセクションは多くのチュートリアルが省略しがちなため、チームが午前 2 時に不可解な本番障害をデバッグする羽目になります。
説明が曖昧すぎる。 モデルは関数説明を使って、いつそれを呼ぶかを判断します。「ユーザーのリクエストを処理します」のように一般的だと、いつトリガーすべきかの信号になりません。トリガー条件と期待される入力形状を具体的に書いてください。説明は単なるラベルではなく契約だと考えましょう。
一度に公開する関数が多すぎる
関数の説明は、入力プロンプト内でかなりのトークンを消費します。
50 個以上のツール定義をシステムプロンプトへ読み込むと、2 つの問題が生じます。コストとレイテンシ(ツール定義が入力トークンを消費するため)、そして正確性の低下(選択肢が増えるほど、モデルが正しいものを選ぶ能力が下がるため)です。
そのユースケースに本当に必要な最小限の関数から始めましょう。
モデルがパラメータを幻覚しないと考えてしまう。 幻覚します。
モデルはパラメータを幻覚することがあります
— 特に、列挙で明確に境界づけられていないオプションのフィールドで顕著です。これこそ strict: true が重要な理由です。スキーマ外のフィールドをモデルが勝手に作る可能性を排除します。
マルチターンのループ処理を考慮していない。 多くの開発者はハッピーパス(ユーザー質問 → モデルが関数呼び出し → 終了)しか作りません。
モデルが、あなたの定義したスキーマに合わない関数呼び出しを生成したり、提供していない関数を呼ぼうとする場合があります。想定外の関数呼び出しが生成されるなら、システムメッセージに「提供された関数のみを使用してください」といった一文を含めてみてください。
エッジケースを前提に設計しましょう。
書き込み系操作で確認ステップを省略する。
コード実行、データベース更新、通知送信などアクションをトリガーする関数呼び出しは、現実世界に影響を与えます。アクションを行う関数については、実行前にユーザーが確認するステップの実装を強く推奨します。
データ削除、送金、外部状態の変更につながる関数呼び出しは、人間の承認を挟むべきです。
セキュリティと信頼性の考慮事項
関数呼び出しは、LLM にできることを広げます。同時に、攻撃者が実行させ得ることも広げます。
ここでの主要な脅威はプロンプトインジェクションです。
プロンプトインジェクションの最終目的は様々ですが、下流のツールコールを通じた機密データの流出、意図と異なるアクションの実行、その他の望ましくないモデルの挙動変更などが含まれます。
関数呼び出しでメール送信、データベースクエリ、Webhook トリガーが可能な場合、インジェクション攻撃は単にチャットボットが台本から外れる話ではなく、潜在的な侵害になります。
AI システムがチャットを超え、ツールを呼び出してアクションを取るようになるにつれ、プロンプトインジェクションははるかに重大な問題になります。ウェブページ、文書、外部ツールに潜む悪意ある指示は、システムの挙動を上書きし、機微情報を露出させ、モデルが決して取るべきでないアクションを引き起こそうとします。
緩和策には、いくつかの具体的なレイヤーがあります。
信頼できないデータが、エージェントの挙動を直接駆動しないようにワークフローを設計します。外部入力からは、列挙や検証済み JSON のような特定の構造化フィールドのみを抽出して、ノード間にインジェクションリスクが流入しないようにします。
その上で、
モデルが生成した関数呼び出しを常に検証してください。パラメータ、呼び出された関数、意図したアクションと整合しているかを確認します。
不都合な真実として、
「プロンプトインジェクションは、ウェブ上の詐欺やソーシャルエンジニアリングと同様、完全に『解決』されることはおそらくありません。」
これは OpenAI 自身の見解です。実務的には、モデルが常に意図どおりに振る舞うという前提で、エージェント的な関数呼び出しシステムを設計すべきではないということです。多層防御(検証、スコープを絞った権限、破壊的操作に対する人間の介在)こそが唯一妥当な姿勢です。
関数呼び出し vs. プロンプトエンジニアリング — 使い分けの指針
この比較はよく取り上げられます。結論を短く言えば:両者は別の問題を解きます。これを混同すると、関数呼び出しで済むのに過剰にプロンプトを作り込んだり、逆にプロンプトで済むのに脆弱な関数スキーマを作ってしまったりします。
プロンプトエンジニアリングは、たとえば「ステップごとに考えて」と指示することで、LLM の内部推論を導くためのテキスト入力を作ることです。
それはモデルがどう推論するかを形作ります。一方で関数呼び出しは、モデルが出力として何を生成し、それをどのようにシステムへルーティングするかを形作ります。
ツール呼び出しは、LLM が外部システムとやり取りするための能力です。どのツールを使うかを決める助けにプロンプトエンジニアリングを使う一方で、実際にアクションを実行するメカニズムがツール呼び出しです。両方が必要になることは多いですが、目的は異なります。
プロンプトベースの構造化出力に対する、関数呼び出しの技術的優位性の要点:
ツール呼び出しはモデルにネイティブに組み込まれた概念です。特定の形式で返すようにモデルへ説明するためにトークンや労力を費やす必要はありません。
「X、Y、Z というフィールドを持つ JSON で答えを返して」とプロンプトで書くと、その指示にモデルが一貫して従うとは限らず、トークンも浪費します。関数呼び出しでは、スキーマの強制が API レベルで行われます。
いまや多くの LLM プラットフォームがネイティブにサポートする関数呼び出し API は、厳格なデータ検証とプログラマブルなワークフローとの統合を可能にする、スキーマ駆動の正式なインターフェースを提供します。
これが、出力が下流システムに流れ込む必要がある場面で、プロンプトエンジニアリングより関数呼び出しを選ぶ実務的な理由です。本番運用では、信頼性は選択肢ではありません。
| Dimension | Prompt Engineering | Function Calling |
|---|---|---|
| Primary purpose | モデルの推論やトーンを整形する | システム統合のための構造化出力を生成する |
| Output format | 自由形式のテキスト(あるいはテキスト然とした JSON) | 強制された JSON スキーマ |
| Schema reliability | ベストエフォートで、ドリフトしがち | strict: true により保証 |
| Token cost | シンプルな出力なら低コスト | 高め(関数定義がトークンを消費) |
| When to use | 推論タスク、テキスト生成、文体コントロール | 構造化データ抽出、API オーケストレーション、エージェント的アクション |
| Prompt injection exposure | 低め(外部ツールを実行しない) | 高め(関数呼び出しが現実のアクションを引き起こし得る) |
実用的な経験則:出力が下流システム(データベース書き込み、API コール、コード内の分岐)を駆動する必要があるなら関数呼び出しを使いましょう。人間が読むための出力なら、通常はプロンプトエンジニアリングで十分で安価です。
重要なポイント
| Topic | What to Remember |
|---|---|
| What it is | モデルは、どの関数をどの引数で呼ぶべきかを記述した構造化 JSON を出力します — 関数自体は実行しません |
| Current API surface | tools と tool_choice を使います。古い functions と function_call パラメータは非推奨です |
| Strict mode | スキーマ準拠を強制するため、関数定義では常に strict: true を設定しましょう |
| Parallel calling | 2023 年 11 月以降にリリースされたモデルでサポート。1 回のリクエストで複数ツールコールを並列実行可能 |
| Token cost | 関数スキーマは入力トークンを消費します。公開する関数の数は最小限に |
| Security | すべての関数呼び出し出力を検証し、信頼できない外部コンテンツがツール呼び出しを直接駆動しないようにする |
| vs. Prompt Engineering | 関数呼び出しは API レベルで出力構造を強制。プロンプトエンジニアリングは内部推論を整形 |
| Confirmation steps | 現実世界の副作用(書き込み、送信、削除)がある関数は、実行前にユーザー確認を要件化 |
さまざまなモデル — GPT-5.4、claude opus 4.7、gemini 3.1 pro — を横断して関数呼び出しを試すとき、各社ごとの API 資格情報を管理したくないなら、CometAPI を使えば、単一のエンドポイントとキーでそれらすべてにアクセスでき、モデル横断のテストの摩擦を大幅に減らせます。
CometAPI はインフラのオーバーヘッドを解消します:
✅ 統一された関数呼び出しシンタックス — 15+ のモデルで共通
✅ 単一の API キー — OpenAI/Anthropic/Google それぞれのアカウント不要
✅ スキーマの自動変換 — 一度書けばどこでもテスト可能
✅ 内蔵のコストトラッキング — モデルごとのトークン使用量をリアルタイム比較
無料クレジットでテストを開始 → アクセスを取得
