500 和 502 表示故障,而不是限制。這使它們成為此類錯誤中幾乎值得立即重試的類型——不同於 429(你自己的速率限制)和 529(供應商已滿載)。對三者中的錯誤類型重試,會把小型事故變成你自己的事故。
錯誤
// Straight from the model provider (HTTP 500)
{
"type": "error",
"error": { "type": "api_error", "message": "Internal server error" }
}
// From a gateway or proxy in between (HTTP 502)
{
"error": {
"message": "Failed to reach upstream provider",
"type": "upstream_error",
"code": "upstream_error",
"param": null
}
}原因與解決方法一覽
| 原因 | 解決方法 |
|---|---|
| 供應商端的暫時性故障 | 使用指數退避與抖動重試,最多約 5 次。 |
| 連線已接受,之後卻始終沒有回應 | 這是卡住,而不是錯誤。將首位元組時間與總耗時分開設定上限。 |
| 中介元件回傳自己的 502 | 與模型無關。檢查回應主體是否符合供應商格式,或是代理伺服器格式。 |
| 在真正的事故期間盲目重試 | 限制嘗試次數並採用退避——否則你的重試會成為中斷服務的一部分。 |
選擇處理方式前,先區分 500、529 與 429
429 是你超出速率限制——請降低速度。529 是供應商已達容量——請採用更大幅度且更長時間的退避。500/502 是故障,通常短暫,且常常只針對單一請求。只有第三種值得快速重試;將三者一視同仁,正是重試迴圈讓事故惡化的原因。
重試 5xx,絕不重試 4xx
使用帶抖動的指數退避,最多五次嘗試。同一個輔助函式可適用於所有供應商——400 或 422 在下一次嘗試時仍會以相同方式失敗,因此重試只會增加延遲,最後得到相同錯誤。
import time, random
from openai import OpenAI, APIStatusError
client = OpenAI(base_url="https://api.kunavo.com/v1", api_key="sk-kn-...")
def with_backoff(fn, max_retries=5):
for attempt in range(max_retries):
try:
return fn()
except APIStatusError as e:
if e.status_code not in (429, 500, 529):
raise # don't retry auth/validation errors
retry_after = e.response.headers.get("retry-after")
delay = float(retry_after) if retry_after else min(2 ** attempt, 30)
time.sleep(delay + random.uniform(0, 0.5)) # jitter avoids herds
raise RuntimeError("retries exhausted")
resp = with_backoff(lambda: client.chat.completions.create(
model="claude-sonnet-5",
messages=[{"role": "user", "content": "ping"}],
max_tokens=32,
))
print(resp.choices[0].message.content)將首位元組時間與總耗時分開設定上限
整個請求只設定一個逾時,無法區分長時間生成與失效連線。為首位元組設定較短期限,為其餘內容設定較寬裕期限;如此一來,卡住會快速失敗,而真正緩慢的答案則不會被中斷。
記錄每次嘗試的狀態與延遲
如果沒有每次嘗試的記錄,事後看來,供應商事故與你自己的逾時會完全相同。狀態碼、延遲與嘗試次數已足以讓你在隔天早上區分兩者。
如果你透過 Kunavo 呼叫
截至 2026 年 9 月,Kunavo 上的每個 Claude 模型都透過單一上游通道提供服務,因此該通道的 5xx 不會在請求內重試:它會以攜帶訊息「Upstream provider error」的 502 到達你這端(在 /v1/messages 上類型為 api_error),且請求會以零成本記錄。Kunavo 的請求內重試只會針對已設定第二通道的模型執行:逾時、5xx、429,或 Kunavo 自己的上游金鑰遭拒時,請求會在任何結果到達你這端之前,先透過第二通道重試。這項機制適用於 /v1/messages、/v1/responses,以及 /v1/chat/completions 上的 Claude 模型。串流會在第一段內容到達前暫緩傳送,因此尚未開始傳送的串流內錯誤也會重試;內容開始傳送後,串流中途的失敗則由你自行處理。無論如何,請在你這端保留本頁所述的重試策略。 該行為背後的路由說明位於 我們的 AI 閘道指南.
常見問題
回傳 500 的請求會向我收費嗎?
在 Kunavo,不會——失敗的請求會以零成本記錄。直接向供應商付費時情況各異,但 5xx 通常不會收費。
重試 500 可能產生兩個完成結果嗎?
可能。請求可能在模型已經生成內容後才失敗。如果工作具有副作用,請先在自己的層級確保冪等性,再加入重試。
500、502 與 529 的一句話差異是什麼?
500 表示供應商發生故障,502 表示其前方的某個元件無法連上供應商,而 529 表示供應商已達容量——前兩者應很快重試,第三者則應在更久之後重試。