429/容量錯誤:帳號輪換的正確預期與模型容量耗盡的誤區
學完你能做什麼
- 正確區分「配額不足」和「上游限流」,避免誤判
- 理解 Antigravity Tools 的自動輪換機制和預期行為
- 遇到 429 錯誤時,知道如何快速定位問題並優化設定
你現在的困境
- 看到返回 429 錯誤,誤以為是「模型沒容量了」
- 配了多個帳號,卻還是頻繁遇到 429,不知道是設定問題還是帳號問題
- 不清楚系統什麼時候會自動切換帳號,什麼時候會「卡住」
核心思路
什麼是 429 錯誤?
429 Too Many Requests 是 HTTP 狀態碼。在 Antigravity Tools 裡,429 不只代表「請求太頻繁」,還可能是配額耗盡、模型暫時過載等一類「你暫時用不了」的訊號。
代理會嘗試識別 429 的原因
代理會從響應體裡嘗試解析 error.details[0].reason 或 error.message,把 429 粗分為幾類(實際以返回為準):
| 代理識別的類型 | 常見 reason / 線索 | 典型特徵 |
|---|---|---|
| 配額耗盡 | QUOTA_EXHAUSTED / 文字包含 exhausted、quota | 可能需要等到配額刷新 |
| 速率限制 | RATE_LIMIT_EXCEEDED / 文字包含 per minute、rate limit、too many requests | 通常是幾十秒等級的冷卻 |
| 模型容量不足 | MODEL_CAPACITY_EXHAUSTED / 文字包含 model_capacity | 常見是短暫過載,稍後可恢復 |
| 未知 | 無法解析 | 走預設冷卻策略 |
Antigravity Tools 的自動處理
當一次請求遇到 429(以及部分 5xx/過載狀態)時,代理通常會在伺服器端做兩件事:
- 記錄冷卻時間:把這次錯誤寫入
RateLimitTracker,後續選帳號時會主動避開「仍在冷卻」的帳號。 - 在重試裡輪換帳號:Handlers 會在單次請求內進行多次嘗試,重試時會
force_rotate=true,從而觸發 TokenManager 選擇下一個可用帳號。
你怎麼知道它有沒有換號?
即使你的請求 body 不變,響應裡通常會帶 X-Account-Email(以及 X-Mapped-Model),你可以用它驗證「這次請求到底用的是哪個帳號」。
什麼時候會遇到 429 錯誤?
場景 1:單個帳號請求過快
現象:即使只有一個帳號,短時間內發送大量請求也會觸發 429。
原因:每個帳號都有自己的速率限制(RPM/TPM),超過就會限流。
解決:
- 增加帳號數量
- 降低請求頻率
- 使用固定帳號模式分散壓力(詳見「固定帳號模式」)
場景 2:所有帳號同時限流
現象:有多個帳號,但所有帳號都返回 429。
原因:
- 帳號總數不足以支撐你的請求頻率
- 所有帳號幾乎同時觸發限流/過載
解決:
- 增加更多帳號
- 調整調度模式為「效能優先」(跳過黏性會話與 60s 視窗複用)
- 檢查配額保護是否誤將可用帳號排除
場景 3:帳號被配額保護誤判
現象:某個帳號的配額很充足,但系統一直跳過它。
原因:
- 開啟了配額保護,閾值設定偏高
- 該帳號的特定模型配額低於閾值
- 帳號被手動標記為
proxy_disabled
解決:
- 檢查配額保護設定(Settings → Quota Protection),按你的使用強度調整閾值與監控模型
- 在帳號資料中檢查
protected_models,確認是不是被保護策略跳過
跟我做
第 1 步:識別 429 錯誤類型
為什麼:不同類型的 429 錯誤需要不同的處理方式。
在 Proxy Monitor 中查看 429 錯誤的響應體,重點看兩類資訊:
- 原因:
error.details[0].reason(例如RATE_LIMIT_EXCEEDED、QUOTA_EXHAUSTED)或error.message - 等待時間:
RetryInfo.retryDelay或details[0].metadata.quotaResetDelay(如果存在)
{
"error": {
"details": [
{
"reason": "RATE_LIMIT_EXCEEDED",
"metadata": {
"quotaResetDelay": "42s"
}
}
]
}
}你應該看到:
- 如果響應體裡能找到等待時間(例如
RetryInfo.retryDelay或quotaResetDelay),代理通常會先等待一小段時間再重試。 - 如果沒有等待時間,代理會按內建策略給這個帳號加一個「冷卻期」,並在重試裡直接換下一個帳號。
第 2 步:檢查帳號調度設定
為什麼:調度設定直接影響帳號輪換頻率和優先級。
進入 API Proxy 頁面,查看調度策略:
| 設定項 | 說明 | 預設值/建議 |
|---|---|---|
| Scheduling Mode | 調度模式 | Balance(預設) |
| Preferred Account | 固定帳號模式 | 未選取(預設) |
調度模式對比:
| 模式 | 帳號複用策略 | 限流處理 | 適用場景 |
|---|---|---|---|
| CacheFirst | 啟用黏性會話與 60s 視窗複用 | 優先等待,極大提升 Prompt Caching 命中率 | 對話類/需要高快取命中率 |
| Balance | 啟用黏性會話與 60s 視窗複用 | 立即切換到備選帳號,兼顧成功率和效能 | 通用場景,預設 |
| PerformanceFirst | 跳過黏性會話與 60s 視窗複用,純輪詢模式 | 立即切換,帳號負載最均衡 | 高併發、無狀態請求 |
快取優先 vs 平衡模式
如果你使用 Prompt Caching 且希望提升快取命中率,選擇 CacheFirst —— 限流時它會優先等待而不是立即換號。如果你更看重請求成功率而不是快取,選擇 Balance —— 限流時它會立即換號。
效能優先模式
如果你的請求是無狀態的(如圖片生成、獨立查詢),可以試試 PerformanceFirst。它會跳過黏性會話與 60s 視窗複用,讓連續請求更容易落到不同帳號。
第 3 步:驗證帳號輪換是否正常工作
為什麼:確認系統能夠自動切換帳號。
方法 1:看響應 Header
用 curl 或你自己的客戶端把響應頭印出來,觀察 X-Account-Email 是否會變化。
方法 2:查看日誌
打開日誌檔案(根據你的系統位置),搜尋 🔄 [Token Rotation]:
🔄 [Token Rotation] Accounts: [
"[email protected](protected=[])",
"[email protected](protected=[])",
"[email protected](protected=[])"
]方法 3:使用 Proxy Monitor
在 Monitor 頁面查看請求日誌,關注:
- Account 欄位是否在不同帳號間切換
- Status 為 429 的請求後,是否有成功的請求使用了不同帳號
你應該看到:
- 當某個帳號返回 429 後,後續請求自動切換到其他帳號
- 如果看到多個請求使用同一帳號且都失敗,可能是調度設定問題
第 4 步:優化帳號優先級
為什麼:讓系統優先使用高配額/高等級帳號,減少 429 機率。
在 TokenManager 裡,系統會在選擇帳號前對帳號池做一次排序(會列印 🔄 [Token Rotation] Accounts: ...):
- 訂閱等級優先:ULTRA > PRO > FREE
- 配額百分比優先:同等級內,配額高的在前
- 排序入口:這個排序發生在代理側,最終用哪個帳號以代理側排序+可用性判斷為準。
智慧排序原理(代理側)
優先級是 ULTRA > PRO > FREE;同一訂閱等級內按 remaining_quota(帳號最大剩餘配額百分比)降序。
操作:
- 拖曳帳號調整顯示順序(可選)
- 刷新配額(Accounts → 刷新所有配額)
- 檢查帳號的訂閱等級和配額
踩坑提醒
❌ 錯誤 1:誤將 429 當成「模型沒容量」
現象:看到 429 錯誤就以為模型沒容量了。
正確理解:
- 429 是限流,不是容量問題
- 增加帳號可以降低 429 機率
- 調整調度模式可以提升切換速度
❌ 錯誤 2:配額保護閾值設定過高
現象:配額充足但系統一直跳過帳號。
原因:Quota Protection 會把低於閾值的模型加入帳號的 protected_models,代理在調度時會跳過「被保護的模型」。閾值過高時,可能導致可用帳號被過度排除。
修正:
- 回到 Settings → Quota Protection,調整監控模型與閾值
- 如果你想搞清楚它到底保護了哪些模型,去帳號資料裡看
protected_models
❌ 錯誤 3:固定帳號模式導致無法輪換
現象:設定了 Preferred Account,但該帳號限流後系統「卡住」。
原因:固定帳號模式下,系統優先使用指定帳號,只有在帳號不可用時才降級到輪詢。
修正:
- 如果不需要固定帳號,清空
Preferred Account - 或確保固定帳號的配額充足,避免限流
檢查點 ✅
- [ ] 能區分配額不足和上游限流
- [ ] 知道如何在 Proxy Monitor 中查看 429 錯誤詳情
- [ ] 理解三種調度模式的區別和使用場景
- [ ] 知道如何檢查帳號輪換是否正常工作
- [ ] 能優化帳號優先級並檢查配額保護策略
常見問題
Q1:為什麼我有多個帳號,還是會遇到 429?
A:可能的原因:
- 所有帳號同時觸發限流(請求頻率過高)
- 連續請求在「60s 視窗複用」下反反覆複用同一帳號,更容易把單帳號打到限流
- 配額保護誤將可用帳號排除
- 帳號總數不足以支撐你的請求頻率
解決:
- 增加更多帳號
- 使用
PerformanceFirst模式 - 檢查 Quota Protection 是否把你要用的模型加入了
protected_models(必要時調整監控模型與閾值) - 降低請求頻率
Q2:429 錯誤會自動重試嗎?
A:會在單次請求內自動重試。重試次數上限通常是 3 次,具體計算方式為 min(3, 帳號池大小),且至少嘗試 1 次。
重試次數範例:
- 帳號池 1 個帳號 → 嘗試 1 次(不重試)
- 帳號池 2 個帳號 → 嘗試 2 次(重試 1 次)
- 帳號池 3 個或更多帳號 → 嘗試 3 次(重試 2 次)
大致流程:
- 記錄限流/過載資訊(進入
RateLimitTracker) - 如果能解析到等待時間(例如
RetryInfo.retryDelay/quotaResetDelay),會先等待一小段時間再繼續 - 重試時強制輪換帳號(
attempt > 0時force_rotate=true),嘗試用下一個可用帳號發起上游請求
如果所有嘗試都失敗,代理會把錯誤返回給客戶端;同時你仍然可以從響應頭(如 X-Account-Email)或 Proxy Monitor 看到實際使用過的帳號。
Q3:如何查看某個帳號被限流了多久?
A:有兩種方式:
方式 1:查看日誌,搜尋 rate-limited
🔒 [FIX #820] Preferred account [email protected] is rate-limited, falling back to round-robin方式 2:日誌中會顯示剩餘等待時間
All accounts are currently limited. Please wait 30s.Q4:配額保護和限流是一回事嗎?
A:不是。
| 特性 | 配額保護 | 限流追蹤 |
|---|---|---|
| 觸發條件 | 模型配額低於閾值 | 收到 429 錯誤 |
| 作用範圍 | 特定模型 | 整個帳號 |
| 持續時間 | 直到配額恢復 | 由上游決定(通常幾秒到幾分鐘) |
| 行為 | 跳過該模型 | 跳過該帳號 |
Q5:如何強制立即切換帳號?
A:可以從「讓下一次請求更容易換號」的角度入手:
- 調度層面:切到
PerformanceFirst,跳過黏性會話與 60s 視窗複用 - 固定帳號:如果啟用了
Preferred Account,先清空它,否則會優先用固定帳號(直到它限流/被保護) - 帳號池:增加帳號數量,單帳號被限流時更容易找到替代帳號
單次請求裡,代理本身也會在重試時強制輪換(attempt > 0 會觸發 force_rotate=true),但重試次數受上限控制。
本課小結
- 429 在 Antigravity Tools 裡是一類「上游暫時不可用」的訊號,可能是速率限制、配額耗盡、模型容量不足等原因
- 代理會記錄冷卻時間,並在單次請求的重試裡嘗試輪換帳號(但重試次數有限)
- 調度模式、Quota Protection、帳號數量都會影響你遇到 429 的機率與恢復速度
- 用 Proxy Monitor、響應頭
X-Account-Email和日誌可以快速定位問題
下一課預告
下一課我們學習 404/路徑不相容:Base URL、/v1 前綴與「疊路徑」客戶端。
你會學到:
- 最常見的接入錯誤(404)是如何產生的
- 不同客戶端對 base_url 的拼接差異
- 如何快速修復 404 問題
附錄:原始碼參考
點擊展開查看原始碼位置
更新時間:2026-01-23
| 功能 | 檔案路徑 | 行號 |
|---|---|---|
| 429 重試延遲解析(RetryInfo / quotaResetDelay) | src-tauri/src/proxy/upstream/retry.rs | 38-67 |
| Duration 解析工具 | src-tauri/src/proxy/upstream/retry.rs | 11-35 |
| 調度模式列舉(CacheFirst/Balance/PerformanceFirst) | src-tauri/src/proxy/sticky_config.rs | 3-12 |
| 限流原因解析與預設冷卻策略 | src-tauri/src/proxy/rate_limit.rs | 5-258 |
| MAX_RETRY_ATTEMPTS 常數定義(OpenAI handler) | src-tauri/src/proxy/handlers/openai.rs | 14 |
| 重試次數計算(max_attempts = min(MAX_RETRY_ATTEMPTS, pool_size)) | src-tauri/src/proxy/handlers/openai.rs | 830 |
| OpenAI handler:429/5xx 時標記限流並重試/輪換 | src-tauri/src/proxy/handlers/openai.rs | 349-389 |
| 帳號排序優先級(ULTRA > PRO > FREE + remaining_quota) | src-tauri/src/proxy/token_manager.rs | 504-538 |
| 60s 視窗複用 + 避開限流/配額保護 | src-tauri/src/proxy/token_manager.rs | 624-739 |
| 限流記錄入口(mark_rate_limited) | src-tauri/src/proxy/token_manager.rs | 1089-1113 |
| 429 精確鎖定/即時配額刷新/降級策略(mark_rate_limited_async) | src-tauri/src/proxy/token_manager.rs | 1258-1417 |
關鍵常數:
MAX_RETRY_ATTEMPTS = 3:單次請求內最大重試次數(OpenAI/Gemini handler)60:60 秒視窗複用(僅在PerformanceFirst之外的模式啟用)5:Token 獲取逾時時間(秒)300:Token 提前刷新閾值(秒,5 分鐘)
關鍵函數:
parse_retry_delay():從 429 錯誤響應中提取重試延遲get_token_internal():帳號選擇與輪換的核心邏輯mark_rate_limited():標記帳號為限流狀態