AIエージェントを業務に入れると、「失敗したらもう一度実行すればよい」と考えがちです。けれど、再実行は単なるリトライではありません。途中まで file edit した、PR comment を投稿した、MCP 経由で issue を更新した、承認待ちで一晩止まった、外部 API は成功したが agent は失敗扱いにした。こういう状態で同じ prompt をもう一度投げると、二重実行、古い state の再利用、別 branch への上書きが起きます。
この記事では、AIエージェントの 再実行設計 を扱います。1回の run に何を渡すかは AIエージェントのコンテキスト設計ガイド、session をまたいで何を残すかは AIエージェントメモリ設計ガイド、事故後の停止と復旧は AIエージェント停止手順ガイド、作業完了時の返し方は AIエージェント出力契約設計ガイド に分けています。
今回の論点は、途中で止まった作業を、どの単位なら安全にやり直せるかです。
先に結論: retry する前に作業単位を分ける
AIエージェントの retry は、同じ prompt を再投入することではありません。
私なら、再実行できる単位を最初に次の5層へ分けます。
| 層 | 例 | 再実行方針 |
|---|---|---|
| read | docs検索、repo調査、log確認 | 原則そのまま再実行可 |
| draft | patch案、PR本文案、設計案 | sandbox内なら再生成可 |
| local write | file edit、format、test | branch / worktree / diff を見て再開 |
| external write | GitHub comment、issue更新、MCP write | idempotency key なしで再実行しない |
| irreversible action | deploy、顧客通知、課金、権限変更 | retry ではなく人間承認と復旧手順へ回す |
この分類を持たずに「もう一度やって」と言うと、agent は失敗前の状態を知らないまま動きます。人間には「さっきの続き」のつもりでも、agent から見ると新しい作業です。再実行の前に、どの層まで完了し、どの層からやり直すのかを決めます。
既存記事との役割分担
近いテーマが多いので、責務を先に切ります。
| 近いテーマ | 扱うこと | この記事で扱うこと |
|---|---|---|
| context engineering | run 開始時に何を渡すか | 失敗後に何を再利用し、何を捨てるか |
| memory design | session をまたぐ保存と削除 | retry 判断に必要な短期 state |
| incident response | 事故後に止めて復旧する | 事故にする前の安全なやり直し |
| runtime monitoring | 稼働中の異常検知 | retry loop を設計で防ぐ |
| output contract | 完了時に何を返すか | 未完了時にどこから再開できるか |
再実行設計は、memory 設計の一部ではありません。長期記憶ではなく、作業の進行状態、承認状態、外部副作用、再開可能地点を扱う運用設計です。
retry packet を残す
AIエージェントに再実行させるなら、失敗時の返却を自由文にしない方がよいです。
最小限、次の retry_packet を残します。
retry_packet:
run_id: 20260630-billing-fix-01
task: "billing retry の不具合を修正する"
last_known_state:
branch: "fix/billing-retry"
worktree: ".codex-worktrees/billing-retry"
changed_files:
- "src/billing/retry.ts"
- "src/billing/retry.test.ts"
verification:
- command: "pnpm test src/billing/retry.test.ts"
status: "failed"
failure: "expected retryCount to be 1, received 0"
completed_steps:
- "仕様確認"
- "再現テスト追加"
pending_steps:
- "実装修正"
- "単体テスト"
- "PR作成"
external_effects:
- type: "github_comment"
status: "not_started"
retry_from: "implementation_fix"
これは監査ログほど重くなくてよいです。目的は、次の run が「何をやり直し、何を繰り返してはいけないか」を判断できることです。
checkpoint は git と agent state で分ける
checkpoint という言葉は便利ですが、何を保存しているかを曖昧にすると危険です。
| checkpoint | 保存するもの | 戻せないもの |
|---|---|---|
| git commit | code diff、生成ファイル | 外部API、MCP write、会話状態 |
| worktree | 作業中の filesystem | 投稿済み comment、承認状態 |
| agent session | 会話履歴、tool結果、承認待ち state | Git の正しい履歴 |
| audit log | 実行証跡、承認、外部操作 | 作業再開に必要な文脈全文 |
| external idempotency record | 外部操作の重複防止 key | local patch の意味 |
Claude Code や Codex のような coding agent では、git checkpoint と agent session を混ぜない方が安全です。git は差分を戻すための仕組み、agent state は作業の続きを理解するための仕組みです。どちらか片方だけで再実行できるとは考えません。
私なら、write 権限を持つ agent には次の3点を必ず残します。
- branch / worktree / base commit
- changed files と未検証の差分
- 外部 side effect の有無
この3つが無い run は、続きから再開せず、新しい worktree で調査からやり直した方が安全です。
OpenAI Agents SDK の state は durable だが万能ではない
OpenAI Agents SDK の Sessions は、同じ session に会話履歴を保持し、複数 run をまたいで context を続けられます。Human-in-the-loop では、tool approval で止まった結果を RunState に変換し、approve / reject 後に同じ state から再開できます。長時間承認では RunState を JSON や文字列として保存して後で復元する設計も用意されています。
これは強力ですが、業務上は注意が必要です。
- serialized state に secret や顧客情報を混ぜない
- prompt / tool definition / policy version を state と一緒に記録する
- 承認待ちの間に tool schema が変わったら、そのまま再開しない
- agent state だけで外部操作の二重実行を防げると思わない
特に最後が重要です。run state が再開できても、外部サービス側で同じ操作を二度受け付けるなら事故になります。state の durable 化と、side effect の idempotency は別問題です。
外部 write は idempotency key を持たせる
AIエージェントの再実行で一番危ないのは、外部 write です。
たとえば、次の操作は二重実行の影響が出ます。
- GitHub issue に comment を投稿する
- Slack / Teams に通知する
- Notion / CRM / ticket を更新する
- deploy を開始する
- package publish や release note を出す
- 課金、返金、権限変更に関わる API を呼ぶ
Temporal の docs でも、Activity は retry され得るため idempotent に設計することが推奨されています。AIエージェントでも同じです。外部 write は「成功したか不明」の状態が必ず起きるので、再実行時に同じ操作だと識別できる key を持たせます。
external_action:
action: "github_issue_comment"
target: "nidoneko/HP#123"
idempotency_key: "run_20260630_billing_fix_comment_1"
desired_state:
marker: "<!-- ai-agent:run_20260630_billing_fix_comment_1 -->"
body_hash: "sha256:..."
retry_policy:
before_retry:
- "same marker comment が既にあるか確認する"
- "body_hash が同じなら投稿しない"
- "body_hash が違うなら人間確認へ戻す"
GitHub comment のように API が専用 idempotency key を持たない場合でも、comment marker、dedupe table、correlation id、target resource の current state で近いことはできます。大事なのは、agent に「同じことをもう一度やらせる」前に、外部側の状態を読むことです。
retry policy を tool risk tier とつなぐ
再実行ルールは、tool risk tier と分けて書かない方がよいです。
| risk tier | retry 方針 |
|---|---|
| read | 自動 retry 可。ただし rate limit と freshness を見る |
| inspect | 自動 retry 可。結果差分が大きい場合は要約を捨てる |
| draft | 同じ入力なら再生成可。古い draft は明示的に破棄 |
| write | worktree / diff / test 状態を見て条件付き retry |
| external action | idempotency key と target state 確認後だけ retry |
| forbidden | retry しない。依頼を分解するか人間へ戻す |
AIエージェント tool risk tier 設計ガイド で分類した tier を、承認や監査だけでなく retry にも渡すと運用が揃います。risk tier が無い retry は、便利そうに見えて危険です。
retry loop を検知して止める
retry 設計では、成功条件だけでなく停止条件も必要です。
よくある失敗は、agent が同じ tool、同じ error、同じ修正を繰り返すことです。
retry_guard:
stop_if:
- "same command fails 3 times with same error"
- "same file is edited and reverted twice"
- "same external action is requested twice without new evidence"
- "base branch changed after retry started"
on_stop:
next_action: "human_review"
required_output:
- "last 3 attempts"
- "common failure signature"
- "proposed smaller next step"
この guard は AIエージェント本番監視設計ガイド とつながります。監視側で retry loop を検知し、retry packet 側で次に何を見ればよいかを返す。この分担にすると、失敗した run を救いやすくなります。
MCP session と agent retry を混同しない
MCP Streamable HTTP の session は、client と server の論理的なやり取りを束ねるものです。仕様では、server は MCP-Session-Id を返せます。client は以後の request にそれを含め、server が session を終了した場合は 404 を返し、client は session ID なしで再初期化します。不要になった session は DELETE で終了できます。
これは transport / server state の話です。AIエージェントの業務 retry とは別です。
混同すると、次の事故が起きます。
- MCP session を再初期化しただけで、外部操作も戻ったと思う
- agent run を再実行しただけで、MCP server 側の購読状態も整ったと思う
MCP-Session-Idが同じなら、業務上の idempotency も担保されたと思う
MCP session は通信状態の境界です。業務上の二重実行防止は、target resource、idempotency key、audit log、approval state で別に持ちます。
実務での導入順
小さく始めるなら、次の順で十分です。
- write / external action を含む agent だけ対象にする
- 失敗時に
retry_packetを返させる - worktree、branch、base commit、changed files を必須項目にする
- 外部 write には correlation id か marker を付ける
- 同じ失敗を3回繰り返したら止める
- 承認待ち state には policy / tool / prompt version を添える
- retry できない操作は incident runbook へ逃がす
最初から durable workflow engine を作る必要はありません。むしろ、最初に必要なのは「どこからやり直してよいか」を人間と agent が同じ言葉で言えることです。
まとめ
AIエージェントの再実行設計は、失敗に強くするための地味な設計です。派手な自動化より先に、retry、checkpoint、idempotency、state、外部 side effect の境界を決める必要があります。
context engineering は入力を整えます。memory design は長期保存を整えます。incident response は事故後の停止と復旧を扱います。再実行設計はその間にあり、失敗した作業を事故へ広げず、次の小さい単位へ戻すための設計です。
私なら、write 権限を持つ AIエージェントには必ず retry_packet、base commit、external side effect list、retry guard を持たせます。これが無い agent に、PR comment、MCP write、deploy、顧客通知を任せるのはまだ早いです。