マルチモデル API ゲートウェイの構造化出力: JSON スキーマ、ツール呼び出し、セマンティック ガードレール
複数の LLM プロバイダーにわたって信頼性の高い構造化出力を実現する実用的なアダプター パターン。スキーマの正規化、応答の検証、ツール呼び出しの処理、失敗のログ記録、本番ワークフローに到達する前に安全でないアクションのブロックを行います。
モデルに「JSON を返す」よう促すことは、運用契約ではありません。間違った列挙型の有効な JSON が生成されたり、必要なビジネス ルールが省略されたり、ユーザーが許可していないアクションを堂々と要求したりする可能性があります。マルチプロバイダーのワークフローでは、問題はさらに難しくなります。各プロバイダーは、異なる構造化出力メカニズムとツール使用メカニズムを公開し、それぞれが JSON スキーマ ユニバースの一部のみをサポートします。
実際的な解決策は、1 つの魔法のプロンプトではありません。これは階層化されたゲートウェイ パターンです。開発者が希望するスキーマを正規化し、可能であればプロバイダー ネイティブの構造化出力またはツール呼び出し形式に変換し、返されたオブジェクトを検証し、副作用が発生する前にセマンティック ガードレールを適用します。
このガイドでは、しばしば混在する 3 つの異なる目標を分けて説明します。
- 構文の有効性: 応答は解析可能な JSON です。
- スキーマの有効性: JSON は必須フィールド、型、列挙型、構造ルールと一致します。
- ビジネス上の正確性: オブジェクトは安全で、ユーザーの意図に忠実であり、下流のアクションに対して有効です。
本番環境の失敗: 有効な JSON、間違ったアクション
受信したチケットをルーティングするサポートの自動化を検討してください。
{
"チケットID": "t_481",
"カテゴリ": "請求",
"優先度": "緊急"、
"アクション": "払い戻し_顧客",
「金額_米ドル」: 499
}
このオブジェクトは構文的に有効です。 action が文字列で、amount_usd が数値の場合は、単純なスキーマを渡すこともできます。しかし、それでも間違っている可能性があります。おそらく顧客は請求書のコピーだけを要求したのでしょう。おそらく 100 ドルを超える払い戻しにはマネージャーの承認が必要です。おそらく、ユーザーには払い戻しをトリガーする権限がまったくない可能性があります。
構造化された出力により、解析の失敗が減少します。これらは、承認、ポリシー チェック、在庫チェック、価格設定チェック、冪等性、または危険な操作のための人による確認に代わるものではありません。
事実: プロバイダーの構造化出力モードが行うことと約束しないこと
プロバイダーの状況は急速に変化しますが、アーキテクチャにとって重要な安定した事実がいくつかあります。
- JSON モードは有効な JSON の生成に役立ちますが、有効な JSON は特定のスキーマに準拠していることと同じではありません。
- プロバイダネイティブの構造化出力モードは、スキーマの遵守を向上させるように設計されていますが、通常は JSON スキーマのサブセットのみをサポートします。
- ツール呼び出しは、通常、自由形式の JSON よりもアクションに適しています。これは、モデルが宣言されたツールを選択して構造化引数を返し、アプリケーションが実行の責任を負うためです。
- プロバイダーが異なれば、公開されるコントラクトも異なります。厳密な JSON スキーマ応答形式を使用する場合もあれば、ツール入力スキーマを使用する場合もあり、検証と再試行のフォールバックを必要とする場合もあります。
- スキーマが有効な出力であっても、データベース、ワークフロー、有料アクションに到達する前に意味的に間違っている可能性があります。
アーキテクチャ上の意味は単純です。OpenAI 互換 API はクライアント インターフェイスを標準化できますが、信頼性レイヤーは依然としてプロバイダーの機能を理解し、生成後の出力を検証する必要があります。
推奨アーキテクチャ: 構造化出力アダプター
アプリケーション コードとプロバイダー API の間でゲートウェイ側アダプターを使用します。アプリケーションは 1 つのスキーマ インテントを送信します。ゲートウェイは、そのインテントをサポートされている最も強力なプロバイダー メカニズムにマッピングします。
1.アプリケーションから正規化されたリクエストを 1 つ受け入れる
クライアントは、プロバイダーごとに個別のコード パスを必要とする必要はありません。実際のリクエスト エンベロープには、モデル設定、タスク入力、スキーマ、スキーマ メタデータ、リスク レベルが含まれます。
{
"モデル": "自動:正確",
「メッセージ」: [
{"role": "system", "content": "請求書のフィールドを抽出します。欠損値を推測しません。"},
{"役割": "ユーザー", "コンテンツ": "請求書のテキスト..."}
]、
"構造化出力": {
"schema_id": "請求書抽出",
"スキーマ_バージョン": "2026-08-01",
"モード": "json_schema",
"厳密": true、
「スキーマ」: {
"タイプ": "オブジェクト",
"追加プロパティ": false、
"必須": ["請求書番号", "ベンダー名", "合計", "通貨", "期限日"],
"プロパティ": {
"請求書番号": {"タイプ": "文字列"},
"ベンダー名": {"タイプ": "文字列"},
"合計": {"タイプ": "数値", "最小": 0},
"通貨": {"タイプ": "文字列", "列挙型": ["USD", "EUR", "GBP"]},
"due_date": {"type": "string", "format": "date"},
"信頼度": {"タイプ": "数値"、"最小": 0、"最大": 1}
}
}
}、
「メタデータ」: {
"ワークフロー": "支払い可能なアカウント",
"リスクレベル": "中"
}
}
このコントラクトは、プロバイダー ネイティブの実装を選択し、検証を実行し、意味のある障害データをログに記録するために十分な情報をゲートウェイに提供します。
2.プロバイダーの機能マトリックスを維持する
ゲートウェイは、「すべての OpenAI 互換モデルが同じスキーマ動作をサポートする」などの前提に依存するのではなく、機械可読な機能マトリックスを保持する必要があります。有用なマトリックスには次のものがあります。
- プロバイダーとモデル名。
- JSON モードをサポートします。
- JSON スキーマ応答形式をサポートします。
- ツール呼び出しをサポートします。
- 厳密なスキーマ モードをサポートします。
- 既知の JSON スキーマ サブセットの制限事項。
- 並列ツール呼び出しが厳密スキーマ モードと互換性があるかどうか。
- 要求されたモードがサポートされていない場合のフォールバック動作
能力レコードの例:
{
"プロバイダー": "プロバイダー_a",
"モデル": "モデル_x",
"json_mode": true、
"json_schema_response": true、
"tool_calls": true、
"strict_schema": true、
"schema_limitations": ["no oneOf", "限定された形式検証"],
"フォールバック": "互換モデルへの拒否またはルート"
}
このマトリックスはバージョン管理してテストする必要があります。プロバイダーが動作を変更する場合、または新しいモデルが追加される場合は、運用ルーティングの前に構造化出力の互換性を検証する必要があります。
3.最強のプロバイダネイティブ契約に変換
アダプターは明確な優先順位に従う必要があります。
<オル>リスクの高い操作を厳密なスキーマ モードから「ベスト エフォート JSON」にサイレントにダウングレードしないでください。アプリケーションが厳密な動作を要求し、選択されたプロバイダーがそれをサポートできない場合、ゲートウェイはエラー、ルーティング決定、または明示的なダウングレード フラグを通じてそれを可視化する必要があります。
実行前の 3 つの検証層
レイヤー 1: 解析検証
まず、応答を予想されるエンベロープに解析できるかどうかを判断します。契約で禁止されている場合、不正な JSON、ツール呼び出しブロックの欠落、切り捨てられた応答、または自然言語と JSON の混合に対してフェイルファストを実行します。
関数 parseStructuredResponse(raw) {
{を試してください
return { ok: true、値: JSON.parse(raw) };
} キャッチ (エラー) {
return { ok: false、failure_type: "parse_failure"、error: String(error) };
}
}
プロバイダー ネイティブ ツールの呼び出しでは、生のテキスト BLOB の解析は必要ないかもしれませんが、それでもエンベロープ検証が必要です。つまり、モデルは既知のツールを選択したか、引数を提供したか、予想どおりツールの実行のために停止したか?
レイヤー 2: JSON スキーマの検証
次に、サーバー側バリデータを使用して、宣言されたスキーマに対してオブジェクトを検証します。プロバイダーが厳密なスキーマのサポートを主張している場合でも、これを実行してください。ゲートウェイ側の検証により、一貫した障害ログが得られ、統合ミスから保護され、ダウンストリームの非互換性が検出されます。
const validate = schemaValidator.compile(スキーマ);
const valid = validate(オブジェクト);
if (!有効) {
戻り値 {
OK: 偽、
失敗タイプ: "スキーマ失敗",
エラー: validate.errors
};
}
移植性を高めるために、共通のサブセットを念頭に置いてスキーマを設計します。
- 明示的な
type、required、properties、enum、およびAdditionalProperties: falseを優先します。 - 対象プロバイダがサポートしていることがわかっていない限り、深くネストされた
oneOf、anyOf、条件付きスキーマなどの複雑な組み合わせは避けてください。 - アクションに関する議論は小さく、具体的なものにしてください。
- ダウンストリーム システムで別のタイプが必要な場合を除き、ID、日付、コードには文字列を使用します。
confidence、missing_fields、requires_human_reviewなどのフィールドを使用して、不確実性を明示的に表します。
レイヤー 3: セマンティックおよびビジネスの検証
最後に、構造化された結果がタスクに対して正しいかどうかを検証します。このレイヤーはドメイン固有であり、JSON スキーマのみにアウトソーシングすることはできません。
請求書抽出の場合、セマンティック チェックには次のものが含まれる場合があります。
- 合計は負ではなく、許容範囲内で広告申込情報と一致します。
- 通貨はソースドキュメントに表示されます。
- 期日は、ありえないほど過去または未来ではありません。
- ベンダーは承認されたベンダー リストに存在します。
- 信頼度は自動エントリに十分なほど高いです。
リードの適格性を確認するために、次のようなチェックが行われる場合があります。
- 選択したセグメントは、営業チームのアクティブなセグメントの 1 つです。
- ユーザーが予算を指定しなかった場合、リクエストされた予算は作成されません。
- 「ブックデモ」アクションは、ユーザーが明示的に要求しない限り実行されません。
パートナー API 自動化の場合、次のようなチェックが行われる可能性があります。
- リセラー アカウントには、要求された顧客またはキーを作成する権限が与えられています。
- リクエストされた支出制限はパートナー ポリシーの範囲内です。
- オペレーションにはべき等キーがあります。
- アクションは実行前に監査ログに記録されます。
ツール呼び出し: モデル出力を実行ではなくリクエストとして扱います
ツール呼び出しは、モデルがアプリケーションに何かを要求する必要がある場合に適切なパターンです。チケットの作成、Telegram ボット コマンドの送信、価格設定の検索、顧客レコードの更新、ワークフローの開始などです。
安全なツール ループは次のようになります:
<オル>ツールの呼び出しを、アクションが発生するはずであるという証拠として扱わないでください。構造化された提案として扱います。副作用に対する権限は引き続きアプリケーションにあります。
マルチモデル ワークフロー向けの安全なフォールバック ラダー
ゲートウェイは、インシデントが発生する前にフォールバック動作を定義する必要があります。実際のはしごは次のとおりです。
<オル>再試行は、フォーマットや軽度のスキーマの失敗に役立ちますが、安全戦略ではありません。オブジェクトが意味的に安全でない場合、プロンプトを繰り返すと、正しい拒否が危険な実行可能オブジェクトに変わる可能性があります。リスクの高いアクションの場合は、強制的に成功を試みる試みを繰り返すよりも、レビューまたは拒否を優先します。
可観測性: 構造化された出力決定をすべてログに記録します
構造化出力の障害は動作信号です。不必要な機密コンテンツを公開することなく、ルーティング、スキーマ、プロンプトを改善するために、十分な詳細を記録してください。
推奨されるフィールド:
schema_idとschema_version。- プロバイダーとモデル。
- 要求されたモードと実際に使用されるモード。
- 解析失敗ステータス。
- スキーマ障害ステータスと検証エラー
- セマンティック検証が失敗した理由。
- 再試行回数。
- レイテンシ。
- トークンの使用量とコスト
- 最終的なアクションのステータス: 実行、キューに登録、拒否、またはユーザーに返されました。
- チーム、プロジェクト、API キー、またはパートナー アカウント識別子(該当する場合)
これらのログは、デバッグ、コスト分析、プロバイダーの比較、チーム API ガバナンスをサポートします。また、「最も多くの再試行が発生するスキーマ バージョンはどれですか?」などの質問に答えるのにも役立ちます。および「構文はパスしますが、ビジネス検証に失敗するフォールバック モデルはどれですか?」
スキーマのバージョン管理ルール
スキーマは実稼働インターフェースです。 API コントラクトのように扱います。
- リクエストのメタデータとログに
schema_idとschema_versionを含めます。 - 既存のオートメーションの必須フィールドをサイレントに変更しないでください。
- クライアントの移行中も古いスキーマを利用可能な状態に保ちます。
- 必須にする前に、新しいオプションのフィールドを追加します。
- ルーティング プール内のすべてのプロバイダとフォールバック モデルに対してスキーマをテストする
- 副作用のあるアクションごとにどのスキーマ バージョンが使用されたかを記録します。
バージョン管理は、多くの下流顧客が安定した構造化された契約に依存している可能性がある代理店、再販業者、パートナー API 自動化にとって特に重要になります。
構造化された結果を実行しない場合
次のいずれかの状況が発生した場合は、ハード ストップを使用してください。
- 応答は解析できません。
- オブジェクトは JSON スキーマの検証に失敗します。
- 列挙値はサポートされていないか、作成されたものです。
- 数量、価格、日付、通貨は不可能です。
- 結果はユーザーが述べた意図と矛盾します。
- モデルは信頼性が低いか、証拠が欠けていることを示しています。
- ユーザーの指示があいまいです。
- このアクションには副作用があり、確認が不足しています。
- アカウント、チーム、または API キーが承認されていません。
- プロバイダーの応答には、拒否または安全関連の無応答が含まれます。
推奨と予測
推奨事項: 可能な場合はプロバイダー ネイティブの構造化出力を使用し、すべての応答をゲートウェイ側で検証し、アクションのツール呼び出しを優先し、機能マトリックス、バージョン スキーマを維持し、セマンティック チェックに合格するまで副作用をブロックします。
予測: 構造化出力に対するプロバイダーのサポートはより強化され、より一貫性のあるものになる可能性がありますが、モデル ファミリ、スキーマ サブセット、ツール呼び出しループは一夜にして同一になるわけではないため、移植性は引き続きゲートウェイの懸念事項となります。検証、可観測性、スキーマのバージョン管理を構築するチームは、すべてのワークフローを書き直すことなく、新しいプロバイダーの機能を採用できるようになります。
実用的な実装チェックリスト
<オル>実際的な目標は、すべてのモデルを同じように動作させることではありません。これは、ゲートウェイがプロバイダーの違いを正直に処理しながら、アプリケーション開発者に 1 つの安定した契約を提供するためです。構造化された出力は、信頼性の高い AI 自動化に必要なインフラストラクチャですが、運用境界は、オブジェクトが安全に使用できるかどうかを決定するバリデータ層とポリシー層です。