Programmatic Tool Callingは、GPT-5.6がResponses API内でJavaScriptを書き、複数のツール呼び出しを並列実行したり、ループや条件分岐で処理したりできる仕組みです。
通常のTool Callingでは、モデルがツールを1つずつ選び、結果を読んで次の判断をします。Programmatic Tool Callingでは、処理手順が明確な部分をコードへまとめ、中間結果を絞り込んでからモデルへ返せます。
この記事では、通常のTool Callingとの違い、向いている処理、V8実行環境の制約、JavaScriptでの実装例、安全に使うための設計を解説します。
情報確認日:2026年7月11日(日本時間)
結論:予測できる複数ツール処理をJavaScriptへまとめる機能
この記事の結論
- モデルが生成したJavaScriptをOpenAIの分離されたV8環境で実行する
- 独立したツール呼び出しの並列化、ループ、条件分岐、集計に向いている
- モデルに毎回意味判断をさせたい処理や、承認が必要な書き込みは直接呼び出しが向いている
programmatic_tool_callingと、各ツールのallowed_callersを設定する- ツールの戻り値は
output_schemaで構造化し、引数と権限をアプリ側でも検証する
Programmatic Tool Callingとは?
Programmatic Tool Callingは、モデルがツールを呼び出すためのJavaScriptプログラムを生成し、そのプログラムをResponses API内のホスト環境で実行する機能です。
たとえば在庫と注文数を別々のツールから取得する場合、通常はモデルが在庫を取得し、結果を読み、次に注文数を取得して計算します。Programmatic Tool Callingでは、2つの取得をPromise.all()で並列に行い、差分だけを最終結果として返せます。
これにより、モデルのコンテキストへ大量の中間データをそのまま追加せず、コードでフィルター、結合、重複削除、集計、検証を行える場合があります。
通常のTool Calling・Function Callingとの違い
| 方式 | 処理の進め方 | 向いている場面 |
|---|---|---|
| Function Calling | モデルがアプリ側の関数を選び、引数を生成する | 1つの関数実行や、小さなAPI連携 |
| 直接のTool Calling | ツール結果をモデルが読み、次のツールや回答を判断する | 結果ごとに意味判断が必要な検索や承認操作 |
| Programmatic Tool Calling | モデルがJavaScriptを生成し、複数ツールをコードで制御する | 並列取得、集計、変換、検証、予測可能な依存処理 |
Tool Callingの基本を確認したい場合は、Tool Callingとは?AIに外部ツールを使わせる仕組みと、Function Callingの使い方から読むと整理しやすくなります。
Programmatic Tool Callingが向いている処理
- 複数の独立したデータ取得を並列実行する
- 大量の結果を条件で絞り込む
- 複数の結果を結合し、重複を削除する
- 数値を集計し、小さなJSONへまとめる
- 後続ツールの引数を前の結果から機械的に作る
- 明確な終了条件と再試行回数がある処理
直接のTool Callingを使うほうがよい処理
- 1回の検索や1つの操作で終わる
- 各結果を読んで、次の検索方針を意味的に変える
- 送信、削除、購入、更新など、承認が必要な操作を行う
- 引用やネイティブな成果物をそのまま維持する必要がある
- ツールの戻り値の構造が事前に決められない
基本方針:1回の呼び出しなら直接、予測できる複数処理ならProgrammatic、結果ごとにモデルの判断が必要なら再び直接呼び出しを使います。
JavaScriptが実行される環境の制約
生成されたプログラムは、OpenAIが用意する新しい分離済みV8環境で実行されます。一般的なNode.jsサーバーではありません。
| 利用できるもの | 利用できないもの |
|---|---|
JavaScript、トップレベルのawait、許可されたツール、text()・image()による出力 |
Node.js、npmパッケージ、直接のネットワーク通信、一般的なファイルシステム、サブプロセス、console、実行間で残る状態 |
外部システムへアクセスする場合は、プログラムが直接HTTP通信を行うのではなく、リクエストで許可されたFunction、MCP、Shellなどのツールを通します。
Programmatic Tool Callingを有効にする設定
基本設定は2つです。
- tools配列へ
{ type: "programmatic_tool_calling" }を追加する - プログラムから使わせるツールへ
allowed_callers: ["programmatic"]を設定する
allowed_callers |
意味 |
|---|---|
省略または["direct"] |
モデルがツールを直接呼び出す |
["programmatic"] |
生成されたprogram内からだけ呼び出す |
["direct", "programmatic"] |
直接とprogram内の両方から呼び出せる |
ツールの戻り値が決まっている場合は、output_schemaも定義します。生成されたJavaScriptが、説明文を解析せずにフィールドを利用できるためです。
Programmatic Tool CallingのJavaScript実装例
次の例では、在庫数と注文数を別のFunctionから取得し、不足数を計算します。モデルは2つのFunctionをprogram内で並列に呼び出せます。
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const implementations = {
get_stock: async ({ sku }) => ({ sku, available: 42 }),
get_orders: async ({ sku }) => ({ sku, requested: 58 }),
};
const tools = [
{
type: "function",
name: "get_stock",
description: "Return the available stock for one SKU.",
parameters: {
type: "object",
properties: { sku: { type: "string" } },
required: ["sku"],
additionalProperties: false,
},
output_schema: {
type: "object",
properties: {
sku: { type: "string" },
available: { type: "number" },
},
required: ["sku", "available"],
additionalProperties: false,
},
allowed_callers: ["programmatic"],
},
{
type: "function",
name: "get_orders",
description: "Return requested order units for one SKU.",
parameters: {
type: "object",
properties: { sku: { type: "string" } },
required: ["sku"],
additionalProperties: false,
},
output_schema: {
type: "object",
properties: {
sku: { type: "string" },
requested: { type: "number" },
},
required: ["sku", "requested"],
additionalProperties: false,
},
allowed_callers: ["programmatic"],
},
{ type: "programmatic_tool_calling" },
];
const input = [
{
role: "developer",
content:
"Use Programmatic Tool Calling for the stock comparison. " +
"Call independent tools in parallel, then return one JSON object " +
"with sku, available, requested, and shortage. Do not change data.",
},
{
role: "user",
content: "Check whether sku_123 has enough stock.",
},
];
while (true) {
const response = await client.responses.create({
model: "gpt-5.6-sol",
store: false,
input,
tools,
include: ["reasoning.encrypted_content"],
});
if (response.status !== "completed") {
throw new Error(`Response ended with: ${response.status}`);
}
// program・reasoning・messageを含め、出力を順番どおり保持する
input.push(...response.output);
const calls = response.output.filter(
(item) => item.type === "function_call",
);
if (calls.length === 0) {
const message = response.output.find(
(item) => item.type === "message",
);
if (message) {
console.log(response.output_text);
break;
}
continue;
}
const outputs = await Promise.all(
calls.map(async (call) => {
const run = implementations[call.name];
if (!run) throw new Error(`Unknown tool: ${call.name}`);
const result = await run(JSON.parse(call.arguments));
return {
type: "function_call_output",
call_id: call.call_id,
output: JSON.stringify(result),
// どのprogramを再開するか判断するため、callerを維持する
caller: call.caller,
};
}),
);
input.push(...outputs);
}
このコードでは、OpenAI側が生成したJavaScriptをアプリが直接実行するわけではありません。OpenAIの実行環境から返されたfunction_callだけをアプリが処理し、結果をfunction_call_outputとして戻します。
レスポンスに追加される主な項目
| 項目 | 内容 |
|---|---|
program |
モデルが生成したJavaScript、call_id、再開に使うfingerprint |
function_call |
programから呼ばれたアプリ側のFunction。callerで親programを識別する |
program_output |
programの最終結果とcompleted/incompleteの状態 |
message |
利用者へ返す最終回答 |
programは複数回停止し、Functionの結果を待つ場合があります。最終的なmessageが返るまで、出力項目を順番どおり保持して処理を継続します。store: falseでは、program、reasoning、Function呼び出し、Function結果を含む履歴を再送します。
安全に実装するためのポイント
- ツール名、引数、戻り値を具体的に定義する
- 戻り値が決まっているツールには
output_schemaを付ける - アプリ側でも引数、権限、対象データを検証する
- 再試行されても問題が起きにくい処理にする
- 書き込みや高影響操作には、アプリ側の承認を必須にする
- 終了条件、最大件数、再試行回数を指示する
- 許可するツールを必要最小限にする
「効率よく使って」のような曖昧な指示だけでは、直接呼び出しとProgrammaticの境界が不明確になります。「この集計部分だけprogramで実行し、公開や更新は直接呼び出しで承認を取る」のように役割を分けます。
Programmatic Tool Callingの効果を確認する方法
すべての処理でProgrammatic Tool Callingが速く安くなるとは限りません。まず直接のTool Callingを基準にし、同じ入力データで比較します。
- 最終結果の正確さ
- 中間データを含む入力トークン量
- 処理時間
- ツール呼び出し回数と重複
- 失敗時の再試行と復旧のしやすさ
- 承認やログを追跡しやすいか
よくある質問
生成されたJavaScriptを自分のサーバーで実行しますか?
実行しません。JavaScriptはOpenAIの分離されたV8環境で動き、アプリは返されたクライアント所有Functionだけを実行します。
Node.jsのライブラリを使えますか?
Programmatic Tool Callingの実行環境ではNode.jsやnpmパッケージを利用できません。必要な外部処理は、許可したツールとして提供します。
すべてのツールをprogramから呼べますか?
対応するツールへallowed_callersを設定する必要があります。Function、Custom、MCP、Apply Patch、Shell、Code Interpreterなど、programからの呼び出しに対応したツールが対象です。
データ更新にも使えますか?
技術的に呼び出せる場合でも、書き込みや承認が必要な操作は直接のTool Callingを基本にし、アプリ側で明確な承認境界を設けるのが安全です。
まとめ
Programmatic Tool Callingは、GPT-5.6に複数ツールの制御用JavaScriptを生成させ、並列取得、条件分岐、ループ、集計などをResponses API内で実行する機能です。
- 予測可能な複数処理をコードへまとめる
- 意味判断や承認が必要な処理は直接呼び出しを使う
allowed_callersとoutput_schemaを明確にする- アプリ側で引数、権限、承認を検証する
- 直接のTool Callingを基準に、速度、料金、精度を比較する
最初は、2つの読み取り専用Functionを並列に呼び、結果を1つの小さなJSONへまとめる処理から試すと、通常のTool Callingとの違いを確認しやすくなります。