GEMINI LABEN
ROBOTICS — 8月31日に停止した ER 1.6 preview には後継があります。Gemini Robotics ER 2 が公開プレビュー中で、通常版とストリーミング版の2種類が提供されていますVIDEO — ER 2 の成功・失敗判定は静止画ではなく生の映像フィード上で動きます。こぼれ・滑り・位置ずれのような、実行の途中で起きる失敗を捉えられる設計ですDEADLINE — 次の期限は9月30日、gemini-omni-flash-preview の廃止です。移行先は8月27日に GA になった gemini-omni-1.1-flash で、残り4週間を切りましたAPIKEY — 残りの標準 API キーは、制限付きのものも含めて9月中に全面停止します。移行先は Google Cloud サービスアカウントに紐付く auth キー形式ですPRICE — Gemini 3.7 Flash の導入価格 $0.75/$3.75 per 1M は12月31日までです。2027年1月1日から $1.50/$7.50 になるため、年を跨ぐ見積もりは2本立てが要りますAUDIO — Gemini 3.5 Transcribe は85言語以上の言語検出、話者ダイアライゼーション、単語単位タイムスタンプ、最大1,000語のカスタム語彙バイアスに対応していますROBOTICS — 8月31日に停止した ER 1.6 preview には後継があります。Gemini Robotics ER 2 が公開プレビュー中で、通常版とストリーミング版の2種類が提供されていますVIDEO — ER 2 の成功・失敗判定は静止画ではなく生の映像フィード上で動きます。こぼれ・滑り・位置ずれのような、実行の途中で起きる失敗を捉えられる設計ですDEADLINE — 次の期限は9月30日、gemini-omni-flash-preview の廃止です。移行先は8月27日に GA になった gemini-omni-1.1-flash で、残り4週間を切りましたAPIKEY — 残りの標準 API キーは、制限付きのものも含めて9月中に全面停止します。移行先は Google Cloud サービスアカウントに紐付く auth キー形式ですPRICE — Gemini 3.7 Flash の導入価格 $0.75/$3.75 per 1M は12月31日までです。2027年1月1日から $1.50/$7.50 になるため、年を跨ぐ見積もりは2本立てが要りますAUDIO — Gemini 3.5 Transcribe は85言語以上の言語検出、話者ダイアライゼーション、単語単位タイムスタンプ、最大1,000語のカスタム語彙バイアスに対応しています
記事一覧/API / SDK
API / SDK/2026-05-18上級

Gemini API asyncio 非同期処理の本番パターン——並列リクエストで処理時間を1/5に短縮した実装記録

Gemini API の asyncio 非同期処理を本番環境に組み込んだ実装記録。Semaphore によるレート制限対策、指数バックオフ、部分失敗の扱い方まで、個人開発アプリのバックエンドで実際に遭遇したパターンを整理して紹介します。

gemini-api285asyncio3python103非同期処理5本番環境6個人開発111

プレミアム記事

2026年に入ってから、個人で運営している壁紙アプリ「Beautiful 4K/HDR Wallpapers」のバックエンドで、Gemini APIを使って画像コンテンツの自動カテゴリ分類に取り組みました。廣川政樹として2013年からアプリ事業を続けてきた中で、累計5,000万DLを超えた今もアプリのコンテンツ更新作業は頻繁に発生します。その更新作業を自動化しようとした際、最初に直面したのが「同期処理では現実的な時間に収まらない」という問題でした。

最初のバージョンは Python の同期処理で書いていて、1,000枚の画像を処理するのに推定6時間以上かかる計算でした。アプリのカタログ更新はほぼ毎週行う必要があるため、この所要時間は明らかに現実的ではありません。asyncio による非同期処理に切り替えたところ、最終的に処理時間を約1/5まで短縮できました。

学んだ Gemini API の asyncio 実装パターンを整理して共有します。「動くコード」だけでなく、「本番で詰まったポイント」と「なぜこう書くのか」の理由まで含めています。

なぜ同期処理では限界が来るのか

Gemini API は HTTP ベースの REST API です。同期処理でリクエストを1件ずつ投げると、それぞれのネットワーク往復時間が積み上がっていきます。1リクエストあたりの応答時間が平均2秒だとすると、1,000件で2,000秒(約33分)。画像の前処理やローカルI/Oも含めると6時間という計算が現実に近くなります。

同期処理のコードは読みやすく、デバッグも簡単です。スケールしない以外は問題がなく、少量のデータを扱う間は問題なく動き続けます。しかしアプリのコンテンツが増え、分類対象の画像が数百件から数千件になる段階で、同期処理の限界は突然訪れます。

import google.generativeai as genai
 
# ❌ 同期処理の例(これでは遅い)
def classify_images_sync(image_paths: list[str]) -> list[dict]:
    model = genai.GenerativeModel("gemini-2.5-flash")
    results = []
    for path in image_paths:
        with open(path, "rb") as f:
            image_data = f.read()
        response = model.generate_content([
            '{"category": "...", "tags": [...]}の形式でJSONのみ返してください。',
            {"mime_type": "image/jpeg", "data": image_data}
        ])
        results.append({"path": path, "result": response.text})
    return results

asyncio を使えば、複数のリクエストを同時に飛ばすことができます。ネットワークの応答を待っている間、イベントループは別のリクエストを開始できます。ただし Gemini API には RPM(1分あたりのリクエスト数)と TPM(1分あたりのトークン数)の制限があるため、無制限に並列化するとすぐにレート制限エラーが返ってきます。「並列化しながらレート制限を守る」という二律背反を解決するのが、次に説明する Semaphore パターンです。この二律背反こそが asyncio 初学者が一番詰まるポイントです。レート制限を無視して並列数を上げすぎると 429 エラーが頻発し、レート制限を守りすぎると並列化のメリットが失われます。ちょうどよいバランスを見つけることが設計の核心です。

asyncio.to_thread() による同期SDKのラップ

2026年5月時点で、google-generativeai の Python SDK は同期クライアントのみを提供しています。asyncio で使うには asyncio.to_thread() を使って同期関数をスレッドプールで実行するのが最も安定した方法です。

asyncio.to_thread() は Python 3.9 以上で使えます。内部的には loop.run_in_executor(None, func) と同等ですが、より直感的に書けます。これを使うことで、同期処理のAPIコールを「ブロッキングしないコルーチン」として扱えるようになります。

import asyncio
import google.generativeai as genai
 
genai.configure(api_key="YOUR_GEMINI_API_KEY")
model = genai.GenerativeModel("gemini-2.5-flash")
 
async def call_gemini_async(prompt: str, image_data: bytes, mime_type: str = "image/jpeg") -> str:
    """
    同期のGemini APIコールをスレッドプールで非同期実行する。
    asyncio.to_thread() でブロッキング処理をイベントループの外に逃がす。
    """
    def _sync_call():
        response = model.generate_content([
            prompt,
            {"mime_type": mime_type, "data": image_data}
        ])
        return response.text
 
    return await asyncio.to_thread(_sync_call)

この実装で重要な点は、genai.GenerativeModel のインスタンスを複数のスレッドで共有していることです。私の環境では、並列数30のスレッドプールで共有しても状態の競合は発生しませんでした。ただし genai.configure(api_key=...) はモジュールレベルで一度だけ呼ぶことが前提です。

これだけでは「非同期で実行できる」だけで、複数件を並列実行する仕組みがありません。次のステップが核心部分です。

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

この記事の続きを読む

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

この記事で得られること
画像1,000枚の逐次処理で6時間かかっていたバックエンドが、asyncio 並列化でどう変わったかを追体験できる
Gemini API の RPM/TPM 制限に引っかかることなく高スループットを実現する Semaphore パターンのコードを入手できる
部分失敗・タイムアウト・指数バックオフを一つに組み込んだ本番用の asyncio ラッパーをそのまま使えるようになる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

API / SDK2026-04-09
Gemini 2.5 Pro × Python 非同期処理:高スループットAPIシステムの本番構築
Python の asyncio で Gemini 2.5 Pro API の処理能力を引き出す高スループット構成を解説します。非同期クライアントの実装、指数バックオフとジッターによるレート制限対策、非同期ストリーミング、大量ドキュメント処理パイプラインまでコードつきです。
API / SDK2026-05-18
Gemini Vision で壁紙アプリの自動カテゴリ分類を実装した話
個人開発の壁紙アプリで Gemini Vision API を使い、画像の自動カテゴリ分類を実装した実体験です。精度改善のプロセスと、公式ドキュメントには載っていない落とし穴、GPT-4o Vision とのコスト比較までまとめました。
API / SDK2026-05-17
git log から日英リリースノートを Gemini API で自動生成した — Beautiful HD Wallpapers v2.1.0 での実装記録
個人開発アプリのリリースノートを毎回手書きしていたコストに気づき、Gemini API で git log から日英自動生成するスクリプトを作った記録。Beautiful HD Wallpapers v2.1.0 のリリース作業で実証し、30言語対応への拡張方法も紹介します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →