AIエージェントの緊急停止設計 — サーキットブレーカーの実装ガイド

AIエージェントの緊急停止設計 — サーキットブレーカーの実装ガイド

AIエージェントのサーキットブレーカーとは、エージェントの異常動作・コスト超過・ループ暴走を検知して自動停止させる安全機構である。本記事では、LLMを活用したAIエージェントの緊急停止設計に携わる開発者・MLOpsエンジニアを対象に、サーキットブレーカーの実装パターンからAIガードレールとの統合まで、実践的な手順を解説する。

AIエージェントのサーキットブレーカーとは、エージェントの異常動作・コスト超過・ループ暴走をリアルタイムに検知し、被害が拡大する前に処理を自動停止させる安全機構である。本記事は、LLM を組み込んだ AI エージェントを本番運用する開発者・MLOps エンジニアを対象に、監視レイヤーの構築からトリガー条件の設定、キルスイッチとフォールバックの実装、ガードレールとの統合までを手順を追って解説する。読み終えると、自社のエージェントに「止める仕組み」を設計段階から組み込み、暴走コストとセキュリティ事故を抑える具体的な実装方針を描けるようになる。

自律的に判断し続ける AI エージェントは、設計者の想定を超えてツールを呼び出し、コストとリスクを指数的に膨張させうる。緊急停止設計は「動かす仕組み」と同じ重みで「止める仕組み」を持つための前提である。 ここでは、停止設計を後回しにできない三つの理由——コスト・セキュリティ・規制——を整理する。

エージェントの暴走がもたらすリスク:コスト・セキュリティ・信頼性

従来のアプリケーションは、リクエストとレスポンスが 1 対 1 で対応するため、被害の上限が見積もりやすい。一方 AI エージェントは、1 つの指示から十数回のツール呼び出しと LLM 推論を連鎖させる。この連鎖が想定どおり収束すれば問題ないが、ループ条件の判定を誤ると呼び出しが止まらず、課金が青天井に膨らむ。

リスクは大きく三層に分かれる。第一にコスト——トークン課金や外部 API の従量課金が制御を失う。第二にセキュリティ——プロンプトインジェクションに誘導され、本来許可していない操作(メール送信、データ削除、外部送信)を実行してしまう。第三に信頼性——ハルシネーションを含む出力を確定情報として下流処理へ流し、業務データを汚染する。これら三つは独立ではなく、暴走時には連鎖して同時に顕在化する。だからこそ、個別対策ではなく「検知して止める」共通機構が要る。

アンバウンデッド・コンサンプションとエクセシブ・エージェンシーの脅威

AI エージェント固有のリスクは、OWASP の LLM アプリケーション向け脅威カテゴリでも明確に位置づけられている。代表的なのが**アンバウンデッド・コンサンプション(Unbounded Consumption)エクセシブ・エージェンシー(Excessive Agency)**の二つだ。

アンバウンデッド・コンサンプションは、入力や再帰呼び出しに上限がなく、計算資源・コスト・トークンが際限なく消費される状態を指す。無限ループや、攻撃者が意図的に重いタスクを投入するサービス妨害(DoS)がこれに当たる。

エクセシブ・エージェンシーは、エージェントに与えた権限・ツール・自律性が過剰で、誤作動時の影響範囲が広がりすぎる状態を指す。「読み取りで十分な処理に書き込み権限を渡している」「人間の承認なしに不可逆操作を実行できる」設計が典型だ。サーキットブレーカーは前者を、権限の最小化(最小権限設計)は後者を主に抑える。両者は補完関係にあり、片方だけでは防ぎきれない。

AIガバナンス・EU AI Actが求める停止制御の要件

暴走防止は技術課題であると同時に、コンプライアンス要件でもある。全面施行済みの EU AI Act は、高リスク AI システムに対して、運用中に人間が介入し、必要に応じて**システムを停止できる手段(ヒューマン・オーバーサイト)**を備えることを求めている。停止ボタンに相当する制御が設計に組み込まれていること自体が、適合性評価の論点になる。

つまりキルスイッチは「あれば安心」ではなく、規制対象領域では「なければ要件を満たさない」構成要素になりつつある。社内ルールや監査対応を含めた全体像はAI ガバナンスの実務ガイドで整理しているが、停止制御の観点では最低限、(1) 誰が・どの条件で停止できるか、(2) 停止操作と理由がログに残るか、(3) 停止後に安全な状態へ復帰できるか、の三点を設計時に明文化しておきたい。

実装前に確認すべき前提条件と設計方針は?

実装前に確認すべき前提条件と設計方針は?

サーキットブレーカーは単体では機能しない。「何が起きているか」を観測する基盤と、「誰がどこまで介入するか」の方針、そして「どの値で止めるか」の閾値定義が揃って初めて動く。 実装に入る前に、この三つの前提を確認する。

AIオブザーバビリティ基盤の整備状況を確認する

止める仕組みは、観測できる範囲でしか働かない。トークン消費もループ回数も、計測されていなければトリガーのしようがない。したがって最初の前提は、エージェントの内部状態を可視化するAI オブザーバビリティ基盤が整っているかどうかだ。

具体的には、各ステップの入力・出力・使用トークン・ツール呼び出し・レイテンシ・エラーを、トレース単位で時系列に記録できている必要がある。OpenTelemetry のような分散トレーシングの考え方を LLM 呼び出しに適用し、「1 タスク = 1 トレース」「1 ステップ = 1 スパン」で構造化しておくと、後段の閾値判定がそのまま書ける。観測基盤の設計そのものはAI オブザーバビリティの実践ガイドに譲るが、本記事の手順は「計測済みのメトリクスが取得できる」ことを前提に進める。未整備なら、先に観測から着手するのが順序として正しい。

ヒューマン・イン・ザ・ループ/オン・ザ・ループの介入レベルを決める

次に決めるのは、停止判断に人間をどう関与させるかだ。介入の濃度は大きく三段階で考えると整理しやすい。

**イン・ザ・ループ(in-the-loop)**は、重要な操作の前で必ず人間の承認を挟む方式。不可逆・高リスクな処理に向くが、スループットは落ちる。**オン・ザ・ループ(on-the-loop)**は、エージェントは自律実行しつつ、人間が監視ダッシュボードで状況を見て、必要時に介入・停止する方式。アウト・オブ・ザ・ループは完全自律で、停止は機械的なトリガーに委ねる。

実務では、処理の不可逆性とリスクに応じてツールごとに段階を変えるのが現実的だ。例えば「検索は自律、外部送信は承認必須、決済は二重承認」のように分ける。介入設計の基礎はヒューマン・イン・ザ・ループ(HITL)の解説に詳しい。サーキットブレーカーは、この介入レベルと矛盾しないよう、停止時のエスカレーション先を明確にしておく。

停止トリガーとなる閾値指標(トークン数・コスト・ループ回数)を定義する

前提の最後は、何を見て止めるかの指標選定だ。代表的な閾値指標を、観測のしやすさと誤検知のしにくさで選ぶ。

指標主に防ぐもの
累積トークン数1 タスク 50,000 トークンコスト暴走
累積コスト1 タスク 0.5 USDコスト暴走
ステップ数 / ループ回数30 ステップ無限ループ
連続エラー率直近 5 回中 3 回失敗外部障害の連鎖
経過時間セッション 10 分ハング・滞留

重要なのは、単一指標に頼らず複数を組み合わせることだ。トークン数だけでは「安いが終わらないループ」を取りこぼし、ステップ数だけでは「少数だが高額なツール呼び出し」を見逃す。閾値は最初から完璧を狙わず、本番のメトリクス分布(p50 / p95)を見ながら調整する前提で、まず安全側に置く。コスト系の上限値の決め方はLLM コスト最適化ガイドの予算設計と合わせて検討するとよい。

Step 1: 監視レイヤーをどう構築するか?

Step 1: 監視レイヤーをどう構築するか?

サーキットブレーカーの実体は「計測 → 判定 → 遮断」のループだ。最初のステップは、判定の材料となるメトリクスをリアルタイムに集める監視レイヤーの構築である。 ここでは消費量・進捗・異常シグナルの三系統を計測する。

トークン消費・API呼び出し回数・レイテンシのリアルタイム計測

監視レイヤーの土台は、エージェントの 1 ステップごとに消費量を積算するカウンタだ。LLM クライアントとツール実行をラッパーで包み、呼び出しのたびにトークン数・コスト・回数・レイテンシをタスク単位のコンテキストへ加算する。

python
1class UsageTracker: 2 def __init__(self, budget): 3 self.tokens = 0 4 self.cost = 0.0 5 self.calls = 0 6 self.budget = budget 7 8 def record(self, usage): 9 self.tokens += usage.total_tokens 10 self.cost += usage.cost 11 self.calls += 1 12 # 閾値内なら True、超過なら False を返し呼び出し側で遮断 13 return (self.tokens <= self.budget.max_tokens 14 and self.cost <= self.budget.max_cost)

ポイントは、計測をエージェントのロジック本体から分離し、ラッパー層に閉じ込めることだ。こうすると、後からブレーカーの条件を変えても本体に触れずに済む。レイテンシは、外部 API の遅延が連鎖して全体がハングする兆候を早期に捉えるための指標として併せて記録する。

タスクグラフの進捗追跡と無限ループ検知ロジック

消費量と並んで重要なのが、エージェントが「前に進んでいるか」の追跡だ。無限ループの多くは、同じツールを同じ引数で繰り返す、あるいは同じ状態を行き来する形で現れる。

検知の基本は二つ。第一にステップ上限——タスクごとに最大ステップ数を決め、超えたら強制終了する。第二に反復検知——直近 N ステップのツール名と引数のハッシュを保持し、同一パターンが閾値回数を超えたらループとみなす。

python
1def is_looping(history, window=6, repeat=3): 2 recent = history[-window:] 3 sigs = [hash((h.tool, h.args_digest)) for h in recent] 4 return any(sigs.count(s) >= repeat for s in set(sigs))

計画と実行を分離するマルチエージェント構成では、タスクグラフのノード遷移そのものを監視対象にできる。設計パターンはマルチエージェント AI の解説を参照。進捗が一定時間更新されない「スタック」状態も、別途タイムアウトで拾う。

プロンプトインジェクション・ハルシネーションの異常シグナル収集

量と進捗に加えて、出力の「質の異常」もシグナルとして集めておく。これは後段でガードレールや人間の介入を発火させる材料になる。

プロンプトインジェクションの兆候としては、システム指示を上書きしようとする語(「これまでの指示を無視」等)の出現、許可外ツールへの突然の呼び出し、出力に含まれる外部 URL や認証情報の流出パターンなどを監視する。ハルシネーションの兆候としては、ツール結果に存在しない事実への言及、確信度の自己申告が不自然に高い・低い、同一質問への回答の揺れなどを拾う。

ここで集めるのはあくまで「シグナル」であり、単体で確定的に止める根拠にはしない点が重要だ。誤検知が多いと正常タスクまで遮断してしまう。検知ロジックの作り込みは、攻撃側の手口を把握しておくと精度が上がる——AI レッドチーミングで典型的な攻撃パターンを押さえておきたい。

Step 2: サーキットブレーカーのトリガー条件をどう設定するか?

Step 2: サーキットブレーカーのトリガー条件をどう設定するか?

監視で集めたメトリクスを「止める / 止めない」の判定に変換するのが、このステップだ。マイクロサービスのサーキットブレーカーと同じく、コスト・エラー率・タイムアウトの三系統でトリガーを定義する。 それぞれの閾値設計を見ていく。

コストベースのスロットリング:LLMトークン予算の上限設定

最初のトリガーは予算ベースだ。タスクごとにトークン・コスト・呼び出し回数の上限を定め、超過時の挙動をセットで設計する。上限は一律ではなく、少なくとも三段で持つと運用しやすい。

段階超過時の挙動
ソフト上限0.3 USD警告+安価モデルへ切替
ハード上限0.5 USD強制中断+人間へエスカレーション
呼び出し上限LLM 30 回 / ツール 50 回ループ強制終了

タスクの性質で適正値は変わる。抽出や整形のように収束しやすいタスクは安く済み、調査や長期計画は反復回数が読みにくい。「探索系 / 抽出系 / 生成系」のように分類して予算を別建てすると、全タスクに同じ上限を当てて「9 割が緩すぎ・1 割が厳しすぎ」になる事態を避けられる。予算をコスト設計全体へ位置づける考え方はAI エージェントの経済モデルで詳述している。

エラーレートベースの遮断:連続失敗回数による自動切断

二つ目はエラー率ベースのトリガーで、これが本来の「サーキットブレーカー」に最も近い。マイクロサービスのパターンを踏襲し、三状態で管理する。

  • クローズ(閉):通常運転。呼び出しは通すが失敗をカウントする。
  • オープン(開):失敗が閾値を超えたら回路を開き、一定時間すべての呼び出しを即座に拒否する(フェイルファスト)。
  • ハーフオープン(半開):クールダウン後に試験的に数回だけ通し、回復していればクローズへ戻す。
python
1if breaker.state == "open": 2 if now < breaker.retry_at: 3 raise CircuitOpen("外部依存が不安定なため遮断中") 4 breaker.state = "half_open" # 試験的に再開

これにより、外部 API やツールが落ちているときに、失敗するとわかっている呼び出しを延々と再試行してコストと時間を浪費する事態を防ぐ。閾値は「直近 N 回中 M 回失敗」のような率で持つと、低頻度の単発エラーで過剰に開くのを避けられる。

タイムアウトベースの停止:ステップ単位・セッション単位の制限

三つ目は時間ベースだ。コストもエラーも閾値内なのに、外部応答待ちやツールのハングで全体が滞留するケースを拾う。タイムアウトは階層で持つ。

ステップ単位では、個々の LLM 呼び出し・ツール実行に上限時間を設け、超えたらその呼び出しを打ち切ってリトライまたはフォールバックへ回す。セッション単位では、1 タスク全体の経過時間に上限を設け、超えたら未完了でも安全に中断する。両者を併用しないと、「各ステップは速いが終わらないループ」や「1 ステップが固まって全体を止める」を取りこぼす。

実装上は、非同期処理のキャンセル機構(タイムアウト付き await、キャンセルトークン)と組み合わせ、中断時にリソース(接続・一時ファイル・ロック)が確実に解放されるようにする。中断が中途半端だと、止めたつもりが裏で処理が走り続ける「ゾンビタスク」を生む。

Step 3: キルスイッチとフォールバック処理をどう実装するか?

Step 3: キルスイッチとフォールバック処理をどう実装するか?

トリガーが発火した後、どう止め、止めた後に何を返すかを設計するのがこのステップだ。止め方には強弱があり、業務影響に応じて使い分ける。さらにガードレールやマルチエージェント隔離と組み合わせて多層化する。 実装の勘所を見ていく。

ハードストップとソフトストップの使い分け

停止には二種類ある。ハードストップは、処理を即座に打ち切るキルスイッチ。コスト暴走や明確なセキュリティ侵害など、続行する方が危険な場合に使う。ソフトストップは、現在のステップを完了させてから安全な区切りで止める、あるいは機能を縮退させて継続する方式。ユーザー体験を保ちたい場合に向く。

状況推奨停止後の振る舞い
コスト上限超過ハード中断し、途中結果と理由を返す
外部 API 連続失敗ソフト安価モデル/キャッシュ応答へ縮退
インジェクション検知ハード当該セッションを隔離・遮断
レイテンシ超過ソフト部分結果を返し非同期で継続

キルスイッチは、全エージェント・全テナントへ一斉に効くグローバルなものと、特定タスク・特定ユーザーに限定するスコープ付きのものを両方用意しておくと、障害時の被害を最小範囲に閉じ込められる。停止時には必ず、ユーザーへ返すメッセージと内部ログの両方を生成する。

AIガードレールとの統合:プロンプトファイアウォールによる事前遮断

サーキットブレーカーが「走り出した処理を止める」事後の仕組みであるのに対し、ガードレールは「危険な入出力を通さない」事前の仕組みだ。両者は止める層が違うため、組み合わせて多層防御にする。

入力側では、プロンプトファイアウォールでインジェクションや禁止トピックを検知し、エージェントへ渡る前に遮断する。出力側では、個人情報・認証情報・有害表現のフィルタを通してから下流へ流す。ここで弾いた事象は、前段で集めた異常シグナルとしてブレーカーのカウンタにも反映し、「ガードレールに繰り返し引っかかるセッションは丸ごと遮断する」といった連動を効かせる。

ガードレールの設計と実装の全体像はAI ガードレール実装ガイドにまとめている。本記事の停止機構は、ガードレールをすり抜けた「実行中の暴走」を最後に受け止める安全網として位置づけるとよい。

マルチエージェントシステムにおける部分停止と隔離設計

複数のエージェントが協調するシステムでは、停止の粒度が重要になる。1 つのサブエージェントが暴走したからといって全体を落とすと、可用性を大きく損なう。

設計の基本は**隔離(バルクヘッド)**だ。サブエージェントごとに独立した予算・ブレーカー・実行コンテキストを割り当て、1 つが開いても他は動き続けるようにする。オーケストレータは、停止したノードのタスクを切り離し、代替経路へ再ルーティングするか、人間へエスカレーションする。

text
1[Orchestrator] 2 ├─ Agent A (breaker: closed) → 継続 3 ├─ Agent B (breaker: open) → 隔離・再割当 4 └─ Agent C (breaker: closed) → 継続

エージェント間がツールや状態を共有していると、1 つの暴走が連鎖して全体に波及する。共有リソースには個別の上限とアクセス制御を設ける。協調設計の詳細はマルチエージェント AIを参照。部分停止が効く構成は、最初のアーキテクチャ選定の段階で決まる。

よくある実装ミスとその回避策は?

よくある実装ミスとその回避策は?

緊急停止は「付けたら終わり」ではない。閾値の置き方や運用の作り込みを誤ると、正常業務を止めたり、肝心なときに役に立たなかったりする。 現場で繰り返し見かける二つの失敗と回避策を挙げる。

閾値の過剰設定で正常タスクまで止めてしまうケース

最も多い失敗は、安全側に倒しすぎて誤遮断(フォルスポジティブ)が頻発するパターンだ。トークン上限を平均値ぎりぎりに設定した結果、正常だが少し重いタスクが軒並み中断され、ユーザーからは「よく止まる使えない機能」に見えてしまう。

回避策は三つ。第一に、閾値は本番のメトリクス分布から決める——p50 ではなく p95 や p99 を基準に、正常タスクの大半が収まる位置へ置く。第二に、いきなりハードストップにせず、まずソフト上限で警告とモデル縮退を挟み、段階的に効かせる。第三に、ブレーカーを最初は**観測モード(シャドーモード)**で動かし、「もし有効化していたら何回・どのタスクを止めていたか」をログだけ取る。実際の遮断を始める前にこの空運転で誤検知率を見ておくと、本番投入後の事故を大きく減らせる。閾値は固定値ではなく、運用しながら調整し続ける対象だと捉える。

停止ログが残らず原因調査できないアンチパターン

もう一つの典型は、止めること自体に気を取られ、「なぜ止まったか」を残さない実装だ。停止はしたがログがなく、ユーザーから「途中で止まった」と報告されても、どのトリガーがどの値で発火したのか追えない。これでは閾値の調整も再発防止もできない。

停止イベントには最低限、(1) トリガー種別(コスト/エラー率/タイムアウト/ガードレール)、(2) 発火時の実測値と閾値、(3) 該当タスク・ユーザー・トレース ID、(4) 停止種別(ハード/ソフト)と事後の挙動、(5) タイムスタンプ、を構造化ログとして残す。これらが揃っていれば、停止の妥当性を後から検証し、閾値を根拠を持って動かせる。

加えて、停止の発生率・誤遮断率をダッシュボードで継続監視し、急増時にアラートを出す。停止機構自体も監視対象であるという視点が、EU AI Act が求める「説明可能な人間の介入」の証跡づくりにもつながる。停止ログは、コストとインシデントの両面で改善ループを回すための一次データになる。

まとめ — 緊急停止設計は「設計段階」から組み込む

まとめ — 緊急停止設計は「設計段階」から組み込む

AI エージェントのサーキットブレーカーは、「計測 → 判定 → 遮断 → 記録」の一連を、運用後の追加機能ではなく設計段階の前提として組み込むことで初めて機能する。本記事の手順を要約すると次のとおりだ。

  • 前提を揃える:オブザーバビリティ基盤・介入レベル・閾値指標を先に定義する。
  • 監視レイヤー:消費量・進捗・異常シグナルの三系統をラッパー層で計測する。
  • トリガー:コスト・エラー率・タイムアウトの三系統で多重に判定する。
  • キルスイッチ:ハード/ソフトを使い分け、ガードレールとマルチエージェント隔離で多層化する。
  • 運用:シャドーモードで誤検知を見極め、停止ログから閾値を調整し続ける。

止める仕組みは、暴走コストの抑制とセキュリティ事故の封じ込め、そして規制対応の三つを同時に支える投資だ。当社では、AI エージェントの本番化支援において、この停止設計を初期アーキテクチャの必須要件として組み込むことを推奨している。エージェント導入や緊急停止設計の具体化についてのご相談は、当社までお問い合わせいただきたい。

著者・監修者

Yusuke Ishihara

Yusuke Ishihara

13歳でMSXに触れプログラミングを開始。武蔵大学卒業後、航空会社の基幹システム開発や日本初のWindowsサーバホスティング・VPS基盤構築など、大規模システム開発に従事。 2008年にサイトエンジン株式会社を共同創業。2010年にユニモン株式会社、2025年にエニソン株式会社を設立し、業務システム・自然言語処理・プラットフォーム開発をリード。 現在は生成AI・大規模言語モデル(LLM)を活用したプロダクト開発およびAI・DX推進を手がける。