実際のAIエージェントの失敗モードは「不確実な完了(uncertain completion)」である
AIエージェントの議論の多くは、間違った失敗モードに焦点を当てています。
人々は次のような話をします:
ハルシネーション
プロンプトインジェクション
ツールの誤用
暴走ループ
不適切な推論
それらは実際に起こります。
しかし、エージェントが外部世界に影響するツールを呼び始めると、別の種類の失敗がはるかに危険になります:
不確実な完了(uncertain completion)
それはシステムが自信を持って答えられない瞬間です:
「このアクションは、すでに実行されたのか?」
そしてその問いが曖昧になると、リトライは非常に速く危険になります。
不確実な完了が実際にどのように見えるか
よくある現実の経路は、たとえば次のようなものです:
エージェントが send_payment() を呼び出す判断をする
→ ツールが支払いリクエストを送信する
→ タイムアウト / クラッシュ / 切断 / 応答の喪失
→ 呼び出し側は成功したかどうかわからない
→ リトライが発生する
→ 支払いが再度送信される可能性がある
同じことは次でも起きます:
注文作成
予約フロー
メール送信
CRMの変更
サポートチケット作成
ブラウザ / UI オートメーション
Webhook がトリガするワークフロー
モデルは正しい判断をしたかもしれません。
しかし失敗は、サイドエフェクトがすでに起きたかどうかをシステムが確実に証明できる耐久的な方法を持っていないことです。
これは主にプロンプトの問題ではない
エージェントが「愚かに」なっているわけではないことが多いです。
システムは単に、きれいな実行境界(execution boundary)を欠いているだけです。
つまり:
同じ論理アクションが複数回試され得る
呼び出し側は「試行(attempted)」と「完了(completed)」を区別できない
リトライは推測を強いられる
そして「推測」がまさに次を生みます:
重複した支払い
重複したメール
重複した注文
重複したAPIミューテーション
重複した取り返しのつかないアクション
隠れた罠: 「試行はログに記録した」
多くのシステムは、何かをしようとしたことを記録します。
しかしそれは「安全に完了したこと」を記録するのとは同じではありません。
ここで重要なのは、この区別です:
状態の可視性(State visibility)
あなたのシステムは、耐久的に次を見られますか:
何が要求されたか
何が主張されたか
何が実際に完了したか
リプレイ時に返すべき結果は何か
結果回復(Result recovery)
サイドエフェクトが起きたのに応答が失われた場合、システムはそのサイドエフェクトを再実行せずに、次に起こるべきことを再構築できますか?
多くのシステムが壊れるのは、まさにこの後半です。
なぜなら、答えが一度:
「確信できないので、もう一度やる」
になった時点で、あなたはすでに危険な領域にいます。
APIの冪等性(idempotency)は役立つ — しかし十分ではない
よくある返答は:
「冪等性キーを使うだけでいい。」
それはしばしば正しいです。
そして、下流のAPIが強い冪等性の意味論をサポートしているなら、絶対にそれを使うべきです。
ですが、それでも難しいケースが残ります:
下流のAPIが冪等性をサポートしていない
キーがリトライ間で安定しない
最初の呼び出しが成功した可能性があるが、呼び出し側はそれを証明できない
サイドエフェクトがブラウザ / UI / デスクトップオートメーションの文脈で起きている
外部システムが弱い、または曖昧なフィードバックしか返さない
そうした場合、問題はもはや単にAPIレベルの冪等性ではありません。
問題はこうなります:
実行レイヤーの安全性(execution-layer safety)
重要な分割: 意図(intent)と実行(execution)
これを考えるための、かなりきれいな方法の1つは:
エージェントは、不可逆なサイドエフェクトを直接所有すべきではない
その代わりに、次の間に分離があるべきです:
エージェントの意図(Agent intent)
「Xをやるべきだと思う」
そして
実行(Execution)
「Xは、ちょうど1回だけ起こることが許可される」
これは非常に重要な境界です。
なぜなら、システムが一度次を分離すると:
意思決定
検証(validation)
実行(execution)
受領(receipt)/リプレイ
…すると、リトライは危険になりにくくなります。
より良いパターン: 提案 → ガード → 実行
より安全な構造は、次のようになります:
エージェントがアクションを提案する
→ 決定論的なレイヤーがアクションを検証する
→ 実行ガードが耐久的な受領(durable receipt)を確認する
→ すでに完了しているなら: 以前の結果を返す
→ そうでなければ: 1回だけ実行し、受領を永続化する
これは、次のパターンとはまったく異なる考え方です:
エージェントが判断する
→ 直ちにサイドエフェクトを起こすツールを呼び出す
この後者のパターンで、多くの本番(production)のエージェントシステムが問題に巻き込まれます。
不可逆なアクションであるほど、境界は厚くする
すべてのツールを同じように扱うべきではありません。
有用な考え方のモデルは:
安全なツール(Safe tools)
例:
検索
read_file
要約(summarize)
fetch_status
これらは通常、リトライしても問題ありません。
副作用のあるツール(Side-effecting tools)
例:
send_email
create_order
create_ticket
update_CRM
これらには実行境界が必要です。
不可逆 / 高リスクのツール
例:
payment
delete
取引(trade execution)
アカウントの変更(account mutation)
これらには最も強い境界が必要です:
決定論的なアイデンティティ
耐久的な受領(durable receipts)
リプレイに安全な意味論(replay-safe semantics)
多くの場合、確認(confirmation)/ ポリシーチェック
原則は単純です:
アクションが不可逆であるほど、実行境界は厚くすべきである
実際にシステムが必要とするもの
実務では、ほとんどのシステムに次のいくつかの組み合わせが必要です:
安定したリクエスト / オペレーションのアイデンティティ
耐久的な受領(receipt)ストレージ
リプレイに安全な実行意味論
結果回復(result recovery)
「提案(propose)」と「実行(execute)」の間の明示的な分離
それは多くの方法で実装できます。
しかし重要なのは、アーキテクチャ上の境界そのものです。
なぜなら、システムが自信を持って次を答えられるようになったら:
「はい、これはすでに起きています」
リトライはずっと安全になります。
なぜエージェントシステムでこれが繰り返し出てくるのか
従来のシステムは、すでにこの問題を抱えていました。
エージェントは、それをより目に見えるものにしているだけです。
なぜでしょう?
エージェントは:
リトライが多い
ツールを使う
非同期で動く
失敗が起きやすい
多くの場合、自律的リプレイのために設計されていないAPIの上にレイヤーとして積み上げられている
そのため、エージェントが次に触れ始めた瞬間に:
支払い
注文
メール
ブラウザ操作
外部システム
…不確実な完了は、スタック内の最も重要な本番(production)課題の1つになります。
最後に
最も怖いエージェントの失敗は、多くの場合:
「モデルが間違った選択をした」
ではありません。
そうではなく:
「モデルが正しい選択を2回やってしまった」
そして、その理由が知能(intelligence)の失敗であることは通常ありません。
それは:
不確実な完了のもとでの実行境界の欠如
関連
実行側のパターンについて、こちらに最初の文章を書きました:
AIエージェントのための実行ガード・パターン(The Execution Guard Pattern for AI Agents)
https://dev.to/azender1/the-execution-guard-pattern-for-ai-agents-23m9
また、このアイデアに基づいたPythonのリファレンス実装も作っています:

