Skip to content

429/容量錯誤:帳號輪換的正確預期與模型容量耗盡的誤區

學完你能做什麼

  • 正確區分「配額不足」和「上游限流」,避免誤判
  • 理解 Antigravity Tools 的自動輪換機制和預期行為
  • 遇到 429 錯誤時,知道如何快速定位問題並優化設定

你現在的困境

  • 看到返回 429 錯誤,誤以為是「模型沒容量了」
  • 配了多個帳號,卻還是頻繁遇到 429,不知道是設定問題還是帳號問題
  • 不清楚系統什麼時候會自動切換帳號,什麼時候會「卡住」

核心思路

什麼是 429 錯誤?

429 Too Many Requests 是 HTTP 狀態碼。在 Antigravity Tools 裡,429 不只代表「請求太頻繁」,還可能是配額耗盡、模型暫時過載等一類「你暫時用不了」的訊號。

代理會嘗試識別 429 的原因

代理會從響應體裡嘗試解析 error.details[0].reasonerror.message,把 429 粗分為幾類(實際以返回為準):

代理識別的類型常見 reason / 線索典型特徵
配額耗盡QUOTA_EXHAUSTED / 文字包含 exhaustedquota可能需要等到配額刷新
速率限制RATE_LIMIT_EXCEEDED / 文字包含 per minuterate limittoo many requests通常是幾十秒等級的冷卻
模型容量不足MODEL_CAPACITY_EXHAUSTED / 文字包含 model_capacity常見是短暫過載,稍後可恢復
未知無法解析走預設冷卻策略

Antigravity Tools 的自動處理

當一次請求遇到 429(以及部分 5xx/過載狀態)時,代理通常會在伺服器端做兩件事:

  1. 記錄冷卻時間:把這次錯誤寫入 RateLimitTracker,後續選帳號時會主動避開「仍在冷卻」的帳號。
  2. 在重試裡輪換帳號: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_EXCEEDEDQUOTA_EXHAUSTED)或 error.message
  • 等待時間RetryInfo.retryDelaydetails[0].metadata.quotaResetDelay(如果存在)
json
{
  "error": {
    "details": [
      {
        "reason": "RATE_LIMIT_EXCEEDED",
        "metadata": {
          "quotaResetDelay": "42s"
        }
      }
    ]
  }
}

你應該看到

  • 如果響應體裡能找到等待時間(例如 RetryInfo.retryDelayquotaResetDelay),代理通常會先等待一小段時間再重試。
  • 如果沒有等待時間,代理會按內建策略給這個帳號加一個「冷卻期」,並在重試裡直接換下一個帳號。

第 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: [
  "account1@example.com(protected=[])",
  "account2@example.com(protected=[])",
  "account3@example.com(protected=[])"
]

方法 3:使用 Proxy Monitor

Monitor 頁面查看請求日誌,關注:

  • Account 欄位是否在不同帳號間切換
  • Status 為 429 的請求後,是否有成功的請求使用了不同帳號

你應該看到

  • 當某個帳號返回 429 後,後續請求自動切換到其他帳號
  • 如果看到多個請求使用同一帳號且都失敗,可能是調度設定問題

第 4 步:優化帳號優先級

為什麼:讓系統優先使用高配額/高等級帳號,減少 429 機率。

在 TokenManager 裡,系統會在選擇帳號前對帳號池做一次排序(會列印 🔄 [Token Rotation] Accounts: ...):

  1. 訂閱等級優先:ULTRA > PRO > FREE
  2. 配額百分比優先:同等級內,配額高的在前
  3. 排序入口:這個排序發生在代理側,最終用哪個帳號以代理側排序+可用性判斷為準。

智慧排序原理(代理側)

優先級是 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:可能的原因:

  1. 所有帳號同時觸發限流(請求頻率過高)
  2. 連續請求在「60s 視窗複用」下反反覆複用同一帳號,更容易把單帳號打到限流
  3. 配額保護誤將可用帳號排除
  4. 帳號總數不足以支撐你的請求頻率

解決

  • 增加更多帳號
  • 使用 PerformanceFirst 模式
  • 檢查 Quota Protection 是否把你要用的模型加入了 protected_models(必要時調整監控模型與閾值)
  • 降低請求頻率

Q2:429 錯誤會自動重試嗎?

A:會在單次請求內自動重試。重試次數上限通常是 3 次,具體計算方式為 min(3, 帳號池大小),且至少嘗試 1 次。

重試次數範例

  • 帳號池 1 個帳號 → 嘗試 1 次(不重試)
  • 帳號池 2 個帳號 → 嘗試 2 次(重試 1 次)
  • 帳號池 3 個或更多帳號 → 嘗試 3 次(重試 2 次)

大致流程

  1. 記錄限流/過載資訊(進入 RateLimitTracker
  2. 如果能解析到等待時間(例如 RetryInfo.retryDelay / quotaResetDelay),會先等待一小段時間再繼續
  3. 重試時強制輪換帳號(attempt > 0force_rotate=true),嘗試用下一個可用帳號發起上游請求

如果所有嘗試都失敗,代理會把錯誤返回給客戶端;同時你仍然可以從響應頭(如 X-Account-Email)或 Proxy Monitor 看到實際使用過的帳號。

Q3:如何查看某個帳號被限流了多久?

A:有兩種方式:

方式 1:查看日誌,搜尋 rate-limited

🔒 [FIX #820] Preferred account xxx@gmail.com is rate-limited, falling back to round-robin

方式 2:日誌中會顯示剩餘等待時間

All accounts are currently limited. Please wait 30s.

Q4:配額保護和限流是一回事嗎?

A:不是。

特性配額保護限流追蹤
觸發條件模型配額低於閾值收到 429 錯誤
作用範圍特定模型整個帳號
持續時間直到配額恢復由上游決定(通常幾秒到幾分鐘)
行為跳過該模型跳過該帳號

Q5:如何強制立即切換帳號?

A:可以從「讓下一次請求更容易換號」的角度入手:

  1. 調度層面:切到 PerformanceFirst,跳過黏性會話與 60s 視窗複用
  2. 固定帳號:如果啟用了 Preferred Account,先清空它,否則會優先用固定帳號(直到它限流/被保護)
  3. 帳號池:增加帳號數量,單帳號被限流時更容易找到替代帳號

單次請求裡,代理本身也會在重試時強制輪換(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.rs38-67
Duration 解析工具src-tauri/src/proxy/upstream/retry.rs11-35
調度模式列舉(CacheFirst/Balance/PerformanceFirst)src-tauri/src/proxy/sticky_config.rs3-12
限流原因解析與預設冷卻策略src-tauri/src/proxy/rate_limit.rs5-258
MAX_RETRY_ATTEMPTS 常數定義(OpenAI handler)src-tauri/src/proxy/handlers/openai.rs14
重試次數計算(max_attempts = min(MAX_RETRY_ATTEMPTS, pool_size))src-tauri/src/proxy/handlers/openai.rs830
OpenAI handler:429/5xx 時標記限流並重試/輪換src-tauri/src/proxy/handlers/openai.rs349-389
帳號排序優先級(ULTRA > PRO > FREE + remaining_quota)src-tauri/src/proxy/token_manager.rs504-538
60s 視窗複用 + 避開限流/配額保護src-tauri/src/proxy/token_manager.rs624-739
限流記錄入口(mark_rate_limited)src-tauri/src/proxy/token_manager.rs1089-1113
429 精確鎖定/即時配額刷新/降級策略(mark_rate_limited_async)src-tauri/src/proxy/token_manager.rs1258-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():標記帳號為限流狀態