AI API 線路推薦的核心不是「哪條線路最快」,而是「哪條線路能讓請求穩定地落在同一個出口上」。網頁端斷一次重新整理即可,腳本裡一次逾時可能讓整批任務重跑,還會帶來重複計費。下面把固定出口、併發連線、逾時重試三件事拆開來講,最後給一份可以直接照著做的排錯步驟。
AI API 呼叫與網頁端的差別
同一個訂閱,瀏覽器裡能開啟的服務,腳本裡未必跑得通。差別不在頻寬,而在請求形態和失敗代價。
- 連線時長不同。網頁端一次頁面載入由幾十個短請求組成,單一請求很快就結束;API 的串流回應會讓一條連線持續幾十秒甚至幾分鐘,中途任何一次抖動都直接反映在輸出上。
- 失敗代價不同。網頁端失敗重試一次;批次任務失敗要重跑,消耗的是配額和費用,還可能因為重複提交產生重複結果。
- 出口敏感度不同。不少 API 服務按「帳號 + 出口 IP」做風控。出口在同一天裡反覆變化,容易觸發二次驗證、臨時限流,嚴重的會直接拒絕。
- 併發模型不同。瀏覽器最多幾個分頁;腳本可以同時開幾十條連線,壓力落在用戶端連線池和出口的 NAT 連線表上。
把這四點放在一起看,選線路的順序就清楚了:先確保出口穩定,再談線路類型,最後才是調逾時參數。
固定出口:為什麼比最快更重要
固定出口指的是同一個帳號的請求,長期從同一個或同一小組出口 IP 出去。它解決的是「伺服器認不認得你」的問題,而不是「跑得快不快」的問題。
出口漂移會造成什麼問題
- 工作階段與 Token 綁定 IP 時,重連換 IP 會讓既有工作階段失效,需要重新驗證。
- 設定了 IP 白名單的介面,出口一變就直接回傳 403。
- 風控系統看到同一帳號短時間內從多個地區登入,會提高驗證等級。
- 排查問題時,日誌裡的出口 IP 每次都不一樣,很難判斷是線路問題還是程式碼問題。
共用出口不等於線路差
很多人把「晚高峰變慢」歸因於線路品質,實際原因常常是出口被共用:同一個出口 IP 上有很多使用者,目標服務看到的是這個 IP 的高頻請求,於是觸發限流。判斷方法是看錯誤類型——如果是 429 或連線被重置,而頻寬測試正常,基本上就是出口側的問題。
怎麼驗證出口是否固定
準備一個能回傳請求來源 IP 的回顯位址,在代理開啟的狀態下連續請求,記錄每次結果;斷開重連後再測一輪;隔幾個小時再測一次。三輪結果一致,才算固定。
export ECHO_URL="你的回顯位址"
# 連續請求,觀察出口 IP 是否漂移
for i in 1 2 3 4 5; do
curl -s --max-time 10 "$ECHO_URL"
printf '\n'
sleep 2
done
併發連線與線路類型的搭配
併發上限由四段共同決定:本機連線池、代理用戶端的多工設定、線路頻寬與出口 NAT 連線表、目標服務的帳號層級限流。任何一段打滿,表現都是逾時或連線被拒,只看其中一段會誤判。
三種線路類型的差別
| 線路類型 | 路徑特徵 | 出口表現 | 適合的呼叫形態 | 需要注意 |
|---|---|---|---|---|
| IEPL 專線 | 走電信業者專線出境,不經過公共網際網路的國際出口 | 出口相對固定,抖動小 | 長連線、串流回應、批次任務 | 成本較高,可選地區比直連少 |
| 中轉 | 先連到就近的中轉節點,再由中轉節點出境 | 出口由落地節點決定 | 日常呼叫、對成本敏感的場景 | 多一跳,中轉節點壅塞時整體變慢 |
| 直連 | 本機直接連境外節點 | 出口隨節點變化 | 輕量請求、臨時除錯 | 國際出口壅塞時波動明顯 |
選哪一種取決於呼叫形態,不是取決於價格。串流回應和批次任務優先選專線,臨時除錯用直連就夠,中轉適合把兩者分開:除錯走一條,正式環境走另一條。
協定層要看的兩點
Shadowsocks、VMess、Trojan、VLESS 走 TCP,Hysteria2、TUIC 基於 QUIC 走 UDP。對 API 呼叫來說,協定選擇影響的是兩件事:
- 時間校驗。VMess 依賴用戶端與伺服器的時間一致性,系統時間偏差過大會直接握手失敗。這類失敗看起來像線路不通,實際上同步一次時間就好。
- UDP 可用性。Hysteria2 和 TUIC 在封包遺失的鏈路上表現更穩,但依賴網路不限制 UDP。部分辦公網路與公共網路會限制 UDP,這時只能退回 TCP 類協定。
逾時與重試:用戶端側的最小設定
逾時不是設一個總數就沒事。一次請求要分成四段看:建立連線、TLS 握手、首位元組回傳,以及串流輸出過程中的閒置間隔。四段混在一起設,排錯時無法定位是哪一段出的問題。
- 連線逾時設短一些,連不上就換線路,不要掛著等。
- 首位元組逾時涵蓋 TLS 與請求送出到第一個位元組回傳,可以比連線逾時寬鬆。
- 閒置讀取逾時針對串流回應,只計算兩段輸出之間的間隔,不計算總時長。
- 總時長對串流請求不要設,否則長回答會被自己的用戶端截斷。
重試要滿足三個條件:請求可重試、錯誤可重試、次數有上限。連線失敗、讀取逾時、429 和 5xx 可以重試;400、401、403 這類參數或驗證錯誤重試多少次都一樣,只會放大問題。
import random
import time
import httpx
API_URL = "https://api.example.com/v1/chat"
# 四段逾時分開設:連線 5s,閒置讀取 60s
timeout = httpx.Timeout(connect=5.0, read=60.0, write=10.0, pool=5.0)
# 連線池上限決定本機併發上限
limits = httpx.Limits(max_connections=16, max_keepalive_connections=8)
with httpx.Client(timeout=timeout, limits=limits) as client:
for attempt in range(4):
try:
with client.stream("POST", API_URL, json={"stream": True}) as resp:
if resp.status_code in (429, 500, 502, 503, 504):
raise httpx.HTTPStatusError(
"retryable", request=resp.request, response=resp
)
resp.raise_for_status()
for line in resp.iter_lines():
handle(line) # 逐行處理,不要先攢進清單
break
except (httpx.ConnectError, httpx.ReadTimeout, httpx.HTTPStatusError):
if attempt == 3:
raise
# 指數退避加抖動,避免多個任務同時重試
time.sleep(min(2 ** attempt, 8) + random.uniform(0, 0.5))
DNS 與分流規則怎麼搭配
DNS 洩漏指的是網域名稱交給本機 DNS 解析,拿到的是「離你最近」的節點,而不是「離出口最近」的節點。對多數 API 來說,伺服器用統一入口,影響有限;但對按區域回傳不同結果的服務,解析結果會直接決定請求打到哪個區域,驗證也可能跟著失敗。
分流比全域更省事
把 API 網域固定走一條線路群組,其餘流量走預設群組,好處有三點:出口穩定、除錯時能單獨切換、一條線路出問題不影響其他任務。規則按網域後綴寫比按 IP 寫更穩,因為 API 的入口 IP 會變,網域不會。
檢查順序
- 在代理開啟的狀態下解析目標網域,記錄結果。
- 關閉代理再解析一次,比對兩次結果是否落在同一區域。
- 用回顯位址確認最終出口 IP,而不是只看解析結果。
- 如果解析結果和出口地區不一致,檢查用戶端的 DNS 設定與分流規則優先順序。
選線路時的自查清單
把上面幾節濃縮成一份清單,選線路時逐條對照,比看參數表有用。下面四個數字是訂閱側能直接確認的條件,不是測速結果。
- 120+ 國家與地區可選出口
- 150+ 線路,可按網域分流
- 不限 裝置台數,瓶頸在出口側
- 7 天 無理由退款,夠跑一輪觀察
- ✅ 出口 IP 是否固定,斷開重連後是否維持不變。
- ✅ 能否指定出口地區,是否有多條線路可切換。
- ✅ 是否支援長連線與串流回應,用戶端會不會做緩衝。
- ✅ 單一帳號併發是否受限,限制在本機還是出口側。
- ✅ 是否支援按網域分流,規則能不能單獨調整。
- ✅ 計費方式是否匹配呼叫量:月付按開通日重置,流量包用完為止、不過期。
- ❌ 只看標稱頻寬,不看出口穩定性。
- ❌ 把除錯、正式環境、批次任務放在同一個出口上。
- ❌ 用單次請求的結果判斷一條線路的好壞。
排錯步驟:從出口 IP 到併發
出問題時不要從改參數開始,按下面的順序走,每一步都有明確的判斷依據。
- 確認代理是否生效。請求回顯位址,看出口 IP 是否為目標地區。IP 沒變,後面都不用查。
- 確認 DNS。比對代理內外的解析結果,判斷是否發生洩漏。
- 確認系統時間。VMess 等協定依賴時間校驗,偏差過大會握手失敗。
- 確認 TLS。憑證錯誤、SNI 不符、中間設備攔截,表現都是連線被重置。
- 確認串流輸出。看首位元組時間與逐行到達情況,判斷是否被緩衝。
- 確認併發。從低併發逐步加壓,記錄錯誤類型分布,而不是只看平均值。
- 確認線路切換。換一條線路重現:能重現說明是用戶端或程式碼問題,不能重現說明是線路問題。
一週觀察記錄與結論
單次請求的結果說明不了什麼。跨境線路的表現按時段波動,平日白天、晚高峰、凌晨是三種狀態。建議用一週時間記錄同一組請求,每次記錄五個欄位:
- 時間與線路名稱
- 出口 IP
- 首位元組時間
- HTTP 狀態碼或錯誤類型
- 是否觸發重試
一週之後看的是分布,不是平均值:錯誤集中在哪個時段、哪條線路、哪類錯誤。如果 429 集中在晚高峰,說明出口被共用;如果連線逾時集中在某條線路,說明那條線路的入口壅塞;如果 TLS 錯誤零散出現,優先查用戶端與中間設備。