◉ANTIGRAVITY LABEN
記事一覧/Antigravity 基本
◉ Antigravity 基本/2026-04-25上級

Antigravity の Retry を本番品質で設計する — 冪等性・バックオフ・コスト上限・失敗トリアージ

Antigravity エージェントの Retry を趣味レベルから本番品質に引き上げるための設計図。冪等性、指数バックオフ、コスト上限、失敗トリアージ、チェックポイント連動、チームでのポリシー運用まで、実装コードを添えて全工程を解説します。

Antigravity386retry8本番運用17冪等性8コスト管理10エージェント74

✦ プレミアム記事

Antigravity エージェントが途中で落ちたとき、Retry ボタンを押し続けて同じ場所で詰まる、という経験をされた方は多いのではないでしょうか。個人プロジェクトであれば「もう一回回す」で済むかもしれません。しかし、クライアント案件の本番環境や、自分の稼働プロダクトでエージェントを自動実行しているとき、この素朴な Retry は静かに牙を剥きます。同じ失敗が 20 回続けば、トークン代は 20 倍です。副作用のある処理(メール送信、決済、データ書き込み)を Retry してしまえば、被害は金額だけでは終わりません。

私も個人開発の壁紙アプリの運用スクリプトを夜間に回していて、朝起きたら想定の 5 倍の API コストが立っていたことがあります。その経験から学んだのは、Retry は「機能」ではなく「設計対象」だということです。以下では、冪等性・バックオフ・コスト上限・失敗トリアージという 4 本柱に分けて、実装コードと手元で測った数字を添えながら組み立てていきます。読み終わる頃には、自分のプロジェクトに今日から差し込める再実行フローが手元にできているはずです。

Retry が「運試し」から「設計」に変わる瞬間

多くの開発者にとって、最初の Retry は UI ボタンです。Antigravity の Manager Surface や CLI を開き、失敗したタスクに Retry を押します。これは開発中のインタラクティブな使い方としては正しいのですが、「誰かが見ていない時間に動くエージェント」に対しては不十分です。

本番品質の Retry に求められる条件は、次の 4 つに集約できます。

  • 冪等性(Idempotency): 同じ入力で何回実行しても、副作用は 1 回だけに留まること
  • 指数バックオフとジッター: 外部依存の過負荷を悪化させない再試行間隔
  • コスト上限(Cost Ceiling): トークン・API 呼び出し回数・金額の上限を事前に決めておくこと
  • 失敗トリアージ: 再試行すべきエラー、即座に止めるべきエラー、人間にエスカレートするエラーの区別

この 4 つを揃えていないエージェントを自動化フローに乗せるのは、ブレーキの効かない車で高速道路に入るようなものです。逆に、この 4 つさえ設計できていれば、夜中に Antigravity のスケジュールタスクを回しても、朝の珈琲を落ち着いて飲めます。以降、それぞれを順に組み立てていきましょう。

冪等性(Idempotency)を設計する — 同じ入力でも副作用を2度起こさない

Retry 設計で最も誤解されやすいのがここです。「ただ関数を呼び直すだけ」と思うかもしれませんが、エージェントは外部の世界に対して副作用を起こします。ファイル書き込み、API 呼び出し、決済、メール、DB 更新。これらを 2 度走らせないために、エージェントが扱うすべての副作用アクションに「このアクションはすでに実行済みか?」を判定できる仕組みを持たせます。

実装パターンはシンプルです。アクションごとに一意の Idempotency Key を生成し、実行前にキーで重複チェックを行います。TypeScript での最小実装例を示します。

// src/retry/idempotency.ts
// エージェントが起こす副作用を、冪等キーで守るためのラッパー。
// 実行前にキーをチェックし、完了したキーは結果付きで 24 時間保存する。
 
import { createHash } from "node:crypto";
 
type ExecutionResult<T> = {
  status: "completed" | "failed";
  data?: T;
  error?: string;
  completedAt: string;
};
 
export class IdempotencyGuard {
  // 本番では Redis / KV を使うこと。ここでは学習目的でメモリ実装。
  private store = new Map<string, ExecutionResult<unknown>>();
 
  private makeKey(action: string, payload: unknown): string {
    const body = JSON.stringify({ action, payload });
    return createHash("sha256").update(body).digest("hex").slice(0, 32);
  }
 
  async run<T>(
    action: string,
    payload: unknown,
    execute: () => Promise<T>,
  ): Promise<T> {
    const key = this.makeKey(action, payload);
    const cached = this.store.get(key);
 
    if (cached?.status === "completed") {
      // 2 回目以降は保存済みの結果をそのまま返す。副作用は実行しない。
      return cached.data as T;
    }
 
    try {
      const data = await execute();
      this.store.set(key, {
        status: "completed",
        data,
        completedAt: new Date().toISOString(),
      });
      return data;
    } catch (err) {
      // 失敗は記録するが、キーには結び付けない。
      // 次回は入力が同じでも再実行される。
      this.store.set(key, {
        status: "failed",
        error: err instanceof Error ? err.message : String(err),
        completedAt: new Date().toISOString(),
      });
      throw err;
    }
  }
}
 
// 使い方
const guard = new IdempotencyGuard();
await guard.run("send_welcome_email", { userId: "u_123" }, async () => {
  await mailer.send({ to: "user@example.com", template: "welcome" });
  return { queued: true };
});
// → 1 回目はメール送信、2 回目以降は送信せずに { queued: true } を返す

期待する出力としては、同じ action + payload の組み合わせで 2 回目以降を呼び出しても、メール送信が走らず即座に { queued: true } が返ることを必ずテストで確認してください。これが Retry 設計の土台です。

なぜキーを「アクション名+入力のハッシュ」にするか

タスク ID や UUID を Idempotency Key に使ってしまうと、エージェントが「同じ意図の処理」を別 ID で何度も投げてしまった時に、すべて別物として扱われます。アクション名と入力の本質的な内容からハッシュを作ることで、「同じ仕事を同じ条件でやろうとしている」ことを検知できます。これは決済 SDK(Stripe の Idempotency Keys)と同じ設計思想です。

本番ストレージでの注意点

メモリストアは再起動で消えるので、本番では必ず外部ストレージを使います。Cloudflare Workers であれば KV、Firebase を使っているなら Firestore の単一ドキュメント + TTL、Redis なら SET key value NX EX 86400 で一発です。TTL は 24〜72 時間が現実的で、これより短いと再実行時に二重送信、長すぎるとストレージが肥大化します。

✦

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

この記事の続きを読む

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

この記事で得られること
✦Retry を押すたびに失敗していた読者が、冪等性・バックオフ・コスト上限を備えた再実行フローを自分のプロジェクトに組み込めるようになります
✦エラーを transient / permanent / ambiguous の 3 分類に落とし込み、再試行するか人間に渡すかを自動判定する失敗トリアージを実装できます
✦エージェントの暴走で課金が跳ねる事故を防ぐ、コスト上限・チェックポイント・アラートを組み合わせた運用設計を手に入れられます
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

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

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

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

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

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

関連記事

◉ Antigravity 基本2026-09-02
部分一致のファイル名検索が、エラー文字列にだけ当たらない理由
Antigravity 2.12 で部分一致のファイル名検索が改善されました。手元の 2,088 ファイルのリポジトリで名前引きと全文引きを測ったところ、読む量は 67 倍、エラー文字列の当たり方は 4.5% でした。切り替えの境目を数字で置き直します。
◉ Antigravity 基本2026-10-16
「Antigravity server crashed unexpectedly」が出たとき、CPU・WSL・版のどれを先に疑うか
画面は開くのにエージェントだけ即座に落ちる「server crashed unexpectedly」を、CPU の AES 対応・WSL や SSH の経路・版の三つに分けて切り分ける手順です。フォーラムと Issue の報告を整理し、確定していないことは確定していないと分けて書きました。
◉ Antigravity 基本2026-10-15
プロジェクトの削除ボタンを押す前に、手元に残るものを 3 つ言えるか確かめる
Antigravity 2.0 のプロジェクト削除でソースコードは消えるのか。コミュニティの説明を二つの保存場所に分けて読み直し、何も消さずに残るものを確かめる小さなスクリプトと、容量を空けるときの順番をまとめます。