AIエージェントを組織で使うと、「失敗したからもう一回投げる」が一番危ない運用になりがちです。ビルドが落ちた、tool が失敗した、MCP 経由の情報が古かった、承認待ちで止まった、PR はできたが根拠が弱い。こうした失敗を全部「モデルが間違えた」で片付けると、次の run でも同じ失敗を繰り返します。
この記事では、AIエージェントの 失敗分類 を扱います。本番投入前に何を評価するかは AIエージェント評価設計ガイド、稼働中に何を検知するかは AIエージェント本番監視設計ガイド、後から何が起きたかを説明する証跡は AIエージェント監査ログ設計ガイド、失敗後にどう安全にやり直すかは AIエージェント再実行設計ガイド に分けています。
今回の論点は、失敗した run を見たあと、prompt、context、tool、権限、MCP、data、environment のどこを直すべきかを決めることです。
先に結論: failure reason を自由文で残さない
AIエージェントの失敗報告を、次のような自由文のまま残すのは弱いです。
うまくいきませんでした。再実行してください。
これでは、再実行すべきなのか、依頼を切り直すべきなのか、tool schema を直すべきなのか、権限を狭めるべきなのか分かりません。
私なら、最初は次の7分類だけで十分だと考えます。
| 分類 | 典型例 | 戻す場所 |
|---|---|---|
prompt_failure | 依頼が曖昧、完了条件がない | task intake / prompt |
context_failure | 古い仕様、不要なログ、前回の誤判断を渡した | context packet |
tool_contract_failure | tool 名、引数、戻り値、retry 可否が曖昧 | tool schema |
permission_failure | write 権限、MCP scope、外部送信の許可が粗い | approval / policy |
mcp_boundary_failure | 未信頼 resource、token、server 由来の混線 | MCP catalog / security rule |
data_evidence_failure | 根拠不足、参照元の日付違い、検証不足 | evidence / verification |
environment_failure | dependency、cache、branch、CI 環境が古い | execution environment |
分類名はこれで固定でなくてよいです。重要なのは、失敗を「AI が悪い」に丸めず、次に直す設計面へ接続できる粒度にすることです。
trace から分類し、最終回答だけで判断しない
失敗分類は、最終回答だけを読んで決めるものではありません。
OpenAI Agents SDK の tracing は、agent run の中で LLM generation、tool call、handoff、guardrail などを trace / span として追える設計になっています。OpenTelemetry の GenAI semantic conventions も、model request、response、tool call、MCP などを観測語彙として揃える方向に進んでいます。
つまり、AIエージェントの失敗分類では、次の順で見るべきです。
- 依頼文と完了条件
- 渡した context と memory
- 選ばれた tool と引数
- tool result と error
- guardrail / approval の停止点
- MCP server、scope、resource の出所
- 最終回答と実際の成果物
最終回答だけを見ると、build failed も permission denied も wrong branch も同じ「失敗」に見えます。trace と成果物を合わせて初めて、分類できます。
failure taxonomy を run ごとに持たせる
失敗分類は、ドキュメントだけでなく run の出力に含めます。私は次のような小さい schema から始めます。
failure_taxonomy:
run_id: "agent-run-20260814-001"
primary_failure: "tool_contract_failure"
secondary_failures:
- "data_evidence_failure"
failed_stage: "tool_call"
observed_signal:
- "update_issue accepted comment_body but tool description did not say it posts externally"
- "agent retried after timeout without idempotency key"
impact:
external_write: "possible_duplicate_comment"
code_change: "none"
next_fix:
owner: "platform-ai"
change:
- "split create_draft_comment and post_comment"
- "add retry_safe=false to external write tools"
- "require idempotency_key for GitHub comment tool"
rerun_allowed: false
ここで大事なのは、primary_failure を1つに絞ることです。失敗には複数の原因が絡みますが、最初に直す場所を決めないと対策が散ります。
たとえば「PRコメントが二重投稿された」は、表面的には retry 失敗です。しかし根本は、外部 write tool に idempotency key がなく、retry してよいかも tool schema に書かれていないことかもしれません。この場合、primary_failure は tool_contract_failure にします。
prompt failure: 依頼の曖昧さをモデル品質にしない
prompt_failure は、依頼そのものが作業に耐えない状態です。
このPRをいい感じに直して
この依頼では、対象範囲、完了条件、触ってよいファイル、禁止操作、検証コマンド、PR へ戻す形式が分かりません。AIエージェントが勝手に調査を広げたり、関係ない refactor を始めたりしても不思議ではありません。
私なら、次のどれかが欠けていたら prompt_failure にします。
| 欠けているもの | 事故り方 |
|---|---|
| goal | 何を終わりとするかがぶれる |
| scope | 依頼外のファイルに広がる |
| stop rule | 判断不能でも進む |
| verification | 「直したつもり」で終わる |
| output contract | 人間が次に何を見るか分からない |
この分類の対策は、モデルを変えることではありません。依頼受付の型を直します。特に automation や scheduled run では、曖昧な依頼をそのまま実行せず、clarification か refusal に戻す方が安定します。
context failure: 渡した情報が多すぎる、古すぎる、混ざっている
context_failure は、依頼は正しいが、agent に渡した文脈が悪い状態です。
よくあるのは次です。
- 古い仕様メモを memory から読んだ
- 前回の失敗手順を「成功パターン」として渡した
- production と staging のログを同じ context に入れた
- 依頼と関係ない社内ルールが長すぎて、重要な禁止事項が埋もれた
- 顧客データ、MCP resource、public docs の出所が混ざった
この失敗は、最終回答だけを見るとモデルの推論ミスに見えます。しかし実際には、入力側で state が壊れています。
私なら、context_packet に次の欄を持たせます。
context_packet:
current_state:
source: "issue-123"
updated_at: "2026-08-14T09:00:00+09:00"
excluded_context:
- "old incident notes before 2026-07-01"
- "customer logs unrelated to checkout"
evidence_priority:
- "current branch diff"
- "latest CI log"
- "official docs"
失敗後に context_failure と分類したら、同じ prompt を投げ直す前に context を削ります。AIエージェントは情報が多いほど正しくなるわけではありません。
tool contract failure: tool はあるが、操作契約が曖昧
tool_contract_failure は、AIエージェントに tool は渡しているが、選び方、引数、戻り値、失敗時の扱いが曖昧な状態です。
MCP の tools 仕様では、tool result は structured / unstructured content を持てます。だからこそ、戻り値を「人間が読める文章」だけにせず、agent が次の判断に使える構造へ寄せる必要があります。
たとえば、次の tool は危険です。
name: update_ticket
description: "チケットを更新する"
input:
text: string
これでは、comment draft を作るのか、外部 ticket に投稿するのか、既存本文を書き換えるのか分かりません。
失敗分類では、次の兆候があれば tool_contract_failure と見ます。
| 兆候 | 直すもの |
|---|---|
| agent が似た tool を取り違えた | tool name / description |
| 不正な引数で tool を呼んだ | input schema |
| 成功と部分成功を区別できない | output schema |
| timeout 後に二重実行した | retry policy / idempotency |
| write tool を read tool のつもりで使った | risk metadata |
対策は prompt の注意書きではなく、tool の契約を狭くすることです。create_draft_comment と post_comment を分ける。retry_safe を返す。外部 write には idempotency_key を必須にする。これだけで、失敗の再発率はかなり下がります。
permission failure: 許可の粒度が粗い
permission_failure は、agent の判断以前に、許可境界が荒い状態です。
たとえば、次のような失敗です。
- read のつもりで渡した MCP scope が write も含んでいた
- shell 実行は許可したが、network access の行き先を絞っていなかった
- approval は出たが、承認者が何を承認したか説明できない
askで止めるべき外部 action が自動実行された- 一時的な例外 permission が期限切れにならず残った
この分類では、「agent がその操作を選んだこと」だけを責めません。そもそも選べる状態にしてよかったのかを見ます。
失敗後の修正先は、prompt ではなく policy です。
permission_fix:
before:
mcp_scope: "repo:read repo:write"
shell_network: "allowed"
after:
mcp_scope: "repo:read"
shell_network: "deny_by_default"
write_operations:
approval_required: true
approver_role: "repo_owner"
特に AIエージェントでは、承認を「一度OKしたら続きは自由」にしない方がよいです。承認は操作ごとの外部影響に紐づけます。
mcp boundary failure: server と resource の出所を混ぜる
mcp_boundary_failure は、MCP server、resource、tool、token、scope の境界が崩れた状態です。
MCP の Security Best Practices は、scope minimization、token passthrough 禁止、confused deputy、session hijacking、未信頼入力などを扱っています。実務では、MCP で取れた情報を全部「tool result」として同じ信頼度にしてしまうのが危険です。
たとえば、次は別物です。
| MCP 由来の情報 | 扱い |
|---|---|
| 社内DBの確定値 | 権限付き internal data |
| GitHub issue の本文 | user-controlled content |
| Web検索結果 | untrusted external content |
| server が返す tool description | reviewed metadata ではない可能性 |
| OAuth token | agent context に入れない secret |
この分類では、次を確認します。
- どの MCP server から来た情報か
- その server は catalog で許可済みか
- どの scope で呼ばれたか
- resource は user-controlled か
- tool result をそのまま次の write に使ったか
- token や credential が context / log に入っていないか
mcp_boundary_failure の対策は、MCP を禁止することではありません。server catalog、scope、tool annotation、approval、prompt injection 対策を同じ分類語彙でつなぐことです。
data evidence failure: 根拠不足を成功扱いしない
data_evidence_failure は、作業自体は進んだが、根拠や検証が弱い状態です。
よくあるのは次です。
- 公式 docs ではなく古いブログだけを根拠にした
- 参照した docs の日付や version が対象と違う
- CI log の一部だけを読んで root cause と決めた
- build を走らせず、静的に見て通ると判断した
- 手動確認が必要なのに、最終回答で触れていない
NIST AI RMF は、AI リスク管理において govern、map、measure、manage を反復的に扱い、文脈把握や測定、文書化を重視します。AIエージェント運用でも同じで、根拠が追えない成功は、次の改善に使えません。
私なら、最終報告に次のいずれかが欠けていたら data_evidence_failure を付けます。
evidence_gate:
sources:
- url: "official docs or current repo file"
checked_at: "2026-08-14"
used_for: "API behavior"
verification:
- command: "pnpm run build"
result: "passed"
unresolved:
- "production data was not inspected"
根拠不足のまま再実行すると、agent は別の仮説を作って進むだけです。先に evidence gate を満たします。
environment failure: 実行場所の問題をモデル問題にしない
environment_failure は、agent の判断ではなく、実行環境が壊れている状態です。
- branch が古い
- dependency cache が壊れている
- lockfile と node_modules がずれている
- CI と local の Node / pnpm / Python version が違う
- secret や env var が setup されていない
- sandbox で必要な network が閉じている
この失敗をモデル問題として扱うと、prompt をいくら直しても改善しません。
失敗分類では、次のように「再実行してよい環境か」を先に返します。
environment_check:
branch: "agent/fix-checkout"
base: "origin/main@abc123"
dependencies: "installed"
required_env:
- name: "TURSO_DATABASE_URL"
status: "missing"
rerun_allowed: false
next_action: "prepare_environment"
CI failure digest や nightly automation では、この分類がかなり効きます。環境が壊れている run を agent に何度も読ませても、失敗ログが増えるだけです。
失敗分類を次の改善へ戻す
分類はレポートのためではありません。次の修正先を決めるために使います。
| primary failure | まずやること | まだ再実行しない条件 |
|---|---|---|
prompt_failure | task template を直す | goal / scope / verification がない |
context_failure | context を削る、出所を分ける | 古い memory が混ざる |
tool_contract_failure | schema / retry / output を直す | external write が idempotent でない |
permission_failure | policy / approval を直す | write scope が広い |
mcp_boundary_failure | catalog / scope / resource handling を直す | untrusted resource を write に渡す |
data_evidence_failure | source / verification を追加 | 根拠が公式・現行でない |
environment_failure | branch / dependency / env を直す | required env が欠けている |
ここを曖昧にすると、「もう一回やって」で事故が増えます。逆に分類があると、再実行前に直す場所が決まります。
eval と監視へ戻す
本番で起きた失敗は、その場のメモで終わらせません。失敗分類ごとに、eval、monitoring、policy へ戻します。
feedback_loop:
failure: "mcp_boundary_failure"
observed_in: "production weekly report automation"
new_eval_case:
name: "untrusted_issue_body_must_not_trigger_write"
expected: "ask_human_before_external_write"
monitoring_rule:
signal: "mcp_resource_to_write_without_approval"
severity: "high"
policy_update:
rule_id: "MCP-WRITE-002"
change: "user-controlled MCP resources cannot directly feed write tools"
OWASP の AI Agent Security Cheat Sheet も、過去に観測した injection、memory poisoning、tool abuse などを回帰テストへ戻す考え方を示しています。AIエージェントの失敗は、一回限りの運用ミスではなく、次の eval dataset と runtime guard の材料にします。
実務で使う最小チェックリスト
最初から大きな taxonomy を作る必要はありません。私は、失敗した run ごとに次の10項目だけを確認します。
- 失敗はどの stage で起きたか
- primary failure は1つに絞れるか
- secondary failure は何か
- 外部 write は発生したか
- MCP server / scope / resource は特定できるか
- tool の retry 可否は明示されていたか
- 根拠 source は現行か
- 検証コマンドは実行されたか
- 同じ条件で再実行してよいか
- eval / monitoring / policy のどこへ戻すか
これだけでも、AIエージェントの失敗対応はかなり変わります。
よくある失敗
1. すべて prompt で直そうとする
prompt は重要ですが、tool schema、permission、MCP scope、環境の問題は prompt だけでは直りません。分類を持たないチームほど、注意書きだけが増えます。
2. retry と再設計を混ぜる
一時的な network timeout は retry でよい場合があります。しかし external write、古い context、曖昧な tool contract は、再設計してから再実行します。
3. 成功ログだけ残す
成功より失敗の方が設計改善に使えます。失敗分類、失敗 stage、直した設計面を残さないと、同じ事故が別の agent で起きます。
4. MCP 由来の情報を全部同じ信頼度にする
MCP は便利ですが、server、resource、scope、token、tool result の出所が違います。分類なしで write に流すと、prompt injection や権限混線が起きます。
5. environment failure を AI の推論失敗にする
依存関係や branch が壊れているなら、agent の reasoning を直す前に環境を直します。失敗分類に environment_failure を入れる理由はここです。
まとめ
AIエージェントの失敗分類は、障害報告をきれいに書くための分類表ではありません。次の run を安全にするための routing table です。
失敗したら、まず prompt、context、tool contract、permission、MCP boundary、data evidence、environment のどこへ戻すかを決めます。再実行はその後です。
この順番にすると、AIエージェント運用は「失敗したらもう一度」から、「失敗を分類し、設計へ戻し、eval と監視へ接続する」運用に変わります。便利な自動化を増やす前に、失敗の戻し先を増やす方が強いです。