OpenAI Agents API + JSON Schema 実践:安定し、検証でき、実行できる JSON をどう出すか(2026)
一般の Schema 稿は、なぜ契約が要るかを書いた。本稿は Agents API にだけ落とす:モデルが埋める JSON は、門を通ってから実行する。ツール引数、MCP 入力、自分の台帳は三つの門であり、「JSON を出して」という一文ではない。
読む前の一覧
| 門 | 何を鎖すか | 誰が実行するか |
|---|---|---|
| Function parameters | order_id、真偽、列挙 | additionalProperties: false |
| 宿主の検証 | required_actions の arguments | 通らねば関数を走らせない |
| 最終カード | 利用者に見せるオブジェクト | 別 Schema。text.format ではない |
| MCP | 別ツール表の inputSchema | subagent は継承しうる |
Schema は門であり、礼儀ではない。広い object はもう一枚の門を開けたままにする。
安定、検証、実行は三つの手続きであり、一つのスイッチではない
Agents API でもモデルは JSON を埋めるだけ。公式の function には parameters Schema が要る。required、additionalProperties: false、必要なら pattern / enum。これで埋めが安定する。検証とは、実行前に同じ Schema で arguments を走らせること。実行とは、門のあとで宿主が副作用を出すこと。
- 安定:ツール引数を厳しい Schema にする。広い
objectは鍵の発明を招く。 - 検証:
required_actionsの呼び出しを手元で検証する。履歴の function_call では足りない。 - 実行:門を通らねば
lookup_orderを走らせない。success: falseと理由を返す。黙って庫を触らない。
ツールの呼び方は OpenAI Agents API 完全解説。四つの対象を ID で留める話は Agents API の JSON データ構造。Schema / Function Calling / Structured Output の一般の分け方は AI に JSON Schema が必要な理由。本稿は定義を繰り返さない。Agents session への落とし方だけを書く。
第一の門:agent.tools の parameters
公式の function は name、description、JSON Schema。session 作成時に agent.tools へ書く。架空の注文。実鍵は貼らない:
{
"type": "function",
"name": "lookup_order",
"description": "Look up an order by ID. Confirm before any refund.",
"parameters": {
"type": "object",
"properties": {
"order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" },
"include_lines": { "type": "boolean" }
},
"required": ["order_id", "include_lines"],
"additionalProperties": false
}
}
要点は少ない。すべての欄を required に入れる。オブジェクトは余分な鍵を閉じる。番号は pattern であり、裸の string ではない。関数は既定で先行読み込み。遅らせるなら defer_loading: true と tool_search。門そのものは変わらない。
門を通らない引数は実行しない
session が agent.session.requires_action で止まると、required_actions に function_call が出る。次の例は照会に見えるが、すでに越境している。番号は pattern に合わず、refund が増えている:
{
"type": "function_call",
"turn_id": "turn_2",
"call_id": "call_3c91",
"name": "lookup_order",
"arguments": {
"order_id": "1042",
"include_lines": true,
"refund": true
}
}
同じ turn_id / call_id。通る形はこうなる。余分な鍵、欠けた required、漂った pattern。どれも実行してはならない:
{
"type": "function_call",
"turn_id": "turn_2",
"call_id": "call_3c91",
"name": "lookup_order",
"arguments": {
"order_id": "A-1042",
"include_lines": true
}
}
第二の門:宿主が同じ Schema をもう一度走る
公式 Schema は埋めの質を上げる。副作用は引き受けない。実行前に手元で検証する。失敗は見直せるオブジェクトにする:
{
"check": "lookup_order",
"schema": "parameters",
"pass": ["order_id", "include_lines"],
"fail": [
{ "path": "/order_id", "reason": "pattern" },
{ "path": "/refund", "reason": "additionalProperties" }
],
"execute": false
}
失敗なら events 端点へ agent.session.input.tool_result を送り、success: false と読める error。成功なら output を文字列化する。新しい session で「再試行」しない。
{
"type": "agent.session.input.tool_result",
"turn_id": "turn_2",
"call_id": "call_3c91",
"success": false,
"error": "order_id failed schema: expected ^[A-Z]-\\d{4}$"
}
最終カードは第三の門であり、Responses の text.format ではない
利用者に見せる注文カードは、ツール引数の Schema ではない。Agents session は Responses の text.format.json_schema を自動では掛けない。三つを分けて書く:
- ツール引数:副作用の入口を鎖す。照会と書き込みはここ。
- 最終カード:items からオブジェクトを抜き、別 Schema で検証してから見せる。
- 最終形を Structured Outputs で鎖すなら:それは Responses の層。同じ session 資源に混ぜない。
ループを預けるかは Agents API vs Responses API。MCP の行は別のツール表。inputSchema も additionalProperties: false が要る。境界は MCP Tool Schema vs Function Calling。subagent は MCP Schema を継ぎ、function は継がない。
実行できる JSON への五手順
「JSON を出して」から始めない。門を歩く:
- まずツール Schema を書く。pattern、enum、required、additionalProperties: false を一度締める。
- 同じ Schema を宿主の検証器へ入れる。公式 parameters と別稿にしない。
- required_actions では検証してから実行する。通らねば success: false。
- 最終カードは別 Schema。items から抜いたあと検証する。散文をカードにしない。
- 台帳の欄は自分で持つ。compact は細部を落とす。金額と承認を会話にだけ置かない。
ワークフローを Schema に収める話は JSON Schema と Agent ワークフロー。本稿が求めるのは、Agents session の門がすべて対象であること。
安定した出力を見直すなら、二つの JSON を広げる
漂いの多くは、門が揃っていないことだ。モデルが愚かになったことではない。
- parameters と arguments を 整形 し、余分な鍵と欠けを見る。
- JSONPath 抽出 で
order_idと$.parameters.requiredを抜く。 - 門を通らなかった呼び出しと通った呼び出しを JSON Diff。pattern が漂ったら Schema を先に見る。
- カードの Schema とツールの Schema は分けて審る。カードだけ鎖しても、入口は開いたまま。
- 注文、session、社内 MCP を公開フォーマッタに貼らない。JSONSort はブラウザ内で動く。
二つの軌跡が Schema で再建できて初めて、JSON を集めている。そうでなければ散文を集めている。
よくある落とし穴
- instructions に「JSON を出して」とだけ書く。それは門ではない。門は parameters と宿主の検証器。
- required に一部の欄だけ列ぶ。載らない鍵は空のままになり、次の跳躍に穴が開く。
- additionalProperties を書かない、または true にする。公式例は余分な鍵を閉じる。refund が一つ増えると副作用が傾く。
- Responses の text.format を Agents session に写す。資源は二つ。最終カードは自分で検証する。
- 検証に落ちても関数を走らせる。実行の前提は門を通ること。先に error を返す。
- subagent に function を走らせる。下位エージェントは function ツールを持たない。厳しい Schema は主 Agent に残す。
FAQ
Agents API に Structured Outputs はあるか?
ツール引数は JSON Schema で締める。利用者に見せる最終オブジェクトに、session は Responses の text.format を自動では掛けない。最終形を鎖すなら自分で検証するか、その跳躍を Responses に置く。
公式 Schema があるのに、また検証するのか?
する。公式の門は埋めの質を上げる。副作用はあなたのプロセス。required_actions の arguments を同じ Schema に通し、失敗なら success: false。
pattern と enum は要るか?
要る。裸の string では 1042 が入り、A-1042 にならない。金額と状態は enum か明示形式。広い型は最も多い越境。
MCP ツールも同じ規律か?
同じ。inputSchema も余分な鍵を閉じ、required を列べきる。subagent は MCP を継ぎ、function は継がない。自社注文の門は主 Agent に残す。
検証失敗で session は固まるか?
同じ turn_id / call_id の対で tool_result を返せばよい。error を明確に書けば、モデルは引数を変えて再呼びできる。新しい session を再試行にしない。
結論
Agents API の安定した JSON は、より長い指示ではない。三つの門だ。ツール parameters、宿主の再検証、最終カードの別 Schema。実行は門のあと。
A-1042 がどの規則で落ちるかを先に書く。経路を指せれば、データは検証できる。モデルは変わる。門を先に安定させる。
続きを読む
- OpenAI Agents API 完全解説 Session、Tool Calling、Schema のつなぎ
- Agents API の JSON データ構造 Agent / Tool Call / Tool Result / Handoff
- Agents API vs Responses API ループを誰が回すか
- 長時間の Agents API Session、compact、Subagents
- AI に JSON Schema が必要な理由 Schema / Function Calling / Structured Output
- JSONSort のローカル道具箱 整形、検証、Diff
- すべての記事 JSON と AI 開発のメモ
更新記録: 初回公開