症状: 会話はできるのに、ツール引数が検証で落ちる、再試行で注文が二重になる、MCPサーバーは起動しているのにツールが見えない。
最短の対処: JSONをモデルとツールの唯一の契約にする。入力は JSON Schema で縛り、結果は固定フィールドで返し、その契約をプロセスをまたいで発見できるようにするのが MCP です。
対象は、大規模言語モデルを実システムへつなぐ開発者、基盤担当、アーキテクトです。新しい用語を覚えることより、同じ JSON が Function Calling、Tool Calling、MCP のどこを流れ、どの段で止まるかを見極めることが先です。
フレームワーク選定が先なら AI Agent開発フレームワークの選び方 を先に読んでください。ツール実行時の隔離は AI SandboxとDocker、仮想ファイルシステムの比較 も参照できます。
AI Agent が JSON なしでは成立しない理由
モデルは自然言語を生成します。本番システムが受け取るのは構造化コマンドです。在庫照会、チケット更新、テスト実行、ブラウザ操作が必要になった瞬間、「意図」は検証・拒否・監査できるデータにならなければなりません。JSON はその隙間に収まります。人が読め、機械がパースでき、HTTP・ログ・キュー・データベースがすでに扱えます。
本質は検証可能性です。散文はゲートウェイに「order_id は文字列、amount は正の数、currency は列挙」と伝えられません。JSON Schema は伝えられます。OpenAI の Function Calling 案内は、関数パラメータを JSON Schema で定義し、サンプリング時点で合法な構造へ寄せます。OpenAI Function Calling ガイドを見る
型、必須、enum、additionalProperties は学術的な細部ではありません。モデルがフィールドを捏造したり、文字列を数値に押し込めたり、冪等キーを落とすのを止める最初の門です。JSON Schema の説明を見る
層は三つです。
- 対話層:ユーザーが「上海倉庫のあの注文を急行にして」と言う。
- 契約層:モデルが
{"name":"update_order","arguments":{"order_id":"A938","priority":"expedited"}}を出す。 - 実行層:スキーマ検証、権限確認、業務 API、結果 JSON をモデルへ戻す。
契約層が無ければ Agent はチャット窓です。あれば統治可能な実行器になり得ます。
⚠️ 現場の判断:引数をまだ「自由文+正規表現」で抜いているなら、プロトコルは無くプロンプト運だけです。スキーマを固めてから多ツール編成に進んでください。
Function Calling:モデルがフォームを埋める
Function Calling の本体は、ユーザーへ答える前に宣言済み関数を呼ぶか決め、スキーマに合う引数を出すことです。流れは五段で、各段でフィールドが落ちます。
- 登録:リクエストに name、description、JSON Schema の parameters を載せる。
- 判断:関数を呼ぶか、直接答えるか。
- 記入:tool_calls。arguments は JSON 文字列またはオブジェクト。
- 実行:パース、検証、認可、実システム呼び出し。
- 再注入:ツール結果を返し、モデルが最終回答を書く。
description は宣伝文ではなくルーティング信号です。「天気を調べる」と「配送を調べる」が衝突します。「都市名があるときだけ現在気温を取る。気候の歴史には使わない」と書けば誤発火が減ります。スキーマ内のフィールド説明もプロンプトなので、「order_id は業務注文番号であり決済 ID ではない」はシステムプロンプトだけに置かないでください。
strict / Structured Outputs は「JSON っぽい」を「スキーマ一致」に上げます。JSON mode は括弧がパースできることしか保証しません。欠落や型違いは通ります。スキーマ合法は業務合法ではありません。負の金額、存在しない倉庫、権限外の注文はアプリ側で落とします。
最小の実行可能な契約
次のスキーマは列挙と冪等キーを固定します。呼ばない選択はできますが、余分な倉庫フィールドの発明や idempotency_key の省略はできません。
{
"type": "function",
"name": "update_shipment",
"description": "配送優先度の変更をユーザーが明示したときだけ呼ぶ。",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"order_id": {"type": "string", "description": "業務注文番号"},
"priority": {"type": "string", "enum": ["standard", "expedited"]},
"idempotency_key": {"type": "string"}
},
"required": ["order_id", "priority", "idempotency_key"],
"additionalProperties": false
}
}
実行順は JSON parse → スキーマ検証 → 権限 → 冪等表 → 業務 API → {"ok":true,"shipment_id":"..."} または {"ok":false,"error":"not_found"}。スタックトレースや秘密情報を tool result に入れないでください。
Tool Calling:関数からツール平面へ
必要なのは自前関数だけではありません。検索、コード実行、ブラウザ、コンピュータ操作、ファイル検索もツールです。API は初期の function_call から統一の tools / Tool Calling へ進みました。名前は変わり、JSON 契約は name + schema + 呼び出し記録 + 結果返却のままです。
Anthropic は Tool use と呼び、input_schema を JSON Schema で表します。モデルは tool_use ブロックで構造化引数を返し、アプリは tool_result で返します。Anthropic Tool use ドキュメントを見る
エンジニアリング上の新しい問題も、JSON で運びます。
- 並列呼び出し:読み取りは並列、在庫ロックと課金は直列。
- 承認:高リスクツールは実行せず pending の JSON を返す。
- 観測:trace にツール名、引数要約、レイテンシ、エラーコードを残す。
失敗の形も変わります。正しいツールを選んでも、文字列フィールドに危険なペイロードを隠せます。型はスキーマで防げますが意味攻撃は防げません。危険なツールは許可リスト、タイムアウト、サンドボックスが必須です。
MCP:JSON 契約を差し込み可能にする
Function / Tool Calling は一回の API リクエスト内の会話です。MCP はツールの発見、複数ホストでの再利用、別プロセスでの実行です。仕様は JSON-RPC 2.0 で initialize、tools/resources/prompts の一覧、呼び出し、通知を運びます。MCP 仕様を見る
- IDE や Agent ランタイムが MCP Client として起動する。
- stdio、SSE、Streamable HTTP で Server に接続する。
initializeで版と能力を交渉する。tools/listで inputSchema(依然 JSON Schema)付きの一覧を得る。- モデルは Tool Calling のまま。MCP ツールなら Client が JSON 引数で
tools/callする。 - Server の content を tool result にしてモデルへ戻す。
MCP は JSON を置き換えません。アプリに直書きしていた tools 配列を実行時カタログにします。同じ Git、同じブラウザ自動化、同じチケット API を、Cursor や Claude Desktop、自作 Agent が共有できます。
「入れたのにツールが見えない」はほぼ契約障害です。initialize 失敗、list が空、strict 非互換、required 欠落、JSON-RPC error の代わりの自然文エラーです。
一連の流れ:一文から MCP 実行まで
- ユーザーが自然言語を入れる。
- ランタイムが messages、ローカル tools、MCP
tools/listを組み立てる。 - モデルが Tool Calling で JSON 引数を出す。
- ローカル関数か JSON-RPC
tools/callへ分岐する。 - 結果 JSON(または MCP content)が会話に戻る。
- 再呼び出し、ユーザー確認、最終回答のいずれか。
見落としやすい境界:モデルはデータベース接続を持ちません。出すのは JSON だけです。誰がパースし、どのマシンで実行し、SSH や VNC を使うか、外向き通信を許すかはランタイム方針です。クラウド Mac 上の Agent / MCP Server もプロトコルは同じで、権限平面が違います。
| 層 | JSON の役割 | 止めるべき地点 |
|---|---|---|
| Function Calling | 一回の関数引数 | schema、strict、業務検証 |
| Tool Calling | 共通平面の呼び出し記録 | 並列、承認、trace |
| MCP | プロセスをまたぐ発見と呼び出し | 伝送、認証、list/call エラー |
製品名に引っ張られないでください。一つのアプリ専用なら Function/Tool Calling で足ります。複数ホストで再利用するなら MCP Server の価値が出ます。スキーマも検証も無いまま MCP を足すと、混乱が別プロセスへ移るだけです。
JSON が壊れると Agent 全体が壊れる
- 合法 JSON でない:strict オフ、先に説明を書けという指示、Markdown フェンス。構造化ツール経路だけを使い、散文から引数を抜かない。
- パースできるがスキーマ違反:required 欠落、enum 誤り、余分なプロパティ。検証エラーを tool result で返し、再試行回数を制限する。
- スキーマは通るが業務失敗:注文なし、在庫不足、権限拒否。安定した error code を返す。
- 再試行で二重書き込み:timeout のあと再呼び出し。idempotency_key と実行側の重複排除。
- list と call の不一致:名前やスキーマがホットリロードで変わった。名前とスキーマハッシュを版管理し、変更時は initialize し直す。
- 機密が JSON ログへ:共有 trace にフル引数。フィールド名とハッシュだけ残し、トークンと個人情報を伏せる。
タイムアウト、スキーマ失敗、権限拒否を一つの受入シナリオにしてください。無限再試行や引数の勝手な改変が残るなら、決済・出荷・本番 DB には繋がないでください。
公開前の JSON 契約チェックリスト
- [ ] 各ツールに name、description、JSON Schema、
additionalProperties: falseがある。 - [ ] 高リスク欄は enum / format / 最大長で、自由文字列にしない。
- [ ] 書き込みは冪等キー付き。timeout と再試行はランタイムに置く。
- [ ] tool result は
ok/error/data。スタック原文は禁止。 - [ ] 副作用で並列を分ける。決済・メール・削除は原則直列。
- [ ] MCP の initialize / list / call に timeout、認証、エラーコードがある。
- [ ] カタログ変更後にホストがスキーマを再取得する。
- [ ] trace は呼び出し連鎖を復元でき、秘密は復元できない。
- [ ] 固定入力は同じツール名と同じ必須フィールド集合に当たる。
これが通ってから多 Agent や重いワークフローを検討してください。不安定なプロトコルは壊れた JSON を速く複製するだけです。
FAQ
なぜ自然言語のままプログラムに読ませないのか
必須フィールドも型もありません。「急いで」を列挙値へ安定対応できず、余分なフィールドも拒否できません。JSON Schema はパースを検証に変え、失敗を構造化して返せます。
Function Calling と Tool Calling は実質違うのか
アプリ開発者から見ると「JSON のフォームを埋めてコードが実行する」点は同じです。Tool Calling は検索やコード実行などホストツール、並列呼び出し、統一の結果チャネルが広いです。移行ではスキーマとメッセージ役割を先に揃え、古いフィールド名で止まらないでください。
いつ MCP が必要で、いつ配列直書きで足りるのか
同じツールを複数ホストが使う、別プロセスで隔離する、別チームが配布する、というときに MCP が引き合います。一つの内部サービスと寿命を共にするなら Function/Tool Calling の方が単純です。
たまに壊れた JSON が出る。再試行か、プロトコル変更か
まず厳密な構造化出力を有効化し、散文から引数抽出をやめます。頻度が高ければスキーマの深さ、説明の衝突、ツール数を疑います。MCP に替えても引数は JSON のままなので、根は消えません。
共有ノート PC で Agent を動かしていると、環境が変わるたびにスキーマ回帰が壊れ、MCP プロセスが開発用ポートと衝突します。Kvmjet のベアメタル Mac クラウドなら macOS イメージを固定し、SSH または VNC で同じ Tool Calling / MCP 失敗を再現できます。公開情報では日次から四半期までの課金があり、契約を安定させてから長期利用を決められます。
チェックリストを持って Kvmjet ヘルプセンター で常時稼働、権限分離、遠隔接続を確認し、MCP Server をノート、ラック、クラウド Mac のどこに置くか決めてください。
Tool Calling と MCP を固定 Mac 環境で回す
スキーマ、冪等キー、MCP Server は再現可能なランタイムが前提です。共有ノートではディレクトリとポートがすぐ漂流します。
Kvmjet のベアメタル M4 Mac は本物の macOS と SSH/VNC を備え、同じ tools/call 失敗を何度でも再現できます。