メインコンテンツまでスキップ

Message Batches — 50% オフの非同期ジョブ

中級
What you'll learn
  • Message Batches API が 1 日で元を取れるワークロードを見分ける
  • バッチを送信し、ポーリングし、結果をストリーミングで取り戻す — エンドツーエンドで
  • どちらも壊さずに、バッチ割引とプロンプトキャッシュを重ねる
  • リクエストをバッチ対象から静かに外してしまう 4 つの機能を避ける
  • 同じパターンを OpenAI と Gemini に移植する — どこも非同期処理を 50% 割引している

Anthropic の請求額の半分は、おそらく同期処理である必要がありません。夜間の評価、バックフィル、モデレーションのスイープ、大量のコンテンツ生成は、回答が 800 ms で返るか 40 分で返るかを気にしません — そしてこのトレードオフを受け入れれば、Anthropic は 50% 安く請求します。Message Batches API はそれを手に入れる方法です。

バッチが元を取れるとき

以下がすべて当てはまるときにバッチを選びます — 1 つでも「いいえ」があれば、おそらく通常の Messages API を使うべきです。

シグナルバッチが適するのは…
レイテンシ最大 24 時間待てる。ほとんどのバッチは 1 時間以内に完了しますが、SLA は 24 時間です。
ボリューム送るリクエストが少なくとも数百件ある。API はバッチごとに最大 100,000 件を受け付けます。
インタラクティブ性スピナーを見ているユーザーがいない。これはオフライン作業向けです。
結果の形ライブのトークンストリームではなく、JSONL の結果ファイルを消費できる。

典型的な勝ちパターン:

  • 評価(Evals) — リリース前に 5,000 件のモデル出力をルーブリックで採点する。
  • バックフィル — プロンプトを変更したときに既存データセットを再分類する。
  • 一括生成 — 商品説明、要約、メタタグ、翻訳をカタログ規模で。
  • モデレーション/ラベリング — スケジュールに沿ってユーザーコンテンツを毎日スイープする。
  • 合成データ — 小さな下流モデル向けの学習ペアを生成する。

ジョブを形作る制限

制限
割引サポートされるすべてのモデルで、標準の入力および出力トークン価格の 50% オフ。
バッチサイズ100,000 リクエストまたは 256 MB のいずれか早く到達した方。
処理時間ほとんどは 1 時間以内。24 時間のハード期限 — 24 時間後に未処理のものは expired を返します。
結果の保持バッチ作成から 29 日間。その後、結果は利用できなくなります(バッチのメタデータは残ります)。
モデル対応すべての現行 Claude モデル — Fable 5、Mythos 5、Opus 5、Opus 4.x、Sonnet 5、Sonnet 4.x、Haiku 4.5。
スコープWorkspace 単位。Workspace A のキーで Workspace B のバッチは見えません。
支出上限並行処理のため、バッチは設定した Workspace の支出上限をわずかに超えることがあります。

3 ステップのループ

すべてのバッチジョブは同じ形をたどります — 作成、ポーリング、結果のストリーミング。

Guided walkthrough1 of 3
  1. requests 配列を付けて POST /v1/messages/batches を呼びます。各項目は一意の custom_id(自分のデータに戻るための結合キー)と、通常の Messages 呼び出しとまったく同じ形の params ブロックを持ちます。API はバッチ id と in_progress の processing_status を返します。

バッチを作成する(cURL)

最小限のバッチ — Opus 5 の呼び出し 2 件。結果をソース行に結合し直せるよう、それぞれにタグを付けています。

POST /v1/messages/batches

curl https://api.anthropic.com/v1/messages/batches \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--data '{
  "requests": [
    {
      "custom_id": "row-00001",
      "params": {
        "model": "claude-opus-5",
        "max_tokens": 1024,
        "messages": [
          {"role": "user", "content": "Summarize: ..."}
        ]
      }
    },
    {
      "custom_id": "row-00002",
      "params": {
        "model": "claude-opus-5",
        "max_tokens": 1024,
        "messages": [
          {"role": "user", "content": "Summarize: ..."}
        ]
      }
    }
  ]
}'

custom_id^[a-zA-Z0-9_-]{1,64}$ にマッチし、バッチ内で一意でなければなりません。外部キーとして扱ってください — 多くの人は結果をきれいにマージし直せるよう、行 id か入力のハッシュを設定します。

ステータスをポーリングする(Python)

バッチが完了するまで待つ

import time, anthropic

client = anthropic.Anthropic()
batch_id = "msgbatch_..."

while True:
  batch = client.messages.batches.retrieve(batch_id)
  if batch.processing_status == "ended":
      break
  print(batch.request_counts)  # live progress
  time.sleep(60)

結果をストリーミングし、種類ごとに処理する

すべてのリクエストは 4 つのバケットのいずれかに入ります。課金されるのは succeeded のみです — エラー、キャンセル、期限切れは無料です。

結果の種類意味アクション
succeededMessage が返ってきた。custom_id でマージする。
errored不正なリクエストか一時的なサーバーエラー。invalid_request_error なら修正して再送信。サーバーエラーならそのままリトライ。
canceledこの項目が実行される前にバッチをキャンセルした。まだ必要なら再送信。
expiredこのリクエストが実行される前に 24 時間の枠が過ぎた。再送信 — 通常はバッチが大きすぎたか、プラットフォームが混雑していたサイン。

結果をストリーミングする(Python)

for r in client.messages.batches.results(batch_id):
  match r.result.type:
      case "succeeded":
          save(r.custom_id, r.result.message)
      case "errored":
          if r.result.error.error.type == "invalid_request_error":
              log_bad_row(r.custom_id, r.result.error)
          else:
              retry_queue.append(r.custom_id)
      case "expired":
          retry_queue.append(r.custom_id)

結果ファイル全体を素朴な requests.get(...).text でダウンロードしないでください — 大きなバッチでは RAM を使い尽くします。SDK のヘルパーはすでに行単位で反復します。cURL での同等の方法は、レスポンスを実体化するのではなく jq -c にパイプすることです。

複利効果:バッチとプロンプトキャッシュを重ねる

この割引はプロンプトキャッシュと重ねられ、ここで経済性が馬鹿げたレベルになります。キャッシュヒットは入力価格の 10% で、バッチがそれをさらに半分にします。すべてのリクエストが同じ 20k トークンのシステムプロンプトとルーブリックを共有する大規模な評価では、入力の項目は定価の 5% まで下がります — 20 分の 1 です。

知っておくべき 2 つのこと:

  1. 1 時間のキャッシュ期間を使う。 デフォルトの 5 分 TTL は、大きなバッチが処理を終える前に期限切れになるのが普通です。Anthropic 自身のドキュメントも、バッチ処理には特に 1 時間キャッシュを推奨しています。
  2. max_tokens: 0(キャッシュの事前ウォームアップ)はバッチ内では許可されません — バッチ処理中に書き込まれた一時的なエントリは後続の処理が走る前に期限切れになるため、プラットフォームはこれを即座に拒否します。

勝ちパターンの形:通常の Messages 呼び出しを 1 回行ってキャッシュを事前にウォームアップし、書き込まれるのを待ってから、そのキャッシュプレフィックスを次の 1 時間再利用するバッチを投入します。

バッチに入れられるもの — 入れられないもの

はい、バッチ可能: ビジョン、すべてのサーバーツール(Web 検索、Web フェッチ、コード実行、MCP コネクタ、アドバイザー、ツール検索)、システムメッセージ、マルチターン、拡張思考、ほとんどのベータ機能。通常の Messages API で動くものは、ほぼ確実にバッチ内でも動きます。

いいえ、検証時に拒否:

パラメーターブロックされる理由
stream: true結果はライブストリームではなくファイルで返ります。
speed(Fast モード)Fast モードは同期レイテンシを調整するもの — 非同期では意味がありません。
store / previous_thread_event_id(Threads)Threads はステートフルで、バッチはそうではありません。
cache_hint / context_hintルーティングヒントは同期スケジューリングにのみ影響します。
max_tokens: 0使う前に期限切れになるキャッシュエントリを書き込むことになります。
research_preview_2026_02: "active"リサーチプレビューモードはバッチの経路にありません。

検証は非同期で実行されるため、不正なリクエストはバッチ全体が終了したときにしか報告されません。50,000 件のリクエストを送信する前に、1 件を通常の Messages API に通して形が検証を通ることを確認してください。

プロバイダーをまたいで同じパターン

バッチ料金は収束しました。3 大フロンティアプロバイダーはいずれも同じ見出しの形 — 50% オフ、約 24 時間の SLA、JSONL の入出力 — を提供しており、Claude だけの小技ではなく、真に移植可能なパターンになっています。

プロバイダー割引SLA送信方法参照
Anthropic — Message Batches入力+出力 50% オフほとんどは 1 時間未満、24 時間のハード期限JSON ボディ(requests[])、最大 100k / 256 MBドキュメント
OpenAI — Batch API入力+出力 50% オフほとんどは 1〜6 時間、24 時間の SLAJSONL ファイルのアップロード、バッチごとに最大 50k リクエストドキュメント
Google — Gemini Batch API入力+出力 50% オフほとんどは 24 時間未満の SLAインラインまたは GCS ベースのバッチジョブ。コンテキストキャッシュ対応ドキュメント

移植可能なアーキテクチャ:ソーステーブルを読み、行を 10k 行のバッチに分割し、プロバイダーごとに送信し、ポーリングし、custom_id で結果をマージする小さな「ジョブランナー」です。異なるのは送信/ポーリング/結果取得の呼び出しだけで、パイプラインの残りはプロバイダー非依存です。同じ考え方をプロンプト自体に適用したものは Cross-AI プロンプト翻訳を参照してください。

よくある間違い

  • インタラクティブなトラフィックをバッチにする。 ユーザーがページにいる — 60 秒の待ち時間ですら壊れたプロダクトです。バッチはオフラインのスケジュールされた作業向けです。
  • 小さすぎるジョブをバッチにする。 20 件のリクエストではポーリングループと 24 時間の上限に見合いません。数百件未満なら、並行実行付きの通常の Messages API を使ってください。
  • ストリーミングできるのにバッチ全体でブロックする。 JSONL ファイル全体をメモリにダウンロードするのは 50 行なら動きますが、50,000 行では OOM になります。反復してください。
  • expired の結果を無視する。 無料ですが、未完了の作業です。追跡して再キューに入れてください — さもないと、需要ピーク時にパイプラインが静かに行を失います。
  • 検証が同期だと思い込む。 1 行の不正なリクエストはフェイルファストしません。最後に残りと一緒に返ってきます。まず 1 行を通常の Messages API でテストしてください。
  • 結合キーを失う。 バッチは順不同で完了し、結果ファイルは入力順にソートされていません。意味のある custom_id を設定しなければ、結果をソースデータに確実にマージし直すことはできません。
  • 29 日間の保持を忘れる。 その後、results_url は何も返しません。パイプラインの一部として結果をダウンロードし、自分のストレージに永続化してください。
要点
Enter キーまたはスペースキーでカードを裏返します。左右の矢印キーでカードを移動できます。用語を表示しました。
1 / 8

理解度チェック

0/4
  1. Batches API に適さないワークロードはどれですか?
  2. 10,000 件のリクエストをバッチにしました。9,200 件が成功、500 件がエラー、200 件がキャンセル、100 件が期限切れです。何件分を支払いますか?
  3. 40,000 件のリクエストのバッチで巨大なシステムプロンプトを再利用したいとします。どのキャッシュ TTL を使うべきですか?
  4. 大きなジョブのバッチ結果ファイルが 400 MB あります。正しい消費方法はどれですか?
Key takeaways
  • バッチ処理はオフラインワークロードにおける Anthropic の支出を減らす最大のレバー — 50% オフで、プロンプトの書き換えは不要。
  • トレードオフはレイテンシとインタラクティブ性であり、品質ではない。同じモデル、同じ出力形式、同じ機能。
  • 本当の経済性はプロンプトキャッシュと 1 時間 TTL を重ねること — プレフィックスを共有するワークロードでは定価入力価格の 5% に届く。
  • 常に意味のある custom_id を設定し、常に結果ファイルをストリーミングし、常に期限切れの行を再キューに入れる。
  • パターンは移植できる:OpenAI と Gemini も非同期処理を約 24 時間の SLA で 50% 割引している — ジョブランナーを 1 つ作り、プロバイダー間でルーティングする。

次のステップ