非同步圖像生成 API 允許您提交生成請求,立即獲得任務識別碼,並在稍後檢索完成的圖像,而無需長時間保持 HTTP 連線。本教學涵蓋了任務生命週期、何時該使用輪詢與 Webhook,以及如何設計重試機制,以確保緩慢或失敗的任務不會破壞您的產品體驗。
重點摘要
- 圖像生成是基於任務(job-based)而非請求-回應模式,因為生成延遲(數秒到數十秒)在同步連線上並不穩定。
- 輪詢(Polling)的建置與除錯較簡單;Webhook 可降低延遲與請求量,但需要公開端點、簽章驗證,以及對重複傳送的冪等處理。
- 重試邏輯需區分提交失敗、任務卡住以及 Webhook 漏接,每一種情況都需要不同的恢復路徑。
- 確切的端點名稱、欄位名稱與 Webhook 負載格式會因供應商及 TokenLab 自身的 API 介面而異。在發布前,請務必至 docs.tokenlab.sh 確認當前的具體細節。
為什麼圖像生成 API 是非同步的
文字補全 API 通常可以在同一個連線上回傳回應,因為 Token 生成速度夠快,可以進行串流。圖像生成模型(無論是基於擴散模型還是自回歸模型)通常需要更長的時間,且延遲會根據解析度、模型選擇與佇列深度而有較大變動。將同步 HTTP 請求保持開啟數十秒是非常脆弱的:客戶端逾時、負載平衡器閒置限制以及行動網路中斷,都會增加遺失已付費生成結果的風險。
跨圖像生成供應商採用的標準模式是任務模型:您提交請求並收到一個任務識別碼與初始狀態(通常類似於 queued 或 processing)。隨後,您可以輪詢狀態端點,或在任務達到終止狀態時接收 Webhook 通知,並在單獨的呼叫中獲取最終的圖像 URL 或二進位資料。
TokenLab 透過單一 API 介面提供多種圖像模型的存取權,包括 Nano Banana 2、Nano Banana Pro 與 Nano Banana 2 Lite 系列、GPT Image 2、Reve 2.0 以及 MAI-Image-2.5。請參閱圖像模型目錄以獲取當前清單,並參閱非同步圖像生成任務指南以了解 TokenLab 特定的任務端點行為。下方的通用模式適用於您呼叫的任何底層模型,但確切的欄位名稱與狀態值記錄在 docs.tokenlab.sh 中,應以該處為準,而非從本文推斷。
任務生命週期:提交、輪詢、檢索
從概念層面來看,非同步圖像任務分為三個階段:
- 提交 (Submit):POST 提示詞與參數,接收任務 ID 與初始狀態。
- 檢查狀態 (Check status):使用任務 ID 輪詢 GET 端點,或等待 Webhook 事件。
- 檢索輸出 (Retrieve output):一旦狀態為終止(成功或失敗),獲取圖像 URL 或錯誤詳情。
以下是 Python 中的輪詢模式範例。請將端點路徑與欄位名稱視為預留位置;在使用於生產環境前,請確認當前的 TokenLab 任務端點格式。
import time
import requests
API_BASE = "https://api.tokenlab.sh/v1" # 請在 docs.tokenlab.sh 確認當前基礎 URL
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def submit_image_job(prompt, model="nano-banana-2"):
resp = requests.post(
f"{API_BASE}/images/jobs",
headers=HEADERS,
json={"prompt": prompt, "model": model, "idempotency_key": generate_key()},
)
resp.raise_for_status()
return resp.json()["job_id"]
def poll_job(job_id, max_wait_seconds=120, interval=2, backoff=1.5):
waited = 0
while waited < max_wait_seconds:
resp = requests.get(f"{API_BASE}/images/jobs/{job_id}", headers=HEADERS)
resp.raise_for_status()
data = resp.json()
if data["status"] in ("succeeded", "failed"):
return data
time.sleep(interval)
waited += interval
interval = min(interval * backoff, 15)
raise TimeoutError(f"Job {job_id} did not complete within {max_wait_seconds}s")
job_id = submit_image_job("a studio product shot on white background")
result = poll_job(job_id)
if result["status"] == "succeeded":
image_url = result["output"]["url"]
else:
print("job failed:", result.get("error"))
提交呼叫中的 idempotency_key 非常重要:如果任務已建立但客戶端在收到任務 ID 前發生網路錯誤,使用相同的 Key 重試提交呼叫應會回傳現有的任務,而非建立重複的生成請求。請確認 TokenLab 的任務端點在當前文件中是否支援冪等金鑰,因為這是跨供應商常見但非通用的模式。
輪詢 vs. Webhook:權衡
兩種方法皆可行;正確的選擇取決於您的流量模式與基礎架構。
輪詢的實作與本地測試較簡單,不需要公開端點,適用於低流量或批次工作負載,且對幾秒鐘的額外延遲不敏感的場景。其缺點是存在等於輪詢間隔的延遲下限,且若對長時間執行的任務輪詢過於頻繁,會產生不必要的請求量。
Webhook 會在任務狀態變更時主動推播通知到您的伺服器,這能降低延遲並減少無效的狀態檢查呼叫。其代價是營運成本:您需要一個可公開存取的 HTTPS 端點、簽章驗證以確認負載確實來自供應商,並處理重複或順序錯誤的傳送。
OpenAI 的 Webhook 事件參考文件記錄了非同步操作的通用模式:您的端點會收到包含類型與物件識別碼的事件,建議的做法是將 Webhook 負載視為「前往透過 API 獲取資源當前狀態」的通知,而非將 Webhook 本體視為最終事實來源。這種「推播後拉取 (pull-after-push)」模式值得採用,無論您整合的是哪家圖像供應商,因為它能保護您免受 Webhook 負載被截斷、延遲或多次傳送的影響。
安全地實作 Webhook
如果您選擇使用 Webhook 來處理圖像任務完成,以下做法可減少靜默失敗的機率:
- 驗證簽章:在處理每個傳入的 Webhook 請求前進行簽章驗證。拒絕任何不匹配的請求,並將拒絕記錄與正常流量分開,以便快速發現配置錯誤的密鑰。
- 快速回應,稍後處理:驗證後立即以 200 狀態碼回應 Webhook,然後將實際工作(獲取圖像、寫入儲存空間、通知使用者)交給背景任務或佇列。如果供應商未收到及時的 2xx 回應,通常會重試傳送 Webhook,若您的處理器緩慢且為同步執行,這可能導致重複處理。
- 依任務 ID 去重:儲存已處理的任務 ID(或事件雜湊),確保重試傳送不會導致重複通知或重複寫入檔案。
- 重新獲取資源:使用 Webhook 負載中的任務 ID 重新獲取資源,而非信任嵌入的輸出 URL 為最終結果,這與上述的「推播後拉取」模式一致。
最小化處理器範例:
from flask import Flask, request, abort
app = Flask(__name__)
processed_job_ids = set() # 生產環境請使用真實的儲存空間
@app.route("/webhooks/image-jobs", methods=["POST"])
def handle_webhook():
if not verify_signature(request):
abort(401)
event = request.get_json()
job_id = event.get("job_id") or event.get("data", {}).get("id")
if job_id in processed_job_ids:
return "", 200 # 已處理,確認並跳過
enqueue_background_task("fetch_and_store_image", job_id)
processed_job_ids.add(job_id)
return "", 200
請根據當前的供應商文件,以及 docs.tokenlab.sh 中描述的 TokenLab 自身 Webhook 支援,確認圖像任務完成所使用的確切 Webhook 事件名稱、負載結構與簽章標頭,因為這些細節是供應商特有的且可能隨時變更。
重試設計:三類失敗
非同步圖像任務會以三種截然不同的方式失敗,每一種都需要各自的處理方式:
- 提交失敗:建立任務的 POST 回傳 4xx 或 5xx。對於 5xx 與網路錯誤,請使用指數退避與抖動(jitter)進行重試,並重複使用相同的冪等金鑰,以免建立重複任務。對於 4xx 錯誤(提示詞錯誤、模型無效、配額超限),在不修改請求的情況下重試只會再次失敗;應將錯誤呈現給呼叫者。
- 任務卡住:任務在超過預期生成時間後仍處於非終止狀態。請為每個模型設定最大等待閾值(生成時間因模型與解析度而異),並將超過該閾值的任務視為失敗,即使供應商尚未正式標記為失敗。請將這些情況分開記錄,因為卡住任務的比例上升通常預示著供應商端的事故。
- Webhook 漏接:您的端點當機或傳送遺失,導致事件未送達。這就是為什麼即使在 Webhook 優先的設計中,保留輪詢備援機制仍有價值:定期掃描檢查所有超過幾分鐘且未達終止狀態的任務,可以補捉那些 Webhook 靜默失敗的任務。
決策檢查清單
在決定如何為圖像生成功能串接任務完成機制時,請參考此檢查清單。
| 情境 | 建議方法 | 原因 |
|---|---|---|
| 低流量、內部工具或批次指令碼 | 輪詢 | 建置最簡單;無需公開端點 |
| 注重延遲的使用者功能 | Webhook,搭配輪詢備援掃描 | 延遲較低;備援機制可補捉漏接的傳送 |
| 高任務量(每日數千次) | Webhook | 避免過多的狀態檢查請求量 |
| 無法公開 HTTPS 端點 | 輪詢 | Webhook 需要可存取的接收端 |
| 需要嚴格的重複預防 | 提交時使用冪等金鑰,接收時依任務 ID 去重 | 防止重試提交與重複的 Webhook 傳送 |
| 單一管線中包含多個圖像模型 | 在您的層級標準化任務狀態與錯誤處理 | 底層供應商(參閱圖像模型比較)不共享相同的狀態分類法 |
限制
本文描述了非同步圖像任務 API 的通用模式,並不保證 TokenLab 或上述任何特定底層模型供應商的確切端點路徑、欄位名稱、逾時值或 Webhook 事件名稱。任務狀態詞彙、retry-after 標頭與 Webhook 簽章方案在不同供應商之間各異且可能隨時間變更;請將本文中的程式碼視為範例,而非可直接複製的生產程式碼,並在發布前於 docs.tokenlab.sh 確認當前的請求與回應格式。本文不涵蓋任何特定模型的定價、速率限制或吞吐量保證。
常見問題
我應該總是使用 Webhook 而非輪詢嗎? 不一定。Webhook 以較高的營運成本降低了延遲與請求量。對於低流量或內部使用案例,輪詢通常是更簡單且同樣可靠的選擇。許多生產系統將 Webhook 作為主要路徑,並以定期輪詢掃描作為備援。
重試時如何避免重複生成圖像? 在任務提交請求中使用冪等金鑰,這樣在網路失敗後的重試 POST 請求會回傳現有任務,而非建立新任務。在依賴此功能前,請確認您的供應商任務建立端點是否支援。
如果任務完成時我的 Webhook 端點當機了怎麼辦? 行為取決於供應商;有些會重試傳送一段時間,有些則不保證重傳。無論供應商的重試政策為何,針對超過幾分鐘且無終止狀態的任務進行定期輪詢掃描是一種實用的保障措施。
如果您正在建置圖像生成功能,並希望在一個 API 中比較多個模型的任務存取方式,請檢閱圖像模型目錄與非同步圖像生成任務指南,然後前往 Get Started 查閱 TokenLab 的 API 文件,以確認您建置所需的當前端點與 Webhook 細節。
來源
價格觀測於 2026-07-14
- OpenAI webhook events觀測於 2026-07-14
- TokenLab API documentation觀測於 2026-07-14
- TokenLab model directory觀測於 2026-07-14



