05 / 10 · SYSTEM DESIGN

ツール実行:モデルの提案を権限のある操作へ変える

型検証、認可、冪等性、照合から外部操作の境界を設計する。

内容の確認日:

この章で考える問い

AIに外部操作を任せるとき、誰が何を許可し、失敗をどう確かめるか?

まず図全体の流れを見て、細部は「原寸で読む」を開いて確認してください。原寸の図は横にスクロールできます。正常な流れの次に、失敗時の分岐を追いましょう。

ツール呼び出しは権限の委譲ではない

ツールは、モデルの文章を検索、ファイル操作、予約などの外部機能へ接続します。モデルがJSONを出力できても、その利用者に操作権限があるとは限りません。ツール設計では、引数の妥当性、実行の許可、操作の成否をそれぞれ判断します。この章は独自の参照設計であり、Kumyuの実装済み機能ではありません。

守る条件は「利用者が触れられる資源だけを操作する」「同じ操作の再試行で副作用を増やさない」「成否不明を成功と表示しない」の三つです。ツールの説明文に禁止事項を書くだけでは、この条件を実装したことになりません。権限を持つサーバーが毎回検査する必要があります。

全体像:提案、検査、実行を分離する

モデルの操作提案をサーバーが型検証・認可・必要な承認へ通し、外部 API を実行して結果を記録する
原寸で読む(横にスクロール)
モデルの操作提案をサーバーが型検証・認可・必要な承認へ通し、外部 API を実行して結果を記録する
図1:ツールを囲む信頼境界 原寸の図を開く ↗

図1は独自の概念図です。モデルから届く矢印は実行命令ではなく未信頼の提案として読みます。サーバーは許可したツールの名前だけを受け付け、スキーマ、文字列長、列挙値、対象資源の所有権を調べます。利用者IDをモデルの引数から採用せず、認証済みの実行コンテキストから結び付けます。

MCP 2025-06-18のTools仕様はツール名、入力スキーマ、tools/listとtools/callの形を定めています。これは通信上の契約であって、アプリケーション固有の認可を代行するものではありません。仕様中のannotationも外部から来る説明情報として扱い、それだけで安全性を決めません。

読み取りと書き込みでは危険の形が違います。読み取りでも秘密の外部送信が起き得ます。書き込みでは取り消せるか、相手に届くか、金銭や権限を変更するかを分類し、必要な確認と監査を決めます。ガードレールはこの実行境界にも置きます。

状態と操作ID:確認した内容を固定する

提案内容を正規化して確認対象を固定し、操作IDを記録してから実行し、外部の結果と照合する
原寸で読む(横にスクロール)
提案内容を正規化して確認対象を固定し、操作IDを記録してから実行し、外部の結果と照合する
図2:提案から確定結果まで 原寸の図を開く ↗

図2の順序はproposed → validated → approved → executing → succeededを基本とし、failedとunknownを分けます。承認が不要な操作はポリシーの判定記録でapprovedへ進めます。人の確認が必要なら、対象、本文、宛先等を見せ、その内容のハッシュへ承認を結び付けます。確認後の引数変更は再検査します。

{
  "operation_id": "op-example",
  "tool": "create_calendar_event",
  "arguments_hash": "example-digest",
  "actor_id": "user-example",
  "resource_id": "calendar-example",
  "state": "executing",
  "external_reference": null
}

これは未実行の設計例です。operation_idは利用者が意図した一回の業務操作、ツール呼び出しの通信IDは一回の通信を識別します。再試行で通信IDが変わっても、同じ業務操作ならoperation_idを維持します。DBには操作キーの一意性を持たせます。一意制約はローカル記録の重複を防げるが、外部 API の実行まで一つのトランザクションにはできません。

障害:タイムアウトは失敗を意味しない

外部 API で操作が成功した後に応答が消失し、成否不明状態から照会・照合して確定する
原寸で読む(横にスクロール)
外部 API で操作が成功した後に応答が消失し、成否不明状態から照会・照合して確定する
図3:成否不明を照合で回復する 原寸の図を開く ↗

図3では「予約は作成されたが、返答が届かなかった」状況を示します。タイムアウトをfailedとして自動再実行すると二重予約になります。AWSの再試行解説が指摘するように、応答がないことと副作用がないことは同じではありません。

外部 API が冪等キーを受け付ける場合は、operation_idをその契約に合わせて送ります。適用範囲や保持期間、異なる引数を再送した場合の扱いも確認します。キーが使えない場合は外部参照IDや業務キーで照会します。それもできない操作は成否不明で止め、人による照合へ回します。再試行の便利さより、二重反映を避ける条件を先に決めます。

補償操作はロールバックではありません。予約の取消通知が相手へ届くなら「最初から何もなかった」状態には戻りません。実行済みの作用、補償の結果、利用者への説明を別に記録します。ツール結果の文章に次の操作命令が含まれても、それを権限の根拠にしてはいけません。結果は入力データとして取り込み、次の操作も同じ検査経路へ通します。

選択肢を比較する

実行方式 得られること 引き受ける課題
読み取り専用 外部状態の変更を抑える 情報流出と取得権限は残る
ポリシー内の自動実行 定型業務を速く処理 範囲の定義と監査が必要
内容確認後の実行 利用者が対象を確認できる 確認後の変更と期限を管理
非同期の実行台帳 長時間処理を追跡できる 成否不明の照合担当が必要

設計例:会議予定を一件作る

利用者が指定したカレンダーへ、参加者と時刻を固定して予定を作ります。サーバーがカレンダーの書き込み権限、時刻形式、終了が開始より後であることを調べます。確認画面には参加者への通知が起きることも含めます。承認済みハッシュと実行引数が一致したら、台帳を作って外部 API を呼びます。

二つのタブから同じ操作が届いても、操作キーで一つの台帳へ収束させます。外部 API を呼べるのは、台帳をapprovedからexecutingへ条件付きで更新し、実行権を取得した呼び出しだけです。更新できなかった呼び出しは既存操作の状態を参照し、外部 API を再実行しません。外部 API の冪等性がないなら、台帳だけでは完全な重複防止になりません。実行前後のクラッシュ窓を認め、成否不明への照合手順まで用意します。監視はツール名別の成否、成否不明の年齢、権限拒否、予算超過を見ます。機密の引数本文をログへ丸ごと保存しません。

練習と解答

モデルが「失敗したから同じ送信をもう一度」と提案しました。最初の呼び出しはタイムアウトし、外部の実行結果は未確認です。提案どおり再実行してよいでしょうか。

まず台帳を成否不明にし、外部の冪等キーまたは照会手段を確認します。結果が確定してから成功表示または安全な再試行へ進みます。モデルの判断は外部の事実確認を代替しません。型、権限、業務操作の同一性、外部成否を分けて説明できる設計が必要です。

押さえたいポイント

モデルが引数を提案し、サーバーが権限と実行条件を決める。

出典・さらに読む

  1. MCP 2025-06-18: Tools内容の確認日: 2026-10-23
  2. AWS: Timeouts, retries, and backoff with jitter内容の確認日: 2026-10-23
  3. PostgreSQL 18: Constraints内容の確認日: 2026-10-23

学習と設計検討のための概念的な構成例です。稼働中のKumyuの実装を表す図ではありません。

← 全章の一覧へ