◉ANTIGRAVITY LABEN
記事一覧/Agents & Manager
◈ Agents & Manager/2026-06-20上級

失敗したエージェントジョブを取りこぼさない — デッドレターと再投入の設計

夜間のスケジュール実行で失敗したエージェントジョブが静かに消えていく問題を、デッドレター退避と3階層の再投入で防ぐ設計をまとめました。二重実行を避ける冪等キーの持たせ方や、朝5分で終わる確認手順など、複数サイト自動運用の実例に基づいています。

Antigravity411エージェント77信頼性設計8スケジュール実行10デッドレター

✦ プレミアム記事

夜のうちに走らせたエージェントが、朝になると「成功5件・失敗0件」と報告してくる。ところが実際にサイトを開くと、3サイト分の更新がどこにも反映されていない。私自身、個人開発で4つのブログを毎日オフピークに分散して自動更新していますが、この「静かな失敗」に何度も足をすくわれてきました。

失敗そのものより怖いのは、失敗が記録されないまま消えることです。スケジュール実行のエージェントは、誰も見ていない時間帯に動きます。例外を握りつぶして 0 件と返した瞬間、その仕事は存在しなかったことになります。デッドレターは、この「なかったことにされる失敗」を必ず一箇所に集めるための仕組みです。

なぜ「失敗0件」が嘘になるのか

最も多い原因は、ループの中で例外を try/except で飲み込み、ログにも残さずに次へ進む書き方です。Antigravity のエージェントをスクリプトから起動する場合も同じ罠が待っています。タイムアウト、レート制限、トークン期限切れ、ネットワークの瞬断——どれも一過性に見えるため、つい「次回拾えばいい」と素通りしてしまいます。

ところが次回も同じ条件なら、同じ場所で同じように落ちます。落ちたジョブはキューから消え、再投入の手がかりも残りません。私の場合、AdMob のレポート取得を任せたジョブが週末の3日間ずっと無言で落ちていて、月曜にダッシュボードの数字が飛んでいて初めて気づいた、という経験があります。

設計の出発点は単純です。失敗は捨てるのではなく、退避させる。これだけで運用の見通しが大きく変わります。

デッドレターに「何を」残すか

退避先に最低限残すべき情報は、再投入したときに同じ仕事を再現できるだけのコンテキストです。エラーメッセージだけでは足りません。次の項目を1行1レコードの JSON Lines で追記していくと、後から grep や jq で扱いやすくなります。

フィールド役割
job_id同じ仕事を一意に識別する(再投入の重複防止に使う)
payloadジョブを再現するための入力一式
error_class例外の型。再投入の可否を分岐させる鍵になる
attemptこれまでの試行回数
failed_at失敗時刻(UTCで統一して保存する)

実装は驚くほど短く済みます。append-only にしておくと、複数のエージェントが同時に書いても行が壊れにくく、運用が楽になります。

import json, os, datetime, fcntl
 
DLQ_PATH = os.path.expanduser("~/agent/dead_letter.jsonl")
 
def to_dead_letter(job_id: str, payload: dict, exc: Exception, attempt: int) -> None:
    record = {
        "job_id": job_id,
        "payload": payload,
        "error_class": type(exc).__name__,
        "message": str(exc)[:500],
        "attempt": attempt,
        "failed_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
    }
    os.makedirs(os.path.dirname(DLQ_PATH), exist_ok=True)
    with open(DLQ_PATH, "a", encoding="utf-8") as f:
        fcntl.flock(f, fcntl.LOCK_EX)
        f.write(json.dumps(record, ensure_ascii=False) + "\n")
        fcntl.flock(f, fcntl.LOCK_UN)

ここで error_class をきちんと残しておくと、後段の再投入で「これは待てば直る失敗か、人が見るべき失敗か」を機械的に振り分けられます。これが次の階層設計の土台になります。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦失敗ジョブを握りつぶさず JSON Lines のデッドレターに退避する具体的な実装(30行)
✦再投入を即時・遅延・手動の3階層に分け、無限リトライと取りこぼしの両方を避ける判断基準
✦4サイトを毎日オフピークで回す運用で、失敗の見落としをゼロに近づけたチェック手順
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

◈ Agents & Manager2026-10-22
引き継ぎ文書の古い参照は 17 件に見えて実際は 2 ファイルでした。本当に危なかったのは、別のサイトの手順書が混ざっていたことでした
エージェントに読ませるリポジトリ直下の .md を点検する Python スクリプトの全文です。素朴な版は壊れた参照を 17 件と数え、直すと 7 件、実体は 2 ファイル。別の問題が見つかるまでの過程を残します。
◈ Agents & Manager2026-10-16
エージェントに .zip を渡す前に、.git を除いて 29 MB を 15 MB にし、秘密情報の警告 28 件を見分けました
Antigravity アプリ v2.23.0 で .zip を添付できるようになりました。自分のリポジトリを実際に固めて .git の重さと秘密情報検査の誤検知を数え、除外・検査・マニフェストを一度に行う Python スクリプトの全文を残します。
◈ Agents & Manager2026-09-08
/boost が「検証済み」と返してきたとき、その worktree に何が無かったのかを先に数えています
Antigravity の /boost は使い捨ての隔離ワークツリーでテストを走らせます。手元のビルドが git に入っていないファイルへ依存していると、その検証は別の木の上で通ります。ずれを先に数える手順を書き残します。