ガイドと洞察

AI API ゲートウェイを介した統合バッチ ジョブ: 耐久性のあるキュー、プロバイダー アダプター、テナント レベルの課金

耐久性のあるジョブ レコード、プロバイダー バッチ アダプター、冪等な結果の取り込み、予算の予約、テナント レベルの分析など、1 つのマルチモデル API を通じてレイテンシーに強い AI ワークロードを実行するための実用的なアーキテクチャ。

バッチ処理を AI API ゲートウェイの脇道として扱うべきではありません。評価、ドキュメント エンリッチメント、抽出、モデレーション スイープ、または埋め込みジョブが同期リクエスト パスから外れる場合でも、テナント制御、コスト アトリビューション、再試行、監査可能性、および使用状況分析が必要です。

実装パターンは、バッチ実行をファーストクラスのゲートウェイ サブシステムにすることです。ゲートウェイは、OpenAI、Anthropic、Gemini、および将来のプロバイダー バッチ API にバックグラウンドで適応しながら、プロバイダーに依存しない 1 つのジョブ コントラクトを公開する必要があります。

リーダーの問題: バッチ API は目的は似ていますが、操作は異なります

レイテンシに耐性のあるワークロードは、バッチ実行に自然に適合します。難しいのは、ジョブを待つことができるかどうかを判断することではありません。難しい部分は、プロバイダ間でバッチ作業を一貫して実行することです。

検証された事実: OpenAI のバッチ API は非同期で、アップロードされたファイルからリクエストを読み取り、出力ファイルにレスポンスを書き込み、現在 24 時間の処理ウィンドウを使用しています。 OpenAI には、validating、failed、in_progress、finalizing、completed、expired、cancelling、cancelled などのステータスがリストされます。 Anthropic のメッセージ バッチ API は、多くのメッセージ リクエストを非同期で処理し、各リクエストを個別に処理し、ポーリングを必要とし、処理終了後に結果を返します。結果の順序が保証されていないため、Anthropic は意味のある custom_id 値も推奨します。 Gemini のバッチ API は、リスト、キャンセル、削除、更新メソッドなどの長時間実行操作スタイルのメソッドを公開しており、そのキャンセル操作はベストエフォートとして説明されています。

実際のビジネス要件を追加すると、これらの違いは重要になります:

  • 各項目を所有するのはどのテナント、顧客、プロジェクト、または API キーですか?
  • ジョブがゲートウェイを出る前に予算が予約されていますか?
  • バッチが期限切れになるかキャンセルされた場合、どの完了済みアイテムが請求の対象になりますか?
  • 成功した作業を複製せずに部分的な失敗を再試行するにはどうすればよいですか?
  • 結果ファイルはどのくらいの期間取得できますか?ゲートウェイは何を保存する必要がありますか?
  • パートナーは上流プロバイダーを公開せずに顧客対象のバッチ処理を構築できますか? credentials?

答えは、プロバイダーの違いをすべて隠すことではありません。答えは、デバッグ、調整、サポート用にプロバイダー固有のメタデータを保持しながら、運用コントラクトを正規化することです。

推奨パブリック API: バッチ ジョブを同期完了から分離する

推奨事項: バッチ ジョブをチャット完了の特別なフラグとしてではなく、独自の API サーフェスとして公開します。同期リクエストと非同期バッチ ジョブには、ライフサイクル、請求、再試行、結果取得セマンティクスが異なります。

実際のゲートウェイ コントラクトには、次の操作が含まれます。

  • create_job: テナント、プロジェクト、キー、またはパートナー顧客が所有するドラフト ジョブを作成します。
  • append_items または upload_manifest: 安定したアイテムを含む個別のリクエストを追加します。識別子。
  • submit: 送信されたマニフェストの検証、予約、プロバイダーの選択、ディスパッチ、およびロック。
  • get_status: 正規化されたジョブと項目の数を返します。
  • list_results: 正規化された項目の結果、エラー、使用状況を確認します。
  • cancel: 即時を約束せずにキャンセルをリクエストします。 termination.
  • export_usage: 分析または請求システム用にジョブ レベルおよびアイテム レベルのコスト レコードをエクスポートします。

パブリック ジョブ オブジェクトの例:

{
  "job_id": "job_01j7...",
  "tenant_id": "tenant_acme",
  "customer_id": "cust_123",
  "endpoint": "chat.completions",
  "model": "analysis-large",
  "status": "running",
  "counts": {
    "submitted": 50000,
    "completed": 31240,
    "failed": 180,
    "expired": 0
  },
  "cost": {
    "estimated": "184.20",
    "reserved": "205.00",
    "settled": "117.43",
    "currency": "USD"
  },
  "created_at": "2026-08-19T10:00:00Z",
  "submitted_at": "2026-08-19T10:05:00Z",
  "retrieval_deadline": "2026-09-17T10:00:00Z"
}

パブリック オブジェクトは、デフォルトでプロバイダ ファイル ID、オペレーション名、または生のアップストリーム エラーを公開すべきではありません。これらはオペレータ向けのメタデータに属します。

信頼できる情報源として永続的なジョブ レコードを使用する

ゲートウェイ所有のバッチ層は、何かが上流に送信される前に永続的な状態を必要とします。唯一の状態ストアとしてプロバイダーのバッチ レコードに依存しないでください。プロバイダーのレコードは必要ですが、テナント階層、予算予約、内部モデルのエイリアス、パートナー顧客、分析要件は知りません。

最小データベース モデル

有用なスキーマには 3 つのレベルがあります。

1.バッチジョブ

batch_jobs
- job_id
- tenant_id
- project_id
- customer_id nullable
- api_key_id
- endpoint
- requested_model
- resolved_provider
- resolved_provider_model
- status
- item_count
- estimated_input_tokens
- estimated_output_tokens
- reserved_amount
- settled_amount
- created_at
- submitted_at
- completed_at
- expires_at
- retrieval_deadline
- cancellation_requested_at

2.バッチ品目

batch_items
- job_id
- item_id
- custom_id
- idempotency_key
- request_hash
- status
- provider_request_index nullable
- estimated_tokens
- actual_input_tokens nullable
- actual_output_tokens nullable
- settled_amount nullable
- result_pointer nullable
- error_code nullable
- retry_of_item_id nullable
- created_at
- settled_at

3.プロバイダ メタデータ

batch_provider_metadata
- job_id
- provider
- provider_batch_id nullable
- input_file_id nullable
- output_file_id nullable
- error_file_id nullable
- operation_name nullable
- endpoint
- region nullable
- native_status
- native_request_counts jsonb
- last_polled_at
- raw_error_pointer nullable

プロバイダ メタデータをパブリック ジョブ コントラクトから切り離しておくことで、ゲートウェイはテナント向け API を壊さずにプロバイダ アダプタを進化させることができます。

ディスパッチ前に安定したアイテム ID を必須にする

推奨事項: ゲートウェイ job_id を生成し、アイテムごとの custom_id またはディスパッチ前の冪等性キー。順序に従って結果を調整しないでください。

Anthropic は、結果の順序が保証されていないことを明示的に警告し、意味のある custom_id 値を推奨します。プロバイダーが秩序を保っているように見えても、ゲートウェイはそれに依存すべきではありません。ジョブはチャンク化され、再試行され、キャンセルされ、部分的に完了し、再取り込まれます。順序付けの仮定は最終的には失敗します。

安全なアイテム識別子の形式は記述的ですが、機密性は高くありません。

tenantA.invoice_extraction.2026-08-19.row_000381

識別子に生の電子メール、名前、ドキュメントのタイトル、または顧客の秘密を含めることは避けてください。機密の相関データは、プロバイダーに表示される ID 内ではなく、独自のテナント データベース内に保存します。

プロバイダーの詳細を消去せずにステータスを正規化します

プロバイダーのバッチ API は、さまざまなライフサイクルを公開します。ゲートウェイは、ダッシュボード、請求、自動化が理解できる小さな内部ステート マシンにそれらを正規化する必要があります。

推奨される正規化ライフサイクル:

  • draft: ジョブは存在しますが、まだ編集可能です。
  • validating: ゲートウェイまたはプロバイダーの検証が実行中です。
  • queued: 受け入れられていますが、まだ受け入れられていません。処理中。
  • running: プロバイダは項目を処理しています。
  • finalizing: プロバイダは計算を終了し、結果アーティファクトを準備しています。
  • completed: 受け入れられたすべての項目が最終成功に達しました。
  • completed_with_errors: 一部の項目は成功し、一部は失敗しました。
  • expired: プロバイダ ウィンドウすべての作業が完了する前に終了しました。
  • cancel_requested: テナントはキャンセルを要求しましたが、最終的な請求可能な作業は解決されていません。
  • cancelled: キャンセルは解決されました。
  • failed: ジョブレベルの障害により有効な実行が妨げられました。

ネイティブ プロバイダーのエラーを汎用ラベルにまとめるのが早すぎないでください。オペレーターは、デバッグ時にネイティブ ステータス、検証エラー、リクエスト数、ファイル ID、およびオペレーション名にアクセスする必要があります。

送信前に機能マトリックスに対して検証する

推奨事項: 予算の予約とプロバイダーのディスパッチの前に、プリフライト検証を実行します。バッチ モードは、遅延のある同期モードだけではありません。一部のモデル、エンドポイント、リクエスト機能、リージョン、ツール構成は、プロバイダのバッチ API でサポートされていない場合があります。

内部機能マトリックスを確認する必要があります:

  • サポートされるエンドポイント: チャット、メッセージ、埋め込み、モデレーション、または生成。
  • バッチ モードのモデル適格性。
  • 最大ジョブ サイズ、アイテム数、リクエスト サイズ、アップロードされたファイル サイズ。
  • ストリーミングが禁止されているかどうか。
  • ツールの使用と関数呼び出しのサポート。
  • 構造化出力または JSON スキーマのサポート。
  • 画像、音声、またはマルチモーダル入力のサポート。
  • 地域と居住地制約。
  • プロバイダーの保持期間と結果取得ウィンドウ。
  • バッチ固有のレート制限とキュー制限。
  • キャンセル セマンティクス。

適切なプリフライト レスポンスは具体的です:

{
  "error": "batch_capability_not_supported",
  "message": "The selected provider batch adapter does not support streaming responses. Remove stream=true or choose a synchronous endpoint.",
  "field": "items[*].request.stream"
}

これは、ジョブを受け入れて上流の検証後に失敗するよりも便利です。 pass.

テナントの予算を予約し、実際の使用量を決済します

結果ファイルが利用可能になるまで、ゲートウェイが正確な使用量への同期アクセスを失う可能性があるため、バッチ実行では請求が複雑になります。安全なパターンは、見積もり、予約、送信、取り込み、決済、調整です。

確認された事実: OpenAI では、バッチ API の価格は同期 API と比較して割引価格で提供されており、期限切れまたはキャンセルされたバッチでも、請求対象となる完了した作業が返される可能性があると述べています。Anthropic では、高スループットのバッチ処理ではワークスペースの使用制限をわずかに超える可能性があるため、ゲートウェイ側の予約と決済後の処理が重要になることに注意してください。

推奨事項: 推定トークン、選択したプロバイダー価格ルール、および安全マージンを使用して、送信前にテナント予算を予約します。結果が取り込まれた後、アイテムレベルで実際の使用量を決済します。見積もりが高すぎる場合は、未使用の予約を解放します。低すぎる場合は、テナントの構成された超過ポリシーを適用します。

実用的な台帳イベント:

batch.estimated
batch.reserved
batch.submitted
batch.item.settled
batch.item.refunded
batch.cancel_requested
batch.expired
batch.reconciled

項目レベルの台帳は不可欠です。 45,000 項目が完了し、5,000 項目が期限切れになった場合、単一の未分化 BLOB としての元のマニフェストではなく、完了したプロバイダーの作業に対してテナントに請求する必要があります。

ビジネス ロジックの所有者ではなく、トランスレーターとしてプロバイダー アダプターを構築する

各プロバイダー アダプターは、ゲートウェイ ジョブをプロバイダーのバッチ形式に変換し、送信し、ステータスをポーリングまたは取得し、結果をダウンロードし、ネイティブの結果をマッピングする方法を知っている必要があります。正規化されたレコード。

テナント ポリシーをアダプターの外に保持します。アダプターは、顧客に十分な予算があるかどうか、パートナー顧客が一時停止されているかどうか、またはプロンプトを保存できるかどうかを決定すべきではありません。これらはゲートウェイの決定です。

アダプターの責任

  • プロバイダー固有のリクエスト マニフェストをレンダリングします。
  • 入力ファイルをアップロードするか、プロバイダー オペレーションを作成します。
  • プロバイダー識別子をメタデータに保存します。
  • ネイティブ ステータスを正規化されたステータスにマッピングします。
  • 出力を取得します
  • 項目レベルの結果を解析します。
  • 利用可能な場合はネイティブの使用状況レコードを返します。
  • 表面再試行可能エラーとターミナル エラー。

ゲートウェイの責任

  • テナントと API を認証するキー。
  • チーム、プロジェクト、および顧客の管理を適用します。
  • モデルのエイリアスとプロバイダーのルーティング ポリシーを解決します。
  • バッチ機能を検証します。
  • 予算を予約して決済します。
  • ジョブとアイテムの状態を保持します。
  • 保持を強制します
  • 分析とエクスポートを公開します。

この分離により、請求、分析、テナント ガバナンスを書き直すことなく、新しいプロバイダーを簡単に追加できるようになります。

結果を冪等に取り込む

結果の取り込みでは、多くのバッチ システムで誤って料金が重複したり、部分的な作業が失われたりすることがあります。摂取を反復可能なプロセスとして扱います。同じ出力ファイルを 2 回ダウンロードしたり、同じプロバイダーの操作を 2 回処理したり、同じ Webhook イベントを 2 回再生したりしても安全です。

推奨事項: 項目レベルの冪等性キーと台帳の一意性制約を使用します。job_id + custom_id の結果は、取り込みが再試行された場合でも、正確に 1 回確定する必要があります。

堅牢な取り込みフロー:

  1. ジョブまたは結果アーティファクトに対して有効期間の短いロックを取得します。
  2. プロバイダ出力とエラー アーティファクトを取得します。
  3. レコードを正規化されたアイテム結果に解析します。
  4. 各レコードを custom_id またはゲートウェイ アイテム ID で照合します。
  5. 結果のメタデータとトランザクションでの使用法を書き込みます。
  6. 台帳決済イベントがまだ存在しない場合にのみ作成します。
  7. 仮定ではなくアイテムの状態からジョブ数を更新します。
  8. すべての最終状態が終了したら、未使用の予算予約を解放します。

Webhook が利用可能な場合は、署名を検証し、リプレイから保護します。ポーリングが必要な場合は、アダプティブ ポーリングを使用します。完了が予想される近くで頻繁にポーリングし、長時間実行中にバックオフし、最終決済後に停止します。

ジョブ全体ではなく項目を再試行します

推奨事項: 可能な限り項目レベルで再試行してください。ジョブ全体の再試行は簡単ですが、重複作業のリスクが高まり、請求が難しくなります。

再試行する前に失敗を分類します:

  • 検証エラー: 通常、リクエストが修正されるまで終了します。
  • プロバイダ 5xx エラー: は、多くの場合再試行可能ですバックオフ。
  • 割り当てまたはレート制限の失敗: 容量が利用可能になってからのみ再試行します。
  • 安全ブロック: 盲目的に再試行しません。ポリシー処理へのルートです。
  • 期限切れのアイテム: は、テナントがまだ作業を希望していて予算が許せば、新しいジョブで再試行できます。

再試行すると、元のアイテムにリンクされた新しいアイテムが作成されます:

{
  "item_id": "item_retry_002",
  "retry_of_item_id": "item_001",
  "custom_id": "tenantA.eval.row_901.retry_1"
}

completed_with_errors で終了したジョブの一部だったという理由だけで、完了したアイテムを再送信しないでください。または expired.

生の結果、ポインタ、ハッシュなど、何を保存するかを決定します

バッチ システムは、プロンプトと出力を蓄積する場所として魅力的です。これはエクスポートやデバッグには便利ですが、データ保持の責任が増大します。

推奨事項: ストレージ ポリシーをテナント構成可能にします。機密性の高いワークロードの場合は、生のプロンプトや出力ではなく、メタデータ、ハッシュ、使用法、および結果ポインターを保存します。機密性の低いワークロードの場合、保持期間、アクセス制御、削除ワークフローが明確であれば、正規化された結果ストレージが許容される可能性があります。

少なくとも次の点を追跡します。

  • 生の入力が保存されたかどうか。
  • 生の出力が保存されたかどうか。
  • プロバイダの結果アーティファクトが存在する場所。
  • プロバイダの取得期限。
  • ゲートウェイの削除期限。
  • コンテンツの公開を伴わない監査のリクエストとレスポンスのハッシュ。

確認済みの事実: Anthropic によれば、バッチ結果は作成後 29 日間利用可能で、ワークスペース内に隔離されています。この種のプロバイダ固有の取得ウィンドウは、ゲートウェイのメタデータとテナント側のエクスポートに反映される必要があります。

チームの運用方法に一致する分析を公開します

バッチ分析はジョブ レベルとアイテム レベルの両方に存在する必要があります。製品所有者は、夜間のエンリッチメントが完了したかどうかを知りたいと考えています。財務管理者は、テナント、モデル、顧客ごとのコストを知りたいと考えています。エンジニアは、どの失敗クラスを再試行すべきかを知りたいと考えています。

有用な指標には、次のものが含まれます。

  • 送信済み、完了済み、失敗した、期限切れ、およびキャンセルされた項目数。
  • 推定コストと解決済みコストの比較。
  • 予約予算はまだ保持されています。
  • プロバイダー別の入力トークンと出力トークン、およびモデル。
  • プロバイダーが公開するキャッシュ ヒット インジケーター。
  • 再試行回数と再試行成功率。
  • キューに入れられた状態、実行中、終了処理中の状態の平均時間。
  • エンドポイントおよびモデル別の上位の検証エラー。
  • パートナー顧客attribution.

パートナー API ユーザーの場合、バッチ ジョブを顧客スコープのリソースとして公開します。これにより、代理店や SaaS ビルダーは、上流のプロバイダーの認証情報、請求調整、ゲートウェイ内でのレート制限処理を維持しながら、オフライン AI 処理を提供できるようになります。

明示的なトレードオフ

ゲートウェイの抽象化とプロバイダー固有の機能: 統一された契約は統合を簡素化しますが、すべてのプロバイダーの機能を同一にすることはできません。機能エラーは明示的にしてください。

予算の予約と見積もりの​​精度: 予約はテナントを暴走したジョブから保護しますが、見積もりが間違っている可能性があります。台帳は、調整、払い戻し、超過料金の処理をサポートする必要があります。

ポーリングと Webhook の比較: ポーリングはシンプルで信頼性がありますが、API 回の呼び出しが無駄になり、完了が遅れる可能性があります。 Webhook は高速ですが、署名の検証、リプレイ保護、監視が必要です。

生の結果の保存と保持の最小化: 正規化された結果を保存すると、エクスポートと分析が向上しますが、コンプライアンスの負担が増加します。敏感なテナントはポインタとハッシュを好む場合があります。

大規模なバッチとチャンク化されたバッチ: 大きなバッチはプロバイダ側の効率を向上させる可能性がありますが、チャンクが小さいほど爆発半径が減少し、再試行が容易になります。

実装チェックリスト

  • 別のバッチ ジョブを作成します API surface.
  • プロバイダーの送信前にジョブとアイテムのレコードを保持します。
  • ゲートウェイ ジョブ ID とアイテムごとのカスタム ID を要求します。
  • ネイティブ プロバイダーのメタデータを保存しながらステータスを正規化します。
  • 各プロバイダーのバッチ アダプターの機能マトリックスを作成します。
  • 予約する前にマニフェストを検証します。予算。
  • 発送前にテナントの予算を予約します。
  • 取り込み後に項目レベルで実際の使用量を確定します。
  • 結果の取り込みを冪等にします。
  • ジョブ全体をやみくもにではなく、失敗した項目を選択して再試行します。
  • プロバイダの取得期限とゲートウェイの保持を追跡します。ポリシー。
  • ジョブと項目の分析をテナントとパートナー顧客に公開します。

予測: このパターンの方向性

予測: バッチ実行は、単なる割引メカニズムではなく、AI 自動化インフラストラクチャの通常の一部になるでしょう。チームがより多くの評価、データ クリーンアップ タスク、安全性レビュー、エンリッチメント パイプラインを実行するにつれて、非同期ワークロードには同期 API 呼び出しと同じガバナンスが適用されることが期待されます。

予測: プロバイダーのバッチ API は、有用な方法で分岐し続けるでしょう。ファイル用に最適化するもの、長時間実行操作用に最適化するもの、管理されたデータセットまたはイベント コールバック用に最適化するものもあります。ゲートウェイ アダプター レイヤの価値は、アダプターより上の運用コントラクトが安定した状態を維持できるため、価値が下がるのではなく、より高くなります。

実用的な結論

AI API ゲートウェイにバッチ処理をプロバイダー固有のエスケープ ハッチとしてボルト付けしないでください。独自のジョブ レコード、アイテム識別子、ステータス モデル、プロバイダー アダプター、予算予約、べき等取り込み、分析を備えた耐久性のあるサブシステムとして構築します。

最も重要な設計上の選択は、アイテムレベルのアカウンティングです。バッチ内のすべてのリクエストが安定した ID を持つと、ゲートウェイは順序付けされていない結果を調整し、失敗した作業のみを再試行し、完了したプロバイダーの作業のみを請求し、何が起こったかをテナントに表示できます。これが、プロバイダにファイルを送信することと、非同期ワークロード用の信頼できるマルチモデル API を操作することの違いです。

関連資料

FAQ

よくある質問

ゲートウェイはプロバイダーネイティブのバッチ API を直接公開する必要がありますか?
通常はいいえ。ネイティブ API を公開すると、開発者はプロバイダー機能に直接アクセスできるようになりますが、テナント レベルの課金、分析、再試行、ガバナンスが弱体化します。より良いパターンは、オペレーターが利用できるプロバイダー固有のメタデータを備えた、プロバイダーに依存しないジョブ契約です。
アイテムごとにcustom_idが必要なのはなぜですか?
バッチ結果は、送信された順序で返されない場合があります。安定したアイテムごとの識別子により、ゲートウェイは結果を調整し、使用量を解決し、失敗したアイテムを再試行し、重複請求を回避できます。
キャンセルされたバッチまたは期限切れのバッチはどのように請求されるべきですか?
結果が取り込まれて調整された後、完了したプロバイダーの作業に対してのみ請求されます。キャンセルされたジョブや期限切れのジョブには完了したアイテムが含まれている可能性があるため、ジョブ レベルのステータスだけでは正確な請求を行うには十分ではありません。
ゲートウェイはバッチ ジョブからの生のプロンプトと出力を保存する必要がありますか?
デフォルトでは機密性の高いテナントには適用されません。テナントが明確な保持ポリシーを使用して生の結果のストレージを明示的に有効にしない限り、メタデータ、ハッシュ、使用法、および結果ポインターを保存します。