AIエージェントの人間承認(Human-in-the-Loop)設計|どこに確認を置くかを影響範囲と取り消し可能性で決める

エージェントを実務に載せる段階で必ず出てくるのが、「どこで人が確認するか」という問いです。全部の操作に確認を求めれば安全に見えますが、実際には利用者が中身を読まずに承認を押すようになり、確認は形だけになります。逆に確認を置かなければ、モデルの誤判断やプロンプトインジェクションがそのまま実害に変わります。この記事では、人間承認(Human-in-the-Loop)を「置くか置かないか」の二択ではなく、影響範囲と取り消し可能性から置き場所と形を決める設計問題として整理します。入力・出力・挙動の3層をチェックするガードレールの話は あわせて読みたい LLMガードレールの設計|入力・出力・挙動の3層で安全境界をつくる実務ガイド
承認ゲートの目的は「止めること」ではない
承認ゲートを入れる目的は、エージェントの動きを遅くすることではなく、取り返しのつかない結果が出る手前に人の判断を1つ挟むことです。OWASPの生成AI向け脆弱性ランキングでは「過剰な代理性(Excessive Agency)」が独立した項目として置かれ、その根本原因を過剰な機能(excessive functionality)・過剰な権限(excessive permissions)・過剰な自律性(excessive autonomy)の3つに分解しています。緩和策として「影響の大きい操作の実行前に人の承認を必須にするヒューマン・イン・ザ・ループの制御を用いる」ことが挙げられており、例としてSNS投稿を行うアプリでは投稿処理そのものに承認ルーチンを組み込むべきだと述べられています。
同時にOWASPは、承認が権限管理の代わりにはならないとも指摘しています。「その操作が許されるかどうかをLLMに判断させるのではなく、下流のシステム側で認可を実装する」という原則が併記されており、人の承認は認可の上に重ねる層であって、認可の代替ではありません。ここを取り違えると、「人が押したのだから正しい」という運用に流れ、権限設計の甘さが承認画面で覆い隠されます。
Model Context Protocol(MCP)の仕様も、ツール実行の利用者インタラクションについて「信頼と安全のために、ツール呼び出しを拒否できる人間が常にループの中にいるべきである(SHOULD)」と明記し、どのツールが公開されているかを示すUI、ツール実行時の明確な視覚的表示、操作に対する確認プロンプトの提示を推奨しています。プロトコル自体は具体的なUIを規定しませんが、「拒否できる人がいる」ことを前提に置く設計思想は共通です。
メモ
どこに置くかを決める4つの判断軸
承認ゲートの置き場所を決めるとき、筆者が使っているのは次の4軸です。操作ごとにこの4つを評価し、合計の重さで承認の要否と形を決めます。
| 判断軸 | 問い | 重い側の例 | 軽い側の例 |
|---|---|---|---|
| 可逆性 | その操作は取り消せるか。取り消しにどれだけ手間がかかるか | 送金、外部へのメール送信、本番データの物理削除 | 下書き保存、ローカルファイルの編集(バージョン管理下) |
| 影響範囲 | 誤りが誰に届くか | 顧客・取引先・公開チャネル・本番DB | 自分だけ、検証環境、個人の作業ブランチ |
| 検知の遅れ | 間違いにいつ気づけるか | 月次の締めで発覚する会計処理、非同期のバッチ更新 | 即座に結果が返る検索、テストが落ちるコード変更 |
| 頻度 | 1日に何回発生するか | 1日数百回のチケット更新 | 週1回のリリース作業 |
可逆性と影響範囲は「失敗したときの被害の大きさ」を、検知の遅れは「被害が拡大する時間」を、頻度は「承認者の消耗」を表します。前の3つが重いほど承認ゲートを置く理由が強くなり、頻度が高いほど承認ゲートは形骸化しやすくなります。つまり、頻度が高くて影響も大きい操作は、承認を増やすのではなく設計を変える(権限を絞る、操作を分割する、一部を可逆にする)べき領域だという判定になります。
検知の遅れは見落とされがちですが重要です。コード生成のようにテストがすぐ落ちる領域は、間違いが数分で表面化するため事前承認の価値が相対的に下がります。逆に、外部システムへ非同期で反映される操作は、間違いが数日後に別部署から報告されるかたちで現れます。この差が、同じ「書き込み操作」でも承認の要否を分けます。
あわせて読みたい
AIエージェントとは何か|従来の自動化との違いと任せてよい仕事
介入の形は「事前承認」だけではない
人を挟むと言うとダイアログでの事前承認ばかりが想像されますが、実務では次の5類型を使い分けます。
| 類型 | 中身 | 向く場面 |
|---|---|---|
| 事前承認 | 実行前に止め、人が承認・却下する | 不可逆かつ影響が大きい操作。頻度が低いもの |
| ドライラン/プレビュー | 実行せずに「何が起きるか」の差分を提示し、人が確認してから適用する | 変更内容が構造化して見せられる操作(設定変更、一括更新) |
| 事後の取り消し | まず実行し、一定時間内なら取り消せる導線を用意する | 可逆で、待たせるコストのほうが高い操作 |
| サンプリング監査 | 全件は止めず、一定割合や条件に合致したものを抜き取って人が点検する | 高頻度・低単価の操作。品質のドリフト検知 |
| エスカレーション | 自信度が低い、条件を超えた、といった場合だけ人へ回す | 大半が定型で、例外だけ判断が要る業務 |
各社のフレームワークは、この類型のいくつかを機能として提供しています。OpenAIのAgents SDKでは、ツール定義にneedsApproval(Pythonではneeds_approval)を付けると、実行の代わりに承認の割り込みが記録され、結果としてinterruptionsと再開可能なstateが返ります。アプリ側が承認または却下したうえで、新しいユーザーターンを始めるのではなく同じstateから実行を再開する、という流れです。公式ドキュメントは、キャンセル・編集・シェルコマンド・機微なMCP操作といった副作用を伴う呼び出しに承認を推奨しています。
Microsoft Agent Frameworkでは、関数ツールごとにapproval_mode="always_require"を指定する(あるいは.NETではApprovalRequiredAIFunctionでラップする)ことで承認必須にでき、承認要求には呼び出される関数名と引数が含まれるため、それを利用者に提示して可否を決めさせる設計になっています。Amazon Bedrock Agentsのユーザー確認は、アクショングループの関数単位で有効化するオプトインの仕組みです。公式ドキュメントは「アクショングループを設定するときに、特定のアクションについてユーザー確認を有効にすることを選べる」と説明しており、明示的に有効化しない限り確認は求められません。有効にするとInvokeAgentのレスポンスにreturnControlとして呼び出し内容が返り、利用者のCONFIRM/DENYをconfirmationStateとして返送すると、CONFIRMのときだけ実行されます。AWSはこの機能の狙いを、悪意あるプロンプトインジェクションによる意図しない実行から守ることだと説明しています。
ドライランに近い形を持つのがClaude Agent SDKのplanモードです。公式ドキュメントによれば、このモードではClaudeがコードベースを調べて計画を作るだけでソースファイルを編集せず、ファイル編集は許可ルールに合致していても自動承認されずcanUseToolコールバックへ回されます。「案を先に見せ、適用は別判断にする」という介入の形が、モードとして製品に組み込まれている例です。
LangGraphではinterrupt()でグラフの実行を止め、Command(resume=...)で再開します。承認・編集・却下のいずれのパターンもこの仕組みの上に実装でき、状態の永続化にチェックポインタが必須である点が明記されています。承認待ちは秒単位で終わるとは限らないため、待っている間の状態をどこに置くかは設計上の論点になります。OpenAIのドキュメントも、レビューが後回しになる場合はstateをシリアライズして保存できると述べています。
ヒント
承認疲れと自動化バイアス
承認ゲートの最大の失敗モードは、突破されることではなく、形骸化することです。1日に何十回もダイアログが出れば、人は内容を読まずに承認を押すようになります。この現象は制度側でも認識されており、EU AI Actの第14条(人間による監督)は、高リスクAIシステムを、人間による監督を割り当てられた自然人が「高リスクAIシステムの出力に自動的に依存し、あるいは過度に依存してしまう傾向(自動化バイアス)がありうることを引き続き意識」できるような形で運用者へ提供することを求めています。名宛人は監督者本人ではなく、システムを提供する側である点に注意が必要です。同条は同じ建て付けで、状況に応じてシステムを使わない・出力を無視する・覆す・取り消すという判断ができること、そして安全な状態で停止させる「停止」ボタンや同等の手続きで介入・中断できることも、監督者が行えるようにすることを求めています。
注意
承認を減らす最短の道は、確認の回数を減らす工夫ではなく、そもそも承認が必要な操作の数を減らすことです。つまり権限スコープの絞り込みです。Claude Agent SDKのドキュメントは、閉じ込めたエージェントの構成例としてallowedTools: ["Read", "Glob", "Grep"]とpermissionMode: "dontAsk"の組み合わせを挙げています。列挙したツールだけが承認され、それ以外はプロンプトを出さずに拒否される構成です。読み取り系を既定にし、書き込みは限定したリソースにだけ許す、という形にできれば、承認ダイアログは「例外的に出るもの」になり、出たときに人が真面目に読むようになります。
同じドキュメントには、この設計で踏みやすい落とし穴も書かれています。自動承認されたツール呼び出しはcanUseToolコールバックに到達しないため、そこに置いた検査は静かに迂回されます。すべての呼び出しで必ず走らせたいチェックは、評価順の先頭にあるPreToolUseフックに置く必要があります。承認の設計は、どこで止めるかだけでなく、止める仕組みが確実に呼ばれる位置にあるかまで含めて検証すべきです。
人が判断できる情報を出す
「この操作を実行しますか?」という確認は、承認ゲートとしてはほぼ無価値です。承認者は何を承認したのか分からず、押す以外の選択肢を持てません。MCPの仕様は、セキュリティ上の考慮事項としてクライアントに「サーバを呼び出す前にツールの入力を利用者へ提示し、悪意のあるデータ流出や事故を避ける」ことを推奨しています。Microsoft Agent Frameworkが承認要求に関数名と引数を含めるのも、Bedrockが確認時に呼び出し内容を返すのも同じ発想です。
実務では、承認画面に少なくとも次の4点を出すようにしています。
- 1
何をしようとしているか
ツール名だけでなく、実際の引数(宛先、対象レコード、金額、ファイルパスなど)をそのまま見せます。要約に丸めると、承認者は差分を確認できません。 - 2
なぜそうしようとしているか
どのユーザー指示から、どの根拠情報を経由してこの操作に至ったのかを短く添えます。外部文書由来の指示で動いている場合は、その出所を明示します。 - 3
影響範囲の要約
何件のレコードが変わるか、誰に届くか、本番か検証か。件数と対象は数字で出すのが有効です。 - 4
取り消せるかどうか
この操作が可逆か、可逆ならどうやって戻すか。ここが書かれていると、承認者は迷ったときに「承認して後で戻す」か「今止める」かを自分で選べます。
なお、根拠として提示する情報自体が汚染されている可能性は残ります。外部文書やWebページを読んだうえでの操作提案は、その文書に埋め込まれた指示で歪められている場合があるため、提示する根拠は「エージェントの説明」ではなく「実際に読んだ元データへのリンク」に寄せるほうが安全です。
あわせて読みたい
LLMのTool Use(関数呼び出し)とは|仕組みと精度を上げるツール設計
監査ログに何を残すか
承認ゲートは、後から追跡できて初めて運用になります。MCPの仕様もクライアント側の推奨事項として「監査目的でツールの利用をログに残す」ことを挙げています。実務では、最低限として次の項目を1レコードにまとめておくと、事後の調査が成立します。
承認まわりの監査ログに残す項目
- いつ(タイムスタンプ)、どのセッション・実行IDで発生したか
- どのエージェント・どのモデル・どのバージョンの設定で動いていたか
- どのツールを、どの引数で呼ぼうとしたか(機微情報はマスクしつつ、判断できる粒度は残す)
- 承認要求が出た理由(どのルール・条件に合致したか)
- 誰が承認・却下したか(人物と、承認に要した時間)
- 却下された場合、その後エージェントが何をしたか(代替手段に流れていないか)
- 実行結果と、取り消しが行われた場合はその記録
このうち見落とされやすいのが、却下後の挙動です。承認を却下したのに、エージェントが別のツールで同じ目的を達成してしまうことがあります。承認された操作だけでなく、却下された操作とその後の行動をセットで見ないと、承認ゲートが実際に効いているかは判定できません。承認に要した時間も記録しておくと、「平均1.2秒で承認されている」といった形で承認疲れの兆候が数字に出ます。ログ設計とトレースの一般論は あわせて読みたい LLMアプリのオブザーバビリティ|トレーシングとログ設計で「なぜこの出力になったか」を後から追えるようにする
事後の取り消しを介入の形として採用する場合は、取り消し自体の手段も設計対象です。NISTのAI RMFプレイブックは、管理機能のサブカテゴリMANAGE 2.4として「意図した用途と一致しない性能や結果を示すAIシステムを、置き換える・切り離す・停止するための仕組みが用意され適用されており、責任が割り当てられ理解されていること」を挙げ、バイパスや停止の判断を発動する閾値の定期的な見直しや、バイパス手順・冗長系の確認を推奨しています。「止められる」ことを担当者の機転ではなく手順として持つ、という考え方です。
実装で詰まりやすい点
承認ゲートは概念としては単純ですが、実装では次の点でつまずきます。
- 再開時の再実行: LangGraphの公式ドキュメントは、
interrupt()から再開すると「interruptが呼ばれたノードの先頭から再開されるため、interruptより前のコードが再度実行される」と明記しています。承認待ちの前に副作用のある処理を書いていると、再開のたびに二重実行されます。承認の手前に置く処理は冪等にするか、副作用を承認後に寄せる必要があります。 - 承認待ちの寿命: 承認は数秒で返るとは限りません。実行状態をメモリに持つ設計では、プロセス再起動やデプロイで承認待ちが消えます。永続化(チェックポインタや
stateのシリアライズ)と、タイムアウトしたときの既定動作(自動却下が基本)を決めておきます。 - 既定値の向き: Bedrockのユーザー確認のように、承認は明示的に有効化するオプトインの設計になっているのが一般的です。ツールを追加したときに承認設定を付け忘れる事故は起きやすいため、新規ツールは既定で承認必須にし、外す判断を明示的に行うほうが安全側に倒れます。
- 承認の粒度: 「このツールを常に許可」という永続的な承認ルールを用意すると承認疲れは減りますが、許可の範囲が広すぎると事実上の全許可になります。ツール名単位ではなく引数の条件付き(この宛先ドメインだけ、この金額以下だけ)で許可できるかを確認します。
自動化率を段階的に上げる進め方
最初から適切な承認設計を当てるのは難しいので、承認を絞り込んでいく過程そのものを運用に組み込みます。
- 1
全件承認で始める
最初は副作用のある操作をすべて承認対象にします。目的は安全確保だけでなく、エージェントがどんな操作を、どんな引数で提案してくるかという分布を観測することです。 - 2
却下されたケースを分類する
却下の理由をラベル付けします。「対象を取り違えた」「根拠が薄い」「指示の解釈が広すぎる」といった失敗パターンが見えてきます。 - 3
失敗パターンを評価データに落とす
分類した却下ケースを回帰テストのケースに変換します。ここを飛ばすと、自動化を進めた後に同じ失敗が再発しても気づけません。 - 4
安全な領域から自動化する
可逆で影響範囲が狭く、検知が速い操作から承認を外します。ツール単位ではなく、引数の条件付きで外すのが基本です(この検索は自動、この宛先への送信のみ自動、など)。 - 5
外した領域をサンプリング監査に切り替える
承認を外した操作は、全件確認から一定割合の抜き取り点検に移します。品質が落ちてきたら承認に戻せる導線を残しておきます。 - 6
指標を継続的に見る
承認要求の件数、却下率、平均承認時間、取り消しの発生件数を定期的に確認します。却下率がほぼゼロなら承認は不要になっている可能性があり、平均承認時間が極端に短ければ形骸化の疑いがあります。
Claude Agent SDKのドキュメントも、セッション途中でsetPermissionMode()により権限モードを変更できることを説明し、「制限的な状態から始めて、信頼が積み上がるにつれて緩める」使い方を例示しています。段階的に緩めるという考え方は、製品の機能としても想定されているものです。
承認ゲートが安全装置にならない場面
最後に、人間承認が向かない場面を明示しておきます。承認ゲートは、承認者がその内容を検証できることを前提にした仕組みです。前提が崩れると、安全装置ではなく責任の所在を移すだけの儀式になります。
- 承認者が内容を検証できない場合: 数百行のSQLや複雑な設定差分を、業務担当者が数秒で妥当性判断するのは不可能です。この場合は承認ではなく、機械的な検証(テスト、スキーマ検証、影響件数の上限チェック)を先に置くべきです。
- 量が多すぎる場合: 1日数千件の承認は物理的に成立しません。サンプリング監査か、権限側での封じ込めに切り替えます。
- 判断に必要な文脈が承認画面に載らない場合: 「この顧客は先週も同じ連絡を受けている」といった文脈がなければ、送信の可否は判断できません。文脈を出せないなら、その操作は自動化の対象から外すのが現実的です。
- 承認者と実行者の利害が一致している場合: エージェントを動かした本人が自分で承認する構成は、急いでいるときに素通りします。影響が大きい操作は、別の人が承認する経路を検討します。
注意
本文で触れたフレームワークの機能名・挙動は、各社の公式ドキュメント(OpenAI Agents SDKの承認とレビュー、Claude Agent SDKの権限設定、Amazon Bedrock Agentsのユーザー確認、Microsoft Agent Frameworkのツール承認、LangGraphのInterrupts)、およびModel Context Protocolの仕様(2025-06-18)に基づいて記載しました。制度面の記述はEU AI Act第14条とNIST AI RMFプレイブックによります。各仕様・機能は更新されるため、実装前に最新の公式情報を確認してください。
よくある質問
すべての書き込み操作に承認を求めるのは間違いですか
承認と権限管理はどちらを先に設計すべきですか
承認画面には何を表示すればよいですか
承認が形骸化しているかどうかは何で分かりますか
承認待ちの間、エージェントの状態はどう保てばよいですか
承認を挟めばプロンプトインジェクションは防げますか
まとめ
Human-in-the-Loop設計のチェックリスト
- 操作ごとに可逆性・影響範囲・検知の遅れ・頻度の4軸を評価し、承認の要否と形を決めた
- 介入の形を事前承認だけに固定せず、ドライラン・事後の取り消し・サンプリング監査・エスカレーションを検討した
- 承認に回す前に、権限スコープの絞り込み(読み取り既定・書き込みは限定リソース)で承認件数そのものを減らした
- 承認画面に、実際の引数・根拠・影響範囲・取り消し可否を表示した
- 承認要求件数・却下率・平均承認時間・取り消し件数を計測し、形骸化の兆候を追えるようにした
- 誰が・いつ・どのツールを・どの引数で・誰が承認したか、却下後の挙動まで監査ログに残した
- 承認待ちの状態を永続化し、タイムアウト時の既定動作を決めた
- 承認者が内容を検証できない領域を洗い出し、承認ではなく機械的検証か自動化の停止で対処した
人間承認の設計は、「安全のために確認を増やす」作業ではなく、「限られた人の注意をどこに配分するか」を決める作業です。可逆で影響の狭い操作から人の手を離し、不可逆で影響の広い操作にだけ注意を集中させる。そのために権限を絞り、承認画面に判断できる情報を載せ、却下と取り消しの記録から設計を直していく。この配分が適切になったとき、承認ゲートは開発速度を落とす障害物ではなく、エージェントに任せられる範囲を安全に広げていくための土台になります。
出典・参考
- LLM06:2025 Excessive Agency - OWASP Gen AI Security Project(公式)
- Tools - Model Context Protocol specification 2025-06-18(公式)
- Guardrails and human review - OpenAI API(公式)
- Configure permissions - Claude Agent SDK(公式)
- Get user confirmation before invoking action group function - Amazon Bedrock(公式)
- Using function tools with human in the loop approvals - Microsoft Agent Framework(公式)
- Interrupts - Docs by LangChain(公式)
- Article 14: Human Oversight - EU AI Act Service Desk(欧州委員会)
- AI RMF Playbook: Manage - NIST AI Resource Center(公式)
関連する記事
AIエージェントとは何か|従来の自動化との違いと任せてよい仕事
生成AIの活用で注目されるAIエージェントを冷静に解説します。チャットボットやRPAとの違い、自律性がもたらす利点とリスク、実務でエージェントに任せてよい仕事と任せるべきでない仕事の線引きをまとめます。
LLMガードレールの設計|入力・出力・挙動の3層で安全境界をつくる実務ガイド
LLMを組み込むアプリ・エージェントに欠かせないガードレール設計を、実装アーキテクチャの目線で整理します。システムプロンプトだけでは安全境界にならない理由、入力・出力・挙動の3層構成、分類器やスキーマ検証・OSSフレームワークといった実装手段の類型、過剰検知と過小防御のトレードオフ、評価とレッドチーミングの必要性までを扱います。
LLMのTool Use(関数呼び出し)とは|仕組みと精度を上げるツール設計
LLMが外部のツールやAPIを呼び出す「Tool Use(関数呼び出し/function calling)」の仕組みを、実務目線で解説します。tool_useとtool_resultの往復、クライアントツールとサーバーツールの違い、いつ呼ぶかの制御、そして呼び出し精度を上げるためのツール定義のコツまでを整理します。


