症状:JSONは解析できるのに、ツール呼び出しやMCP連携が失敗する。
最短解決:構文、Schema、権限、呼び出しID、結果形式を別々に検証し、同じイベントIDでログを追跡してください。
この方法は、AI AgentのJSONデータフローを本番運用し、複数のツールやAPIを継続的に接続する場合に有効です。JSONは推論を実行する仕組みではなく、モデル、アプリケーション、実行器、プロトコルの間で機械データを運ぶ共通形式です。
この解説を読むべき人
Agent開発者は、Function Callingで生成された引数がどこで実行されるのかを整理できます。
障害対応を担当するエンジニアは、パラメーター、権限、状態、結果のどこで失敗したかを切り分けられます。
プラットフォーム設計者は、Schemaの版管理と統一イベントログを設計する材料を得られます。
まず理解したい、AI AgentのJSONデータフロー
典型的な呼び出しは、次の順で進みます。
- ユーザーの依頼をモデルへ渡す。
- モデルが利用可能なツールから候補を選び、名前と引数をJSON形式で返す。
- オーケストレーターがJSONを解析し、Schemaと業務ルールを検証する。
- 実行器が認証、認可、リソース状態、ネットワークを確認してAPIやローカル処理を実行する。
- 実行結果を呼び出しIDとともにモデルへ返し、最終回答を生成する。
ここで重要なのは、モデルが関数を実行しているわけではない点です。GoogleのFunction Calling仕様でも、モデルは関数名と引数を返し、実行はアプリケーション側の責任とされています。Function Callingの公式フロー
AI AgentがJSONを普遍的に使う理由は何ですか?
JSONは、人間向け文章よりもキー、値、配列、型を明確に扱えるためです。ただし、JSONとして解析できることは「正しいデータである」ことを意味しません。{"user_id": 123} は構文上有効でも、Schemaが文字列を要求していれば不合格です。
そのため、JSONを次の責任範囲に分けて考える必要があります。
- モデル生成:ツールを選び、引数を組み立てる
- アプリケーション実行:引数を検証し、処理を開始する
- プロトコル伝送:呼び出しIDや結果を正しい相手へ渡す
- 業務検証:権限、状態、金額、対象リソースを確認する
JSONが正しくても失敗する4つの境界
Schemaに合わないJSONは、解析できても使えません
最初に確認するのは、JSONの構文ではなくSchemaとの一致です。よくある差異は、必須フィールドの欠落、数値と文字列の取り違え、列挙値の範囲外、想定外フィールドの混入です。
OpenAIの公式仕様では、Function Callingの引数にJSON Schemaを設定でき、strictを有効にすると定義したSchemaへの厳格な準拠を要求できます。ただし、対応するSchema機能には制限があります。Function Callingとstrict指定の仕様
GeminiのStructured OutputもJSON Schemaのサブセットを採用しています。つまり、あるプラットフォームで受理されたSchemaが、別のプラットフォームで同じように動くとは限りません。GeminiのSchema対応範囲
JSONが合法なのにAgentが失敗するのはなぜですか?
構文検証は入口にすぎないからです。Schema検証、業務ルール検証、権限確認のいずれかで拒否されれば、実行は開始されません。エラーを単に「失敗」と返すのではなく、validation_error、authorization_denied、resource_state_errorのような構造化されたエラーとして返してください。モデルに曖昧な失敗理由を推測させると、再試行の方向を誤ります。
Schemaに合っていても、ツール選択を間違えることがあります
引数が正しくても、そもそも不適切なツールが選ばれていれば処理は失敗します。例えば、読み取り専用のツールと削除用ツールの説明が似ていると、モデルはSchemaではなくツールの意味を誤解する可能性があります。
改善策は、型を過度に厳しくすることではありません。
- ツール名に動作と対象を含める
- 説明文に「使う条件」と「使わない条件」を書く
- 1回の依頼で渡す候補ツールを絞る
- 破壊的操作には確認用の前段ツールを置く
- 現在のタスク状態をコンテキストへ明示する
Function Callingは、モデルが候補から関数を選ぶ仕組みです。したがって、選択品質はフィールド型だけでなく、ツール説明、候補数、会話履歴にも左右されます。
引数が正しくても、APIの実行器が拒否します
認証トークンの期限切れ、権限不足、対象リソースの状態、レート制限、ネットワーク障害、業務上の上限などは、JSON Schemaでは表現しきれません。
実行器では、少なくとも次の順で確認してください。
- 認証情報が存在し、期限内か確認する。
- 呼び出し元が対象操作を許可されているか確認する。
- 対象リソースが操作可能な状態か確認する。
- 外部APIの応答コードと本文を保存する。
- 再試行可能か、即時停止すべきかを分類する。
ここでAPIの生エラーをそのままモデルへ渡すのは危険です。実行器が「認証失敗」「権限不足」「対象なし」「一時的障害」を構造化して返せば、Agentは再認証、確認要求、別ツールへの切り替えを判断しやすくなります。
呼び出しIDと履歴を失うと、どの処理が壊れるのか
ツールの結果は、どの呼び出しに対する返答かを識別できなければなりません。並列実行で複数のツールを処理した場合、IDが欠落すると、天気情報を注文情報へ結び付けるような結果の取り違えが起きます。
OpenAIの仕様では、ツール呼び出しにIDが付与され、返却するツールメッセージには対応するtool_call_idが必要です。ツール呼び出しIDの公式仕様
GeminiのInteractions APIでも、関数結果を返す際に呼び出し元のcall_idと、前のやり取りを示すprevious_interaction_idを利用します。状態を保持しない方式では、ユーザー入力、モデルの呼び出し、実行結果を履歴へ正確に再送する必要があります。Geminiの状態管理と関数結果の返却
ツール呼び出しIDが失われると何が起きますか?
結果を正しい呼び出しへ結び付けられず、重複実行、結果の混線、再試行ループ、途中停止が起きます。ログには、request_id、conversation_id、tool_call_id、schema_versionを同時に保存してください。
| 検証対象 | 主な失敗 | 直す担当 | ログに残す値 |
|---|---|---|---|
| JSON構文 | 壊れた文字列、途中で切れた引数 | 受信処理 | 生データ、解析結果 |
| Input Schema | 必須項目、型、列挙値の不一致 | オーケストレーター | Schema版、検証エラー |
| 権限・業務ルール | 認証、認可、状態、上限 | 実行器 | 判定理由、API応答 |
| 呼び出し関連 | ID欠落、履歴不一致 | 状態管理 | call ID、親イベントID |
| Tool結果 | 出力Schema不一致、形式不足 | MCPクライアント | structuredContent、isError |
MCPの結果を下流で消費できない理由
Model Context Protocolでは、ツールの入力にinputSchema、出力に任意のoutputSchemaを定義できます。ツール結果はstructuredContentに構造化データを入れられ、isErrorで実行エラーを示せます。MCP Tools仕様
ただし、すべてのクライアントが同じ結果フィールドを同じ方法で扱うとは限りません。後方互換性のため、構造化結果を返すツールは、JSONをシリアライズしたテキストも併せて返すことが推奨されています。
MCPツールの結果は、どのようにモデルへ戻せばよいですか?
まず、toolUseIdまたは対応する呼び出しIDを維持します。次に、structuredContentを出力Schemaで検証し、モデルが読めるテキスト形式も保持します。エラーは通常のプロトコル障害と混同せず、ツール実行エラーとしてisErrorを付けて返します。MCP Schema仕様
MCPサーバー側でSchemaに適合させても、クライアントや下流の業務処理がそのフィールドを無視することがあります。受信側では「フィールドがあるか」だけでなく、「自分が解釈できる版か」まで確認してください。
第一歩:4種類の故障を再現してログを設計する
本番障害を偶然待つのではなく、次の順で再現テストを作ります。
- 必須フィールドを削除し、Schemaエラーを発生させる。
- 正しい型で存在しないリソースを指定し、業務エラーを発生させる。
- 権限のないトークンでAPIを呼び、認可拒否を確認する。
- 呼び出しIDを変更または削除し、結果の関連付けが失敗することを確認する。
- MCPの
structuredContentから必須項目を削除し、出力Schema検証を確認する。 - 各イベントを同一の相関IDで追跡し、最終回答まで欠落がないか確認する。
実装時は、モデルの出力だけでなく、実行器が受け取った引数、権限判定、APIの応答、MCP結果、最終的な業務検証結果を保存します。これにより「モデルが間違えた」のか、「アプリケーションが実行しなかった」のか、「プロトコルで結果を取り違えた」のかを分離できます。
運用環境にmacOS固有のコマンド、Xcode、シミュレーター、署名済みアプリなどが含まれる場合は、実行ログだけでなく、macOSのバージョン、依存関係、権限、プロセス状態も同じ相関IDで残してください。必要に応じて、Mac環境を使ったAgent検証の案内や日本向けMacレンタル環境を確認すると、環境差による再現漏れを抑えられます。
運用前に確認するチェックリスト
- [ ] モデル生成JSONを、構文とSchemaに分けて検証した
- [ ] ツール名と説明に、使用条件と禁止条件を記載した
- [ ] 認証、認可、リソース状態を実行器で検証した
- [ ] APIエラーを構造化し、再試行可否を分類した
- [ ] tool call IDと会話履歴を保存した
- [ ] 並列呼び出しの結果をID単位で結合した
- [ ] MCPの
inputSchemaとoutputSchemaを版管理した - [ ]
structuredContentと互換テキストの両方を扱えるようにした - [ ]
isErrorを通常の通信エラーと区別した - [ ] macOS依存のAgentでは、実行環境の状態もログへ紐付けた
JSONは、AI Agentの推論を代替する魔法の形式ではありません。モデルが選択し、アプリケーションが実行し、プロトコルが伝送し、業務システムが検証するための境界線です。その境界線ごとに検査点を置くことが、長い呼び出しループを安定させる最短ルートです。
現在の実行環境が共有サーバーや一時的なクラウド環境の場合、依存関係の差、権限設定の違い、ログ保存先の分散、macOS固有ツールへのアクセス制限が、JSONとは別の再現障害を生みます。継続的に跨層の故障を再現するチームなら、隔離されたログ、固定した依存関係、必要なmacOS環境を確保できる構成のほうが、原因調査の手戻りを抑えやすいです。短期の検証や一時的なAgent実行環境が必要なら、KvmzenのMacレンタル環境を候補に加え、必要な期間と接続方式を確認してください。
