0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【保存版】Google Gemini API の Batch API を使って大量リクエストを安く・確実に捌く(JSONL/インライン両対応)

Posted at

Gemini API を本番運用していると、こんな要件に必ず当たります。

  • 数千〜数百万件の文章を要約したい(前処理)
  • テキスト分類やラベリングを一括で回したい(評価/データセット作成)
  • Embedding を大量に作りたい(RAG構築)
  • 画像生成/解析などを「夜間にまとめて」回したい(非同期バッチ処理)

こういった **「今すぐ結果いらないけど大量に処理したい」**ユースケースに最適なのが Gemini Batch API です。

しかも Batch API は 標準料金の 50% で利用できるのが大きい。
「速度を捨ててコストを取る」選択肢が公式に用意された、というのがポイントです。


1. Batch API とは?(どんな時に使うのか)

Gemini Batch API は、大量のリクエストを 非同期 で処理するAPIです。

  • 目標応答時間:24時間
  • ただし「ほとんどの場合もっと早い」
  • 緊急性の低い大規模タスク向け

つまり、リアルタイム応答が必要なプロダクト(チャット/検索/UX直結)ではなく、
データ基盤・評価・オフライン処理のラインに向きます。


2. Batch API の送信方法は2種類(インライン vs JSONLファイル)

Batch API では、リクエストを渡す方法が2つあります。

✅ (A) インラインリクエスト方式(小規模向け)

  • バッチ作成リクエスト内に GenerateContentRequest を配列で埋め込む
  • 合計サイズ 20MB 未満の小さめバッチ向き
  • 結果は inlineResponse の配列で返る

✅ (B) 入力ファイル方式(推奨:大規模向け)

  • 1行に1リクエストの JSON Lines (JSONL) を作る
  • File API でアップロードして参照させる
  • 結果も JSONL ファイルで返る
  • 入力ファイル最大サイズは 2GB

結論:

  • 試作/少数 → インライン
  • 本番/大量 → JSONL(File API)
    が現実的です。

3. インラインでバッチを作る(Python/JS)

Python(インライン)

from google import genai

client = genai.Client()

inline_requests = [
    {
        "contents": [{
            "parts": [{"text": "Tell me a one-sentence joke."}],
            "role": "user"
        }]
    },
    {
        "contents": [{
            "parts": [{"text": "Why is the sky blue?"}],
            "role": "user"
        }]
    }
]

job = client.batches.create(
    model="models/gemini-2.5-flash",
    src=inline_requests,
    config={"display_name": "inlined-requests-job-1"},
)

print(job.name)

公式の通り、batches.create()src としてインライン配列を渡します。


4. JSONLファイルでバッチを作る(本番向け)

4.1 JSONLのフォーマット(超重要)

JSONLは「1行1JSON」です。
さらに、各行に必ず以下を含めます。

  • key:ユーザー定義キー(レスポンスに同じ key が付いて返る)
  • requestGenerateContentRequest 本体

例:

{"key":"request-1","request":{"contents":[{"parts":[{"text":"Describe photosynthesis."}]}],"generation_config":{"temperature":0.7}}}
{"key":"request-2","request":{"contents":[{"parts":[{"text":"Ingredients of Margherita pizza?"}]}]}}

この key があることで「どの結果がどのリクエストか」を確実に紐付けできます。
(本番では UUID や DB の主キーを入れるのがおすすめ)


4.2 File API にアップロード(Python)

import json
from google import genai
from google.genai import types

client = genai.Client()

with open("my-batch-requests.jsonl", "w") as f:
    requests = [
        {"key":"request-1","request":{"contents":[{"parts":[{"text":"Describe photosynthesis."}]}]}},
        {"key":"request-2","request":{"contents":[{"parts":[{"text":"Ingredients of Margherita pizza?"}]}]}}
    ]
    for r in requests:
        f.write(json.dumps(r) + "\n")

uploaded = client.files.upload(
    file="my-batch-requests.jsonl",
    config=types.UploadFileConfig(display_name="my-batch-requests", mime_type="jsonl")
)

print(uploaded.name)

4.3 バッチジョブ作成(ファイル入力)

job = client.batches.create(
    model="models/gemini-2.5-flash",
    src={"file_name": uploaded.name},
    config={"display_name": "file-batch-job-1"}
)

print(job.name)  # 例: batches/123456789

作成すると、batches/xxxx のような ジョブ名が返ります。
これを後続の ステータス確認結果取得に使います。


5. ジョブステータス監視(運用の要)

Batch API は非同期なので、ジョブ状態をポーリングして完了を待ちます。
状態は以下いずれかです:

  • JOB_STATE_PENDING:待機中
  • JOB_STATE_RUNNING:実行中
  • JOB_STATE_SUCCEEDED:成功(結果取得OK)
  • JOB_STATE_FAILED:失敗(エラー確認)
  • JOB_STATE_CANCELLED:キャンセル済み
  • JOB_STATE_EXPIRED48時間以上 pending/running で期限切れ(結果なし)

EXPIRED は「48時間経過で強制終了」
→ 再送 or バッチを分割しましょう。

Python(ポーリング例)

import time
from google import genai

client = genai.Client()

job_name = "batches/your-batch-id"

completed = {
    "JOB_STATE_SUCCEEDED",
    "JOB_STATE_FAILED",
    "JOB_STATE_CANCELLED",
    "JOB_STATE_EXPIRED",
}

while True:
    job = client.batches.get(name=job_name)
    if job.state.name in completed:
        break
    print("waiting...", job.state.name)
    time.sleep(30)

print("final:", job.state.name)

6. 結果の取り出し(インライン vs ファイル)

✅ インライン方式の場合

レスポンスは dest.inlined_responses に入っています。

for r in job.dest.inlined_responses:
    if r.response:
        print(r.response.text)

✅ ファイル方式の場合

結果は JSONLファイル として返ります。

  • ジョブが成功すると responses_file のような出力ファイル参照が得られる
  • それを File API のダウンロードで取得する

運用では「出力JSONL → ETL → DB/BigQuery投入」まで含めるとスムーズです。


7. ジョブのキャンセル(想定外のコスト/処理停止)

進行中ジョブはキャンセルできます。
キャンセルすると「新しいリクエストの処理が停止」します。

Python

from google import genai
client = genai.Client()

client.batches.cancel(name=job_name)

8. Batch API は Embeddings も強い(RAG勢はここ重要)

Batch API は batches.create_embeddingsEmbeddingモデルの大量処理にも対応しています。

例えば:

  • ベクトルDB投入用のEmbedding大量生成
  • RAGの評価用にEmbeddingを一括更新
  • 分析基盤で夜間バッチ実行

などが コスト効率よく回せます。


9. 設計・運用のコツ(実務視点)

ここからが本題。
Batch API を本番で回すなら「APIの使い方」より ジョブ設計が重要です。

✅ 9.1 key はユニークに(必須)

  • key がレスポンス紐付けの命綱
  • DBの主キーやUUIDを入れるのが鉄板

✅ 9.2 EXPIRED を前提に分割設計

  • 48時間で期限切れになる可能性がある
  • 大きすぎるバッチは分割する(例:1万件ごと)

✅ 9.3 失敗時の再送戦略

  • JOB_STATE_FAILED の場合、エラー内容をログに残す
  • 再送できるように JSONL を生成可能な状態で保持する

✅ 9.4 JSONL結果をそのままETLしやすい

  • 出力も JSONL なので

    • BigQuery
    • Spark
    • Python/pandas
    • Dataflow
      などに流しやすい

10. まとめ:Batch API は「LLMバッチ基盤」の主役になれる

Gemini Batch API は、以下を満たす人に刺さります:

✅ 大量データを処理したい
✅ 24時間以内に返ってくれば良い
✅ コストを極限まで抑えたい(50%)
✅ JSONLでETLパイプラインを組みたい
✅ Embeddingsを大量生成したい

リアルタイム性のあるプロダクト処理は通常の generateContent を使い、
非同期バッチ処理は Batch API に切り分けると、LLM利用のコスト/運用が一気に安定します。


References

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?