ガイド
バッチジョブのライフサイクル
同期 vs 非同期、ジョブの状態、部分結果、Webhook
バッチエンドポイント(/batch/distill、/batch/extract)は非同期です。ジョブは小さなステートマシンを通って遷移します。状態を理解することで、ポーリングと Webhook のどちらを使うか、部分的な失敗をどう処理するかを判断できます。
同期 vs 非同期
同期(/distill、/extract) | 非同期(/batch/distill、/batch/extract) | |
|---|---|---|
| リクエストあたり URL 数 | 1 | 最大 100 |
| レスポンス | HTTP body に完全な結果 | ジョブ ID。結果は別途取得 |
| レイテンシ | 1 リクエスト、1 回の待機 | サブミット → ポーリングまたは Webhook → 取得 |
| 適した用途 | リアルタイム UX、エージェントツール、アドホック検索 | スケジュールジョブ、RAG インジェスト、モニタリング |
| 失敗モード | 1 つの不正 URL で呼び出し全体が失敗 | 1 つの不正 URL はその行が失敗、ジョブは継続 |
| 並列度コスト | 呼び出しごとに 1 スロット | バッチ全体で 1 スロット |
迷ったときは:単一 URL → 同期、複数 URL や急がない → 非同期。
ジョブの状態
| ステータス | 意味 |
|---|---|
PENDING | ジョブを受領、キューイング済み |
PROCESSING | 少なくとも 1 つの URL を処理中 |
COMPLETED | すべての URL が終了状態(成功または失敗)に到達 |
FAILED | ジョブレベルの致命的エラー(稀 —— 通常は 1 つの URL が失敗してもジョブ全体は失敗しない) |
CANCELLED | DELETE によるユーザー起点のキャンセル |
URL の失敗ではジョブは失敗しません。results[] の各アイテムは独自の status を持ちます:PENDING、PROCESSING、SUCCEEDED、または FAILED。すべての行が終了状態に到達するとジョブは COMPLETED に遷移します。
ポーリング vs Webhook
| ジョブサイズ | 推奨 | 理由 |
|---|---|---|
| 10 URL 未満 | 5〜10 秒ごとにポーリング | Webhook の配線コストが見合わない |
| 10〜100 URL | Webhook | 5 分のジョブで約 60 ラウンドトリップを消費 |
| 100 URL 超(複数バッチ) | Webhook | 各バッチが完了時に 1 回発火 |
ペイロード形状、署名検証(HMAC-SHA256)、リトライ動作については Webhook を参照。
部分結果
GET /batch/distill/{id} はジョブが PROCESSING 中でも動作します —— その時点で完了したものを取得できます。完了した行をストリーミング表示するダッシュボードに有用です。
import httpx, time
API = "https://openapi.thunderbit.com/openapi/v1"
H = {"Authorization": "Bearer YOUR_API_KEY"}
job = httpx.post(f"{API}/batch/distill", headers=H,
json={"urls": urls}).json()
batch_id = job["data"]["id"]
while True:
body = httpx.get(f"{API}/batch/distill/{batch_id}", headers=H).json()["data"]
fresh = [r for r in body["results"] if r["status"] == "SUCCEEDED"]
yield_to_dashboard(fresh)
if body["status"] in ("COMPLETED", "FAILED", "CANCELLED"):
break
time.sleep(5)キャンセル
DELETE /batch/distill/{id}(または /batch/extract/{id})は PENDING または PROCESSING のジョブにのみ機能します。一度終了状態になるとそこに留まります。キャンセルされたジョブの中ですでに処理済みの URL は課金対象のままです。完了していなかった処理中の URL は課金されません。