OpenAI APIのFunction calling(ツール呼び出し)は、モデルに自分のアプリの機能やデータへアクセスさせるための仕組みである。モデルが直接データベースを触るわけではなく、モデルは「この関数をこの引数で呼びたい」という要求を返し、実際の処理はこちら側のコードが行う。この分担を理解しないまま実装すると、モデルの出力をそのまま実行してしまう設計になったり、引数の形が毎回ぶれて後処理が壊れたりする。
この記事では、OpenAI公式ドキュメント「Function calling」(https://developers.openai.com/api/docs/guides/function-calling、2026年9月21日取得)に記載されている内容だけを根拠に、呼び出しの流れ、関数定義の書き方、strictモードの要件、tool_choiceと並列呼び出しの制御、トークン消費の考え方までを順に整理する。公式に書かれていない挙動や数値は扱わない。
Function callingとは何か|モデルとアプリの役割分担
【完全無料】AI×SNSで成果を出す100大特典を受け取る
AIの使い方を、SNS運用の実務につなげたい方へ。LINEで特典の案内を受け取れます。
要点:Function callingは、モデルが学習データの外にある外部システムやデータへ接続するための仕組みであり、公式ドキュメントではtool calling(ツール呼び出し)とも呼ばれている。
公式ドキュメントは、Function callingを「OpenAIのモデルが外部システムと連携し、学習データの外にあるデータへアクセスするための、強力で柔軟な方法」と説明している(Function calling|OpenAI API、2026年9月21日取得)。ここで重要なのは、モデルが関数を実行するのではないという点である。モデルが返すのは「この関数を、この引数で呼びたい」という要求であり、実際にAPIを叩いたりDBを引いたりするのはアプリ側のコードになる。
同ドキュメントは、モデルに渡せるツールの例として「指定した場所の今日の天気を取得する」「特定のユーザーIDの口座情報にアクセスする」「紛失した注文に対して返金を行う」を挙げている。つまり読み取りだけでなく、返金のような副作用のある操作もツールとして定義しうる。だからこそ、実行の判断をコード側に残す設計が前提になる。
functionとtoolとcustom toolの違いを整理する
要点:functionはJSONスキーマで定義されるツールの一種であり、これに加えて自由テキストを受け取るcustom tool、OpenAIプラットフォーム側が提供するbuilt-in toolsがある。
公式ドキュメントの「Functions versus tools」は3種類を区別している。第一にfunctionで、JSONスキーマによって定義され、モデルからアプリへデータを渡す。第二にcustom toolで、JSONで包まずに自由なテキストを入出力できる。第三にbuilt-in toolsで、これはOpenAIプラットフォームの一部として提供され、Web検索、コード実行、MCPサーバーの機能へのアクセスなどが含まれる(Function calling|OpenAI API、2026年9月21日取得)。
この区別は実装の判断に直結する。構造化した引数を受け取りたいならfunction、コードやクエリのような自由文字列をそのまま受け取りたいならcustom tool、Web検索のようにOpenAI側が用意している機能を使いたいならbuilt-in toolsを選ぶ、という分岐になる。
| 種類 | 入力の形 | 定義する主体 |
|---|---|---|
| function | JSONスキーマで定義した引数 | アプリ側 |
| custom tool | 任意の文字列 | アプリ側 |
| built-in tools | OpenAIプラットフォーム側の仕様 | OpenAI |
ツール呼び出しの5ステップの流れをつかむ
要点:公式ドキュメントはツール呼び出しの流れを5つの段階として示しており、アプリとモデルが2往復する構造になっている。
公式ドキュメントの「The tool calling flow」は、ツール呼び出しを「アプリとモデルのあいだの複数ステップの会話」と位置づけ、次の5段階を挙げている(Function calling|OpenAI API、2026年9月21日取得)。
- 呼び出し候補となるツールを含めてモデルへリクエストする
- モデルからツール呼び出しを受け取る
- ツール呼び出しの入力を使ってアプリ側でコードを実行する
- ツールの実行結果を添えて2回目のリクエストをモデルへ送る
- モデルから最終的な応答(またはさらなるツール呼び出し)を受け取る
Responses APIを使う場合、アプリはタスクに必要な回数だけこの流れを続けられる、と同ドキュメントは説明している。つまり1往復で終わるとは限らず、5番目でさらにツール呼び出しが返ってくる前提でループを組む必要がある。ここを1往復だけの実装にしてしまうと、複数ツールを跨ぐタスクで途中停止する。Responses APIとChat Completionsの選び分けそのものはResponses APIとChat Completionsの違いと使い分けで整理している。
関数定義に書く5つのフィールド
要点:関数定義はtype・name・description・parameters・strictの5フィールドで構成され、parametersにはJSONスキーマを書く。
公式ドキュメントの「Defining functions」は、関数定義のプロパティを次のように示している(Function calling|OpenAI API、2026年9月21日取得)。関数は通常、各APIリクエストのtoolsパラメータで宣言する。
| フィールド | 公式ドキュメントの説明 |
|---|---|
type |
常にfunctionとする |
name |
関数名(例:get_weather) |
description |
その関数をいつ、どのように使うかの詳細 |
parameters |
関数の入力引数を定義するJSONスキーマ |
strict |
その関数呼び出しにstrictモードを強制するかどうか |
上の5つのうち、実装者の判断が一番効くのはdescriptionである。公式の例ではget_weatherのdescriptionが「指定された場所の現在の天気を取得する」となっており、引数側にも「都市と国、例:Bogotá, Colombia」のように形式まで書かれている。引数の書式をdescriptionに書かないと、モデルが都市名だけを渡すのか国名まで含めるのかが安定しない。
strictモードの2つの要件と省略時の挙動
要点:strictをtrueにすると関数呼び出しがスキーマへ従う度合いが上がるが、additionalPropertiesをfalseにすることと、propertiesの全フィールドをrequiredにすることの2要件を満たす必要がある。
公式ドキュメントは「strictをtrueに設定すると、関数呼び出しがベストエフォートではなく、関数スキーマへ確かに従うようになる(reliably adhere)」と説明し、「strictモードを常に有効にすることを推奨する」と明記している(Function calling|OpenAI API、2026年9月21日取得)。内部的にはStructured Outputsの機能を利用しており、そのため2つの要件が生じる。
parameters内の各オブジェクトでadditionalPropertiesをfalseに設定することproperties内の全フィールドをrequiredとして記載すること
2番目の要件は「任意項目を作れない」という意味ではない。公式ドキュメントは、型の選択肢にnullを追加することで任意フィールドを表現できると案内している。つまりrequiredには全項目を並べたうえで、省略可能な項目は型を["string", "null"]のように書く形になる。Structured Outputsそのものの挙動はOpenAI APIの構造化出力の使い方でも扱っている。
省略時の挙動はAPIによって異なる点に注意したい。公式ドキュメントによれば、strict: trueを送ってスキーマが上記要件を満たしていない場合、不足している制約の詳細とともにリクエストが拒否される。一方strictを省略した場合、Responses APIのリクエストは可能であればスキーマをstrictモードへ正規化しようと試み、互換性を持たせられない場合はベストエフォートの非strictな関数呼び出しへフォールバックする。フォールバックが起きたとき、レスポンスのtoolにはstrict: falseが表示される。Chat Completionsのリクエストは既定で非strictのままである。Responses APIでstrictモードを使わずベストエフォートを維持したい場合は、明示的にstrict: falseを設定する。
| 設定 | Responses API | Chat Completions |
|---|---|---|
strict: true(要件を満たす) |
スキーマに従う | スキーマに従う |
strict: true(要件未達) |
不足する制約の詳細つきで拒否 | 不足する制約の詳細つきで拒否 |
strictを省略 |
可能ならstrictへ正規化、不可なら非strictへフォールバック | 既定で非strict |
strict: false |
非strict(明示的なオプトアウト) | 非strict |
仮の例として、社内の在庫照会ツールを作る場面を考える。product_codeとwarehouseの2引数を持つ関数で、warehouseは未指定なら全倉庫を見るという仕様にしたいとする。この場合、requiredにはproduct_codeとwarehouseの両方を並べ、warehouseの型を文字列とnullの2択にする。requiredからwarehouseを外すと、strictモードの2番目の要件に反するため拒否される。
tool_choiceでモデルの選択を制御する4つの指定
要点:tool_choiceは、モデルに任せる(auto)、1個以上を呼ばせる(required)、特定の関数に固定する、呼べる範囲を絞る(allowed_tools)の指定ができ、noneを指定すると関数を渡していない状態を模倣できる。
公式ドキュメントの「Tool choice」は、既定ではモデルがいつ・いくつツールを使うかを判断すると述べたうえで、tool_choiceパラメータで挙動を強制できるとしている(Function calling|OpenAI API、2026年9月21日取得)。示されている指定は次の4種類である。
| 指定 | 挙動 |
|---|---|
"auto"(既定) |
0個、1個、または複数の関数を呼ぶ |
"required" |
1個以上の関数を呼ぶ |
{"type": "function", "name": "get_weather"} |
指定した1つの関数だけを呼ぶ |
allowed_tools |
モデルが呼べるツールを、渡したツールの部分集合へ制限する |
上の4つに加えて、tool_choiceに"none"を設定すると、関数を1つも渡していないときの挙動を模倣できる、と公式は説明している。
allowed_toolsの使いどころについて、公式ドキュメントは明確な理由を挙げている。モデルへ渡すツールの一覧そのものは変えずに、リクエストをまたいで一部のツールだけを利用可能にしたい場合に使うことで、プロンプトキャッシュによる節約を最大化できるという趣旨である。ツール定義の並びが毎回変わるとキャッシュが効きにくくなるため、定義は固定したまま利用範囲だけを絞るという発想になる。プロンプトキャッシュ自体の仕組みはOpenAI公式のPrompt cachingガイド(2026年9月21日取得)にまとまっている。
並列呼び出しをどう扱うか
要点:モデルは1ターンで複数の関数を呼ぶことがあり、parallel_tool_callsをfalseにすると呼ばれるツールは0個または1個に限定される。
公式ドキュメントの「Parallel function calling」は、GPT-5以降の対応モデルでは、built-in toolsも利用可能な状態のときに関数を並列で呼び出せると述べている。ただしbuilt-in toolsを並列の関数呼び出しのバッチへ含めることはできない。また、モデルが1ターンで複数の関数を呼ぶ可能性があり、これを避けたい場合はparallel_tool_callsをfalseに設定すると、呼ばれるツールが0個または1個に限定される(Function calling|OpenAI API、2026年9月21日取得)。
同セクションには2つの注記がある。1つ目は、ファインチューニング済みモデルを使っていて、モデルが1ターンで複数の関数を呼んだ場合、それらの呼び出しについてstrictモードが無効になるという点である。2つ目は、gpt-4.1-nano-2025-04-14というスナップショットについてで、並列ツール呼び出しが有効な場合に同じツールに対する複数のツール呼び出しを含めることがあるため、このスナップショットを使うときは並列呼び出しを無効にすることが推奨されている。
実装上は、副作用のある操作を並列に走らせてよいかという観点で決めるのが分かりやすい。返金や送信のように二重実行が問題になる操作を含むなら、parallel_tool_callsをfalseにして直列化しておくと、重複呼び出しの検討を後回しにできる。
実行結果をモデルへ返すときの形式
要点:関数の実行結果は文字列で返すのが基本で、形式はJSONでもエラーコードでもプレーンテキストでもよく、戻り値のない関数でも成否を示す文字列を返す。
公式ドキュメントの「Formatting results」は、function_call_outputメッセージで渡す結果は通常は文字列であるべきで、その形式(JSON、エラーコード、プレーンテキストなど)は実装者に委ねられていると説明している。モデルはその文字列を必要に応じて解釈する。画像やファイルを返す関数については、文字列の代わりに画像オブジェクトやファイルオブジェクトの配列を渡せる(Function calling|OpenAI API、2026年9月21日取得)。
見落としやすいのは、戻り値のない関数の扱いである。公式ドキュメントはsend_emailのような戻り値のない関数を例に挙げ、"success"のように成功または失敗を示す文字列を返すよう案内している。ここは公式の案内どおりに成否の文字列を返しておくのが素直である。何も返さない設計にすると、モデル側から見て操作が完了したかどうかの手がかりが無くなる、というのが理由として考えられる(この解釈自体は公式ドキュメントに明記されたものではない)。
関数定義の設計でつまずきやすい点
要点:公式のベストプラクティスは、説明を具体的に書くこと、無効な状態を作らせないこと、モデルに埋めさせる引数を減らすこと、最初に見せる関数の数を絞ることを挙げている。
公式ドキュメントの「Best practices for defining functions」から、実装判断に直結する項目を挙げる(Function calling|OpenAI API、2026年9月21日取得)。
- 関数名、パラメータの説明、指示を明確かつ詳細に書く。各パラメータの目的と形式、出力が何を表すかを明示する
- システムプロンプトで、各関数をいつ使い、いつ使わないかを記述する
- 例やエッジケースを含める。ただし推論モデルでは例の追加が性能を下げる場合があると注記されている
- enumとオブジェクト構造を使って無効な状態を防ぐ。公式は
toggle_light(on: bool, off: bool)を、無効な呼び出しが可能になる例として挙げている - すでに分かっている引数をモデルに埋めさせない。注文IDが手元にあるなら引数に含めず、コード側で渡す
- 常に連続して呼ばれる関数はまとめる
- ターン開始時に利用可能な関数は20個未満を目安にする(公式はこれを緩やかな提案としている)
「intern test」という表現も示されている。渡した情報だけで、インターンや人間がその関数を正しく使えるかを確かめ、使えないなら相手が聞いてくるであろう質問の答えをプロンプトへ足す、という考え方である。プロンプト側の書き方の基本はChatGPTのプロンプトはなぜ伝わらない?書き方の5つのコツとはでも扱っている。
関数定義はトークンを消費する
要点:関数定義はシステムメッセージへ注入されるため、モデルのコンテキスト上限を消費し、入力トークンとして課金される。
公式ドキュメントの「Token Usage」は、内部的に関数がモデルの訓練済み構文でシステムメッセージへ注入されると説明している。そのため呼び出し可能な関数定義はモデルのコンテキスト上限にカウントされ、入力トークンとして課金される。トークン上限に当たる場合の対処として、最初に読み込む関数の数を制限すること、可能な範囲でdescriptionを短くすること、tool searchを使って遅延読み込みにすることが挙げられている(Function calling|OpenAI API、2026年9月21日取得)。
つまり「使うかもしれない関数を全部渡しておく」という設計は、精度とコストの両面で不利になる。非同期のバッチ処理でコストを抑える方法はOpenAI Batch APIとは|50%安い非同期処理の使い方と料金で別途扱っている。モデルごとの料金体系はChatGPT料金プラン完全比較も参照できる。
ツールが増えたときの整理|namespaceとtool search
要点:namespaceはツールを業務領域ごとにまとめる仕組みで、tool searchは使用頻度の低いツールを遅延読み込みにする仕組みである。
公式ドキュメントの「Defining namespaces」は、crm、billing、shippingのようにツールを領域ごとにグループ化する用途を示している。CRM用の検索ツールとサポートチケット用の検索ツールのように、異なるシステムや目的に仕える似たツールのあいだでモデルが選ぶ必要があるときに特に有用だとされている。namespaceはtypeにnamespaceを指定し、name、description、toolsを持つ構造で、配下の関数にはdefer_loadingを指定できる(Function calling|OpenAI API、2026年9月21日取得)。
tool searchについて、公式ドキュメントは「アプリケーションが多数の関数や大きなスキーマを持つ場合、Function callingとtool searchを組み合わせて、めったに使われないツールを遅延させ、モデルが必要としたときだけ読み込める」と述べている。同ドキュメントには「tool_searchをサポートするのはgpt-5.4以降のモデルだけである」という制約も明記されている。詳細はOpenAI公式のTool searchガイド(2026年9月21日取得)にある。
なお、tool searchを使う場合もtool_choiceはそのターンで現在呼び出し可能なツールに対して適用される、と公式は補足している。ツールの一部を読み込んだうえで、モデルをその部分集合へ制約したいときに使える。
custom toolで自由テキストを受け取る
要点:custom toolは、JSONスキーマで引数を指定する代わりに、モデルが任意の文字列をそのままツールへ渡せる仕組みである。
公式ドキュメントの「Custom tools」は、custom toolがJSONスキーマ駆動のfunction toolとほぼ同じように動作するが、どんな入力が必要かをモデルへ明示的に指示する代わりに、モデルが任意の文字列を入力としてツールへ返せる点が異なると説明している。応答を不必要にJSONで包むのを避けたい場合や、応答へ独自の文法を適用したい場合に有用だとされている(Function calling|OpenAI API、2026年9月21日取得)。
公式のサンプルでは、Pythonコードを含む文字列を受け取ることを想定したcode_execというcustom toolが示されており、typeにcustom、nameにcode_exec、descriptionに「任意のPythonコードを実行する」を指定する形になっている。コードやクエリをそのまま受け取りたい用途では、JSONで包む前提のfunctionより素直に書ける。コーディング用途でのOpenAI製品の選び方はOpenAI Codexの提供形態の違いやOpenAI Codex 使い方でも整理している。
モデルとAPIの組み合わせに関する制約
要点:公式ドキュメントは、GPT-6 Astraのツール呼び出しにはResponses APIが必要であると明記しており、Chat Completionsの例は互換性のためGPT-5.6を使っている。
公式ドキュメントの冒頭付近には、「GPT-6 Astraはツール呼び出しにResponses APIを必要とする。Chat Completionsの例は互換性のためGPT-5.6を使用している」という記述がある。既存の連携を更新する場合は移行ガイドを参照するよう案内されている(Function calling|OpenAI API、2026年9月21日取得)。移行の手順そのものはOpenAI公式のResponses API移行ガイド(2026年9月21日取得)にまとまっている。
この制約は、モデルを新しいものへ入れ替えるだけでは済まない場合があることを意味する。Chat Completionsでツール呼び出しを実装している既存コードで新しいモデルを使いたい場合、API側の移行が先に必要になる。モデルの世代ごとの違いはGPT-6 AstraとはやChatGPT最新モデルの違いと使い分けで扱っている。
また、Agents APIのセッションでツールを使う場合は、Functionsを使って関数を登録しセッションのアクション要求を処理する、と公式は案内している。この記事で扱ってきた例は、Responses APIとChat Completionsの連携を前提にしたものである。
導入前に決めておきたい設計の順番
要点:ツールの棚卸し、strictモードの要件に合わせたスキーマ設計、副作用の有無に応じた並列可否の決定、という順に決めると手戻りが少ない。
ここまでの公式仕様を、着手順に並べ直す。まずアプリ側で「モデルに任せたい操作」を書き出し、そのうち最初のターンから見せる必要があるものだけを選ぶ。公式のベストプラクティスがターン開始時20個未満を目安として挙げているため、この時点で絞り込みが必要になることが多い。
次にスキーマを書く。strictモードを使う前提なら、additionalPropertiesをfalseにし、propertiesの全項目をrequiredへ入れ、省略可能な項目は型にnullを足す形で設計する。あとからstrictを有効にしようとすると、この2要件のためにスキーマを書き直すことになりやすい。
最後に並列の可否を決める。副作用のある操作を含むならparallel_tool_callsをfalseにし、読み取り専用のツールだけで構成されているなら既定のまま様子を見る、という分け方ができる。仮の例として、社内FAQ検索と在庫照会だけを持つ読み取り専用の構成なら並列のままでよく、そこへ返金処理を足す段階で直列化を検討する、という進め方になる。
よくある質問(FAQ)
- Q1. Function callingを使うと、モデルが直接データベースを操作するのですか。
- いいえ。公式ドキュメントが示す5ステップの流れでは、モデルはツール呼び出しを返すだけで、実際のコード実行はアプリ側の段階として明示されている。実行の可否はアプリ側で判断できる。
- Q2. strictモードは有効にしたほうがよいですか。
- 公式ドキュメントはstrictモードを常に有効にすることを推奨している。ただし
additionalPropertiesをfalseにすることと、propertiesの全フィールドをrequiredにすることの2要件を満たす必要があり、満たさずにstrict: trueを送ると、不足している制約の詳細とともにリクエストが拒否される。 - Q3. strictを書かなかった場合はどうなりますか。
- APIによって異なる。公式ドキュメントによれば、Responses APIは可能であればスキーマをstrictモードへ正規化しようとし、互換性を持たせられない場合は非strictへフォールバックする。フォールバック時はレスポンスのtoolに
strict: falseが表示される。Chat Completionsは既定で非strictのままである。 - Q4. strictモードで任意の引数は作れますか。
- 作れる。
requiredから項目を外すのではなく、その項目の型にnullを足す形で表現する、というのが公式ドキュメントの案内である。 - Q5. 関数をたくさん定義すると何が起きますか。
- 公式ドキュメントは、関数定義がシステムメッセージへ注入されるためコンテキスト上限を消費し、入力トークンとして課金されると説明している。対処として、最初に読み込む関数を制限する、descriptionを短くする、tool searchで遅延読み込みにする、という方法が挙げられている。
- Q6. 並列のツール呼び出しを止めたいときはどうしますか。
parallel_tool_callsをfalseに設定すると、呼ばれるツールが0個または1個に限定される、と公式ドキュメントは説明している。なおgpt-4.1-nano-2025-04-14のスナップショットについては、同じツールへの複数呼び出しが含まれることがあるため並列を無効にすることが推奨されている。
まとめ
Function callingは、モデルに判断を任せ、実行はアプリ側が持つという役割分担の仕組みである。公式ドキュメントが示す5ステップの流れを前提にループを組み、関数定義ではtype・name・description・parameters・strictの5フィールドを埋める。
精度に効くのはdescriptionの具体性と、最初のターンで見せる関数の数の絞り込みである。安定性に効くのはstrictモードで、additionalPropertiesをfalseにし全項目をrequiredへ入れる設計を最初から取っておくと、あとで有効化するときの書き直しを避けられる。副作用のある操作を含む構成では、parallel_tool_callsの扱いを先に決めておく。
いずれの仕様も更新される可能性があるため、実装前にOpenAI公式のFunction callingガイドで現在の記載を確認してほしい。この記事の内容は2026年9月21日時点の同ページの記載にもとづいている。ChatGPT側の機能整理から入りたい場合はChatGPTのプロジェクト機能の使い方やカスタムGPT(GPTs)の作り方も参考になる。
あわせて読みたい・姉妹メディア
