AI 应用的 API 监控怎么做:从探测上游模型接口到告警的完整清单

博客 / 性能

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 APIapi.openai.com96194100%
Claude APIapi.anthropic.com7384100%
Gemini APIgenerativelanguage.googleapis.com6989100%
DeepSeek APIapi.deepseek.com353414100%
Kimi 开放平台api.moonshot.cn375112594.4%
阿里云百炼dashscope.aliyuncs.com6151152100%
火山方舟ark.cn-beijing.volces.com4851149100%

数据来源:cdnping 边缘探测,开放数据 /api/status,CC BY 4.0,口径见数据方法。

这张表里能看出两件事:

  1. 从美国节点看,境外 API 的 p50 在 100 ms 以内,国产 API 在 350–615 ms。这主要反映探测点到入口的距离,不代表国产 API 本身慢。把同样的脚本放在国内机房跑,差距很可能缩小甚至反过来。只用一个位置的探测结论去判断“哪家快”,是错的。
  2. 窗口很短时,一次失败就会明显拉低可用率。Kimi 开放平台在这个窗口里显示 94.4%。按 5 分钟一次算,一个多小时只有 18 个左右的采样点,失败 1 次就是 17/18 ≈ 94.4%。看可用率时要同时看样本量。

实际部署时,探测点应该和你的用户、你的服务器尽量在同一网络环境:

探测点回答的问题适合放什么
你的应用服务器所在机房我的后端能不能调通上游必须有,这是告警主来源
境内另一个机房或云区域是单机房线路问题,还是普遍问题用来排除自己机房的网络故障
境外节点或边缘网络上游入口本身是否正常可以先用 cdnping /status 这类公开数据当参照

自建之前,可以先把 /status 和 /down 当成外部参照:你的探测失败而公开探测正常,问题多半在你这一侧的网络;两边同时失败,再去翻状态页。判断思路和ChatGPT 挂了吗?三步判断是服务故障还是自己的网络问题一样。

第二层:真实请求的成功率和延迟怎么埋点?

可达性探测通过,不代表用户请求能成功。限流、额度耗尽、长上下文超时、流式响应中途断开,这些只有真实请求才会暴露。所以应用侧每次调用模型都要留一条记录。

每次调用要记录哪些字段?

字段说明用途
ts请求开始时间时间序列
provider / endpoint调用的供应商和入口地址按上游拆分
model请求里的模型名,以及响应里返回的模型名发现静默换模型
statusHTTP 状态码,流式请求另记是否完整结束计算成功率
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,用户只会觉得“变笨了”。

可行的做法:

  1. 固定一组回归样本。例如准备 20 到 50 条有确定答案的提示,例如固定格式的 JSON 抽取、简单计算、指定关键词的分类,每天或每小时跑一次,记录通过率。
  2. 核对响应里的模型名。请求的模型和响应返回的模型不一致,要单独告警。更多一致性检查方法见怎么确认 API 给你的是哪个模型。
  3. 关注供应商和量化变化。通过聚合平台调用开源模型时,同一个模型名背后可能是不同供应商、不同精度。cdnping 的模型监测页基于 OpenRouter 公开 API,记录各推理供应商的可用率、延迟、量化精度和上下架变化,同一模型在不同供应商上的差别见同一模型换个 OpenRouter 供应商,可用率能差多少,背景知识见模型变笨还是换了供应商:推理供应商与 fp8、fp4 模型量化。
  4. 把用户反馈也当作信号。点踩率、重新生成率突然上升,有时比回归样本更早反映问题。

回归样本会消耗 token,频率不用高,但必须固定提示词和参数(温度设为 0 或尽量低),否则结果的波动大部分来自采样随机性。

可以直接照做的检查清单

可达性探测

  • 每个上游入口都有一条不耗 token 的探测,5 分钟一次
  • 探测点至少覆盖应用服务器所在机房,最好再加一个不同网络的位置
  • 401/403 视为可达,000 和 5xx 视为不可达,429 单列
  • 告警条件是连续多次失败,而不是单次失败
  • 准备一个外部参照(例如 /status),用来区分自己网络问题和上游问题

真实请求埋点

  • 每次调用记录上面字段表中的字段,至少包括状态码、错误类型、首 token 时间、request_id
  • 可用率口径写进文档:哪些错误算上游、哪些算自己、重试怎么记
  • 按供应商、模型、入口分别出图,不要只看全局成功率
  • 告警阈值基于自己的基线,并设置最小样本数

输出质量

  • 有一组固定回归样本定时运行,记录通过率
  • 核对响应中的模型名
  • 关注上游的供应商、量化精度和官网更新(可以订阅 /changes 的 RSS)

故障时

  • 先看自己的探测和埋点,再看公开探测,最后看官方状态页
  • 留存失败请求的 request_id,便于向厂商反馈
  • 有备用上游时,切换条件和回切条件提前写好

先做哪一件

三层的成本差别很大:可达性探测几乎不花钱,半天就能搭起来;埋点需要改应用代码;质量抽检要持续维护样本。如果只能先做一件事,就先在应用服务器上跑探测脚本,再把它和 /status 的公开数据对照着看。上游出问题时,这样能比用户反馈更早知道,也能分清是自己的线路问题还是上游的问题。

调用境外 AI 服务时,请遵守各服务的使用条款和所在地的法律法规;各服务支持哪些地区,以其官方说明为准。

相关文章

继续阅读