GEMINI LABEN
MODEL — Gemini 3.5 Flashが一般提供となり、gemini-flash-latestの実体になりましたAPI — Interactions APIが一般提供となり、Geminiモデルとエージェントを扱う主要APIになりましたAGENT — Managed Agentsが公開プレビューで提供され、隔離Linux環境で自律エージェントを動かせますAPI — バックグラウンド実行が加わり、長時間処理を投げて結果を後から受け取れますSEARCH — File Searchがgemini-embedding-2で画像もそのまま検索できるようになりましたNOTICE — 6/19以降、未制限APIキーからのリクエストが遮断されるようになりましたMODEL — Gemini 3.5 Flashが一般提供となり、gemini-flash-latestの実体になりましたAPI — Interactions APIが一般提供となり、Geminiモデルとエージェントを扱う主要APIになりましたAGENT — Managed Agentsが公開プレビューで提供され、隔離Linux環境で自律エージェントを動かせますAPI — バックグラウンド実行が加わり、長時間処理を投げて結果を後から受け取れますSEARCH — File Searchがgemini-embedding-2で画像もそのまま検索できるようになりましたNOTICE — 6/19以降、未制限APIキーからのリクエストが遮断されるようになりました
記事一覧/API / SDK
API / SDK/2026-06-30上級

投げて終了する定期実行で、結果を取りこぼさない — Gemini バックグラウンド実行を再取得台帳で回す設計

Interactions API のバックグラウンド実行を cron 駆動の定期実行で安全に回すための設計です。送信前に冪等キーで台帳へ予約し、次のティックで未取得ハンドルだけを再取得する二段コミットを、動くコードで示します。

Gemini API155Interactions API2バックグラウンド実行冪等性自動運用2

プレミアム記事

Interactions API のバックグラウンド実行が GA に入って、長時間処理を「投げて、後で受け取る」構成が素直に書けるようになりました。私は個人開発で記事生成のパイプラインを定期実行で回していますが、ここで一つ厄介な前提があります。cron で起動するランナーは、処理を投げたあとプロセスごと終了してしまうということです。

つまり、Webhook のように「常駐して通知を待つ」設計も、ループで done を待つポーリングも、定期実行とは噛み合いません。起動 → 投げる → 終了、を繰り返すランナーが、いつどこで完了結果を拾うのか。この一点を詰めないと、バックグラウンド実行は「投げたきり迷子になるジョブ」を量産します。

常駐プロセスも Webhook エンドポイントも持たないまま、cron ティックをまたいで結果を確実に回収する「再取得台帳(reclaim ledger)」の作り方を、動くコードで組み立てていきます。

なぜポーリングでも Webhook でもなく「台帳」なのか

三つの取り方には、それぞれ前提があります。違いを整理しておきます。

方式前提となる実行形態定期実行ランナーとの相性
ループでポーリング処理が終わるまで常駐し続ける悪い(投げたら終了するので待てない)
Webhook で受信公開エンドポイントを常時受け付ける悪い(受け口が常駐前提・個人運用だと運用負荷が高い)
台帳に記録して次ティックで再取得状態を外部に持ち、起動のたびに照合する良い(起動 → 照合 → 終了で完結する)

要は、ランナーが終了しても消えない場所に「投げたジョブの一覧」を置いておき、次に起きたときにその一覧を見て未回収のものだけ取りに行く、という形です。Webhook が「向こうから教えてくれる」のに対し、台帳方式は「自分が起きたときに思い出す」設計だと考えています。個人運用では、公開受け口を維持しなくていいぶん、こちらのほうが壊れにくいと感じています。

設計の核心は「送信」と「台帳書き込み」の順序

素朴に書くと、こうなります。

# アンチパターン: 送信してから台帳に書く
op = client.interactions.create(model="gemini-flash-latest", input=payload, background=True)
ledger.insert(handle=op.name, status="submitted")   # ← ここでクラッシュしたら?

create が成功してから ledger.insert までの間にプロセスが落ちると、API 側にはジョブが存在するのに、台帳にはハンドルが無い状態が生まれます。これが孤児ハンドル(orphan)です。次のティックで台帳を見ても存在しないので、永遠に回収されません。課金は発生しているのに結果は捨てられる、避けたい落とし穴です。これを回避することが、この設計の主眼だと考えています。

そこで順序を逆にします。先に冪等キーで予約行を書き、そのあとで送信し、返ってきたハンドルで予約行を更新します。

# 二段コミット: 予約 → 送信 → ハンドル確定
idem = idempotency_key(job)          # 同じ論理ジョブには同じキー
ledger.reserve(idem)                  # status="reserving" で予約(既存ならスキップ)
op = client.interactions.create(..., background=True)
ledger.bind_handle(idem, op.name)     # status="submitted" + handle 確定

この順序なら、どこで落ちても辻褄が合います。予約だけ残って送信されていなければ、回収パスが「予約済みだが未送信」を検出して送り直せます。送信されたのにハンドルが確定していなければ、後述の孤児回収で拾い直せます。

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

この記事の続きを読む

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

この記事で得られること
送信前に冪等キーで台帳へ予約行を書く二段コミットで、二重送信とハンドル喪失を同時に防ぎます
SQLite 1ファイルの台帳を使い、次の cron ティックで未取得ハンドルだけを照会して完了済みを一度だけ後段へ渡す再取得ループを実装します
送信成功と台帳書き込みの隙間で生まれる孤児ハンドルを、回収パスで拾い直すリカバリ設計を示します
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

API / SDK2026-06-28
Gemini API の『未制限キー遮断』で自動運用が止まる前に、キーの制限を点検する
2026年6月19日以降、制限のない Gemini API キーからのリクエストが遮断されるようになりました。自分のキーが対象かを確かめ、本番を止めずに制限を足す手順を整理します。
API / SDK2026-06-16
Gemini Managed Agents を自動化に組み込む ― 会話状態と環境状態を分けて扱う実装メモ
Managed Agents は1回の API 呼び出しで Linux サンドボックスを立て、エージェントを走らせて結果を返します。自前ループから移すとき最初につまずく「会話状態と環境状態は別物」という設計を、実際に動かしながら整理しました。
API / SDK2026-06-29
Gemini APIのレスポンスをCIで守る — スナップショットと意味的回帰の検知設計
生成AIの非決定的なレスポンスを、pytestのスナップショットテストとembeddingベースの意味的回帰検知で守る実装手順。CI組み込み・flakyと本物の回帰の切り分け・スナップショット更新のガバナンスまでを実コードで解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →