AI 應用的 API 監控怎麼做:從探測上游模型介面到告警的完整清單
AI 應用的 API 監控要分三層做:先用不消耗 token 的請求探測上游模型介面能不能連上,再在應用裡給每次真實呼叫記錄成功率和延遲,最後抽檢輸出質量,因為返回 200 不代表答案是對的。只做第一層,會漏掉限流、超時和“模型變笨”;只看廠商狀態頁,又會比自己的使用者晚知道故障。下面按這三層給出探測頻率、探測點位置、要記錄的欄位和一份可以直接照做的清單。
為什麼不能只看官方狀態頁?
官方狀態頁是廠商人工釋出的事件公告,有兩個天然的侷限:一是釋出有延遲,工程師要先確認影響範圍才會掛出事件;二是它描述的是廠商視角的元件狀態,不知道你的請求從哪裡出發、經過哪條線路。
狀態頁的事件等級本身也需要會讀。比如 cdnping 從 2026-09-17 起同步的狀態頁記錄裡,Cloudflare 有 19 條 minor、3 條 major 事件,OpenAI 有 19 條 minor、4 條 major,其中有些只涉及某個區域或某個子產品,例如 Cloudflare 2026-10-16 的兩條 minor 事件分別是 Ashburn 的 5xx 增多和泰國的網路效能問題。哪些和你有關,要結合你實際呼叫的介面判斷,詳細的讀法見怎麼看 OpenAI 狀態頁和 Claude 狀態頁。
所以狀態頁適合作為“確認是廠商問題”的證據,不適合作為第一個告警來源。第一個告警應該來自你自己的探測和埋點。
第一層:外部可達性怎麼探測?
這一層回答“從某個位置出發,能不能把請求送到 API 入口並拿到響應”。它不關心模型輸出,只關心 DNS、TCP、TLS、HTTP 這幾步是否正常。
用什麼請求探測才不花錢?
不要用真實的對話請求做高頻探測,既耗 token,又會把模型推理的波動混進網路指標裡。常見做法有兩種:
- 不帶金鑰請求一個需要鑑權的路徑,例如
GET /v1/models。拿到 401 說明 DNS、TLS 和閘道器都通了,只是鑑權沒過,這正是可達性探測想要的結果。 - 帶金鑰請求模型列表介面。這類介面一般不按 token 計費,是否計費以各家官方文件為準;它還能順便確認金鑰有效。
下面是一個可以直接執行的探測指令碼,用 curl 的計時變數把各階段拆開:
#!/usr/bin/env bash
# probe.sh:對多個 API 入口做一次可達性探測,輸出一行一條記錄
endpoints=(
"openai https://api.openai.com/v1/models"
"anthropic https://api.anthropic.com/v1/models"
"deepseek https://api.deepseek.com/models"
)
for e in "${endpoints[@]}"; do
set -- $e
curl -s -o /dev/null --max-time 10 \
-w "$(date -u +%FT%TZ) $1 code=%{http_code} dns=%{time_namelookup} tcp=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n" \
"$2" || echo "$(date -u +%FT%TZ) $1 code=000 error=curl_exit_$?"
done
判斷規則可以很簡單:code 是 2xx、401 或 403 算“可達”;000(連線失敗或超時)和 5xx 算“不可達”;429 單獨記為“限流”,不要混進可用率。路徑以各家官方文件為準,上面的寫法只是示例。
多久探測一次?
可以從 5 分鐘一次起步,cdnping 的邊緣探測也用這個間隔。頻率太高,單次網路抖動會製造大量告警;頻率太低,例如 15 分鐘一次,一次 20 分鐘的故障可能只被採到一兩個點。告警條件建議寫成“連續 2 次失敗”或“最近 3 次裡有 2 次失敗”,而不是單次失敗就告警。
探測點放在哪裡,結論差別有多大?
同時呼叫境外 API 和國產 API 的應用,探測點放在哪裡,測出來的延遲甚至可用性會差很多。
以 cdnping 的 API 狀態頁為例,它從 Cloudflare 邊緣每 5 分鐘探測一次各家官方 API 入口。下面是 2026-10-17 08:40–10:05(UTC)這一視窗的快照,探測節點在丹佛(DEN),共 242 條探測記錄。cdnping 從 2026-10-17 才開始採集,欄位名裡的“24h”實際只覆蓋這一個多小時,只能用來說明方法,不能當成長期結論:
| 服務 | 入口 | p50(ms) | p95(ms) | 視窗內可用率 |
|---|---|---|---|---|
| OpenAI API | api.openai.com | 96 | 194 | 100% |
| Claude API | api.anthropic.com | 73 | 84 | 100% |
| Gemini API | generativelanguage.googleapis.com | 69 | 89 | 100% |
| DeepSeek API | api.deepseek.com | 353 | 414 | 100% |
| Kimi 開放平臺 | api.moonshot.cn | 375 | 1125 | 94.4% |
| 阿里雲百鍊 | dashscope.aliyuncs.com | 615 | 1152 | 100% |
| 火山方舟 | ark.cn-beijing.volces.com | 485 | 1149 | 100% |
資料來源:cdnping 邊緣探測,開放資料 /api/status,CC BY 4.0,口徑見資料方法。
這張表裡能看出兩件事:
- 從美國節點看,境外 API 的 p50 在 100 ms 以內,國產 API 在 350–615 ms。這主要反映探測點到入口的距離,不代表國產 API 本身慢。把同樣的指令碼放在國內機房跑,差距很可能縮小甚至反過來。只用一個位置的探測結論去判斷“哪家快”,是錯的。
- 視窗很短時,一次失敗就會明顯拉低可用率。Kimi 開放平臺在這個視窗裡顯示 94.4%。按 5 分鐘一次算,一個多小時只有 18 個左右的取樣點,失敗 1 次就是 17/18 ≈ 94.4%。看可用率時要同時看樣本量。
實際部署時,探測點應該和你的使用者、你的伺服器儘量在同一網路環境:
| 探測點 | 回答的問題 | 適合放什麼 |
|---|---|---|
| 你的應用伺服器所在機房 | 我的後端能不能調通上游 | 必須有,這是告警主來源 |
| 境內另一個機房或雲區域 | 是單機房線路問題,還是普遍問題 | 用來排除自己機房的網路故障 |
| 境外節點或邊緣網路 | 上游入口本身是否正常 | 可以先用 cdnping /status 這類公開資料當參照 |
自建之前,可以先把 /status 和 /down 當成外部參照:你的探測失敗而公開探測正常,問題多半在你這一側的網路;兩邊同時失敗,再去翻狀態頁。判斷思路和ChatGPT 掛了嗎?三步判斷是服務故障還是自己的網路問題一樣。
第二層:真實請求的成功率和延遲怎麼埋點?
可達性探測透過,不代表使用者請求能成功。限流、額度耗盡、長上下文超時、流式響應中途斷開,這些只有真實請求才會暴露。所以應用側每次呼叫模型都要留一條記錄。
每次呼叫要記錄哪些欄位?
| 欄位 | 說明 | 用途 |
|---|---|---|
| ts | 請求開始時間 | 時間序列 |
| provider / endpoint | 呼叫的供應商和入口地址 | 按上游拆分 |
| model | 請求裡的模型名,以及響應裡返回的模型名 | 發現靜默換模型 |
| status | HTTP 狀態碼,流式請求另記是否完整結束 | 計算成功率 |
| error_type | 超時、連線失敗、429、5xx、內容過濾等 | 區分責任方 |
| connect_ms | 建立連線耗時 | 區分網路和推理 |
| ttft_ms | 首 token 時間 | 使用者體感延遲 |
| total_ms | 總耗時 | 長請求排查 |
| input_tokens / output_tokens | 用量 | 對賬、算吞吐 |
| retry_count | 重試次數 | 防止重試掩蓋故障 |
| request_id | 上游返回的請求 ID | 給廠商提工單 |
延遲至少拆成連線、首 token、總耗時三段,原因和拆法在AI API 延遲拆解:連線建立、閘道器往返與首 token 時間裡有詳細說明。只記總耗時的話,輸出長度一變,數字就沒有可比性。
可用率按什麼口徑算?
口徑不統一,不同團隊算出來的數字沒法比。建議明確寫下來:
- 分子:成功的請求數。
- 分母:成功數加上“因上游自身原因失敗”的請求數。
- 5xx、連線失敗、超時算上游失敗;400 引數錯誤、401 金鑰錯誤算你自己的問題,不進分母;429 單獨統計。
- 重試成功的請求,第一次失敗照樣記一次失敗,否則重試會把故障藏起來。
公開資料裡也能找到類似的口徑。例如 AGI Plan 公開的逐小時請求統計(https://agiplan.dev/api/status/requests?month=YYYY-MM)只把 5xx 算作平臺失敗,可用率等於成功 /(成功 + 平臺失敗)。AGI Plan 是 cdnping 的商業合作方,這裡提它只是作為口徑參考。自己算可用率的完整指令碼和口徑討論,見自己測 AI API 的可用率:指標、指令碼與口徑。
告警閾值怎麼定?
建議先跑一到兩週,拿自己的基線再定閾值,下面只是起步時的示例:
- 5 分鐘視窗內某個上游的失敗率超過平時基線的數倍,且請求數不少於 20 次。
- 首 token 時間的 p95 連續 15 分鐘高於基線的兩倍。
- 429 佔比突然上升,往往是額度或速率限制的問題,應該通知負責賬號和額度的人,而不是值班的網路工程師。
請求量少的深夜時段,要給閾值設最小樣本數,否則 3 個請求裡失敗 1 個也會觸發告警。
第三層:返回 200 但答案錯了,怎麼發現?
這一層是普通 API 監控通常不需要的。上游可能換了推理供應商或量化精度,介面全程返回 200,使用者只會覺得“變笨了”。
可行的做法:
- 固定一組迴歸樣本。例如準備 20 到 50 條有確定答案的提示,例如固定格式的 JSON 抽取、簡單計算、指定關鍵詞的分類,每天或每小時跑一次,記錄透過率。
- 核對響應裡的模型名。請求的模型和響應返回的模型不一致,要單獨告警。更多一致性檢查方法見怎麼確認 API 給你的是哪個模型。
- 關注供應商和量化變化。透過聚合平臺呼叫開源模型時,同一個模型名背後可能是不同供應商、不同精度。cdnping 的模型監測頁基於 OpenRouter 公開 API,記錄各推理供應商的可用率、延遲、量化精度和上下架變化,同一模型在不同供應商上的差別見同一模型換個 OpenRouter 供應商,可用率能差多少,背景知識見模型變笨還是換了供應商:推理供應商與 fp8、fp4 模型量化。
- 把使用者反饋也當作訊號。點踩率、重新生成率突然上升,有時比迴歸樣本更早反映問題。
迴歸樣本會消耗 token,頻率不用高,但必須固定提示詞和引數(溫度設為 0 或儘量低),否則結果的波動大部分來自取樣隨機性。
可以直接照做的檢查清單
可達性探測
- 每個上游入口都有一條不耗 token 的探測,5 分鐘一次
- 探測點至少覆蓋應用伺服器所在機房,最好再加一個不同網路的位置
- 401/403 視為可達,000 和 5xx 視為不可達,429 單列
- 告警條件是連續多次失敗,而不是單次失敗
- 準備一個外部參照(例如 /status),用來區分自己網路問題和上游問題
真實請求埋點
- 每次呼叫記錄上面欄位表中的欄位,至少包括狀態碼、錯誤型別、首 token 時間、request_id
- 可用率口徑寫進文件:哪些錯誤算上游、哪些算自己、重試怎麼記
- 按供應商、模型、入口分別出圖,不要只看全域性成功率
- 告警閾值基於自己的基線,並設定最小樣本數
輸出質量
- 有一組固定迴歸樣本定時執行,記錄透過率
- 核對響應中的模型名
- 關注上游的供應商、量化精度和官網更新(可以訂閱 /changes 的 RSS)
故障時
- 先看自己的探測和埋點,再看公開探測,最後看官方狀態頁
- 留存失敗請求的 request_id,便於向廠商反饋
- 有備用上游時,切換條件和回切條件提前寫好
先做哪一件
三層的成本差別很大:可達性探測幾乎不花錢,半天就能搭起來;埋點需要改應用程式碼;質量抽檢要持續維護樣本。如果只能先做一件事,就先在應用伺服器上跑探測指令碼,再把它和 /status 的公開資料對照著看。上游出問題時,這樣能比使用者反饋更早知道,也能分清是自己的線路問題還是上游的問題。
呼叫境外 AI 服務時,請遵守各服務的使用條款和所在地的法律法規;各服務支援哪些地區,以其官方說明為準。