---
title: "状态页搭建指南：给 AI 服务拆组件、定等级、写事故更新"
description: "给 AI API 服务做状态页搭建时，组件怎么拆、数据靠探测还是人工发布、状态等级怎么定义、事故更新每段写什么、历史与 JSON/RSS 怎么提供，附上线前检查表。"
url: https://cdnping.org/blog/build-status-page-for-ai-service
language: zh-CN
published: 2026-10-25
category: "开发工具"
tags: ["状态页","status page","可用性监控","AI API","事故管理"]
source: cdnping.org
license: Free to quote and summarize with a link to the url above.
---
# 状态页搭建指南：给 AI 服务拆组件、定等级、写事故更新

状态页搭建的难点不在选哪个工具，而在先想清楚四件事：页面上列哪些组件，每个组件的状态由谁判定，几个等级各自代表什么，出了事故每次更新写什么。对 AI API 服务来说，组件最好按“接入网关 + 各模型组 + 控制台”来拆，状态由自动探测和真实请求统计共同给出，人工只负责确认和写说明。下面按这个顺序讲，文末附上线前检查表。

文中拿 cdnping 自己的 [API 状态页](/status) 和 [AGI Plan 状态页](/status/agiplan) 做参照。AGI Plan 是 cdnping 的商业合作方，这两个页面的做法和缺点我们都比较清楚。

## 状态页到底要回答用户什么问题？

用户打开状态页，通常只想知道三件事：

1. 我现在遇到的问题，是不是你们那边的？
2. 如果是，影响哪部分，你们知道了没有，大概什么时候好？
3. 过去一段时间你们稳不稳？

所以状态页不是监控大盘，不需要把 CPU、队列长度这类内部指标搬上去，只需要给出用户能对照自己情况的结论。用户一般怎么读状态页，可以先看[怎么看 OpenAI 状态页和 Claude 状态页](/blog/how-to-read-ai-status-pages)。

## 组件怎么拆才对 AI 服务有用？

拆组件的原则是：用户能分辨出的故障边界，就是组件边界。用户分不出“鉴权服务”和“计费服务”的区别，但分得出“控制台登不上”和“接口报 5xx”。

一个典型的 AI API 服务可以这样拆：

| 组件 | 用户看到的现象 | 主要数据来源 |
|---|---|---|
| API 接入网关 | 连不上、TLS 失败、所有请求都报错 | 外部探测 |
| 各模型组（例如推理组、通用组、轻量组） | 某一类模型报错多、变慢，其他正常 | 真实请求成功率 |
| 控制台与登录 | 网页打不开、登不上、建不了密钥 | 外部探测 + 人工 |
| 计费与额度 | 扣费异常、额度显示不对 | 人工发布 |
| 文档与官网 | 页面打不开 | 外部探测 |
| 上游依赖（只展示，不计入自家可用率） | 上游厂商有事故 | 同步上游官方状态页 |

模型组为什么要单独拆，数据能说明。以 AGI Plan 为例，cdnping 在 2026 年 10 月 17 日的快照里，从 Cloudflare 边缘（丹佛节点）探测 agiplan.dev 入口，可用率字段为 100%（采集当天才开始，实际只覆盖约一个半小时）；同一份快照里，AGI Plan 公开的按真实请求计算的可用率，最近 1 天“快速组”约为 77.3%，“均衡组”为 100%，“前沿模型组”约为 99.8%。入口能通，不代表每一组模型都能用。如果状态页只放一个“API”组件，这种情况下它会一直是绿色。

上游依赖建议单独成区，标明“第三方”，不计入自己的可用率。

## 状态数据从哪来：自动探测、真实请求还是人工发布？

三种来源各有盲区，单用哪一种都不够。

| 来源 | 能发现什么 | 发现不了什么 | 适合驱动 |
|---|---|---|---|
| 外部定时探测 | 入口不可达、DNS/TLS 问题、整体变慢 | 只有部分模型或部分请求失败 | 网关、控制台、文档 |
| 真实请求统计 | 按组的成功率、错误码分布 | 没有流量的时段（夜里请求很少，比例不可靠） | 各模型组 |
| 人工发布 | 计费错误、数据问题、计划维护 | 反应慢，依赖值班人员 | 事故说明、维护公告 |

探测和真实请求统计的区别，可以参考[合成监控和真实用户监控有什么区别](/blog/synthetic-monitoring-vs-real-user-monitoring-ai)。

cdnping 的 /status 用的是前两种加上游同步：从 Cloudflare 边缘每 5 分钟探测各家官方 API 入口，每 15 分钟同步 OpenAI、Anthropic、Moonshot、Groq、Cloudflare、GitHub、Cursor 的官方状态页，保留 30 天历史。具体口径写在[数据方法](/methodology)里。

探测数据会把真实情况放大或缩小，口径要写清楚。举一个例子：cdnping 在 2026-10-17 北京时间 16:40 到 18:05 之间，从丹佛（DEN）节点共做了 242 次探测，这一窗口里 Kimi 开放平台的可用率字段是 94.4%，p95 延迟 1125 ms，其余入口都是 100%。窗口只有一个半小时、只有一个节点，这个数字说明“这段时间从这个位置探测到过失败”，不能拿来评价长期稳定性。状态页上展示自己的数字时，同样要标明窗口和探测位置。

真实请求统计要注意分母。AGI Plan 的公开口径是“成功 /（成功 + 因平台自身原因失败）”，只有 5xx 算平台失败，用户的 401、429 不算。这个口径你可以不同意，但一定要写出来。夜里每小时只有几个请求时，一次失败就能让比例掉一大截，可以设一个最低请求数，低于它就显示“数据不足”而不是红色。怎么自己测、怎么定口径，可以看[自己测 AI API 的可用率](/blog/measure-ai-api-uptime-yourself)。

### 一个最小探测怎么写？

假设你的接口是 `https://api.example.com`，下面这条命令可以放进任意定时任务，每次输出状态码、连接耗时和总耗时：

```bash
curl -s -o /dev/null --max-time 10 \
  -w '%{http_code} %{time_connect} %{time_appconnect} %{time_total}\n' \
  https://api.example.com/v1/models
```

判断规则可以先这样定：拿不到状态码（超时、DNS 失败、TLS 失败）记为失败；5xx 记为失败；不带密钥返回 401 说明网关在正常工作，记为成功。探测点至少放两个不同地区，只有两个点同时失败才判定为“入口故障”，避免把单个探测点的网络问题算到自己头上。更完整的探测和告警清单见[AI 应用可用性监控怎么做](/blog/ai-app-availability-monitoring-guide)。

## 状态等级怎么定义？

等级越少越好用。建议四级加一个维护状态，并且把阈值写在页面上：

| 等级 | 页面文案 | 示例阈值（按 5 分钟窗口，需按自己的情况调整） |
|---|---|---|
| 正常 | 运行正常 | 成功率 ≥ 99%，p95 延迟在基线 2 倍以内 |
| 性能下降 | 部分请求变慢 | 成功率 ≥ 99%，但 p95 延迟超过基线 2 倍 |
| 部分中断 | 部分请求失败 | 成功率在 90% 到 99% 之间，或某个模型组不可用 |
| 严重中断 | 大部分请求失败 | 成功率低于 90%，或入口不可达 |
| 维护中 | 计划维护 | 提前公告的维护窗口 |

几点经验：

- 自动判定只负责调高等级；降回正常要人工确认或连续几个窗口恢复，避免页面黄绿来回跳。
- 各家给事故定的级别差异很大，不要拿别人的分布当标准。cdnping 同步的官方状态页里，2026-09-17 到 2026-10-17 这一个月，OpenAI 登记了 major 4 次、minor 19 次，Cloudflare 登记了 major 3 次、minor 19 次。大部分事故都标为 minor，标准由各家自己定。
- 可用率目标和等级阈值要对得上。目标和错误预算的算法见[SLI、SLO、SLA 到底差在哪](/blog/sli-slo-sla-error-budget-explained)。

## 事故更新每一段该写什么？

事故公告常见四个阶段：调查中、已定位、观察中、已恢复。每一段都要回答固定的问题：

| 阶段 | 必须写 | 不要写 |
|---|---|---|
| 调查中 | 现象、受影响组件、开始时间、下次更新时间 | 未经确认的原因 |
| 已定位 | 原因的大类（上游、配置变更、容量）、正在做什么 | 甩锅给某个具体厂商的措辞 |
| 观察中 | 已采取的措施、指标是否恢复、用户需不需要操作 | “已完全修复”这类还没验证的结论 |
| 已恢复 | 影响时段（起止时间带时区）、影响范围、后续改进 | 空泛的致歉段落 |

标题写“现象 + 范围”。官方状态页里的标题大多是这个结构，例如 cdnping 同步到的几条：

- Increased HTTP 502 Errors（Cloudflare，minor，持续 591 分钟）
- Network Performance Issues in London（Cloudflare，major，持续 13 分钟）
- Elevated Errors in China Network Colos（Cloudflare，minor）
- Widespread feature degradation（OpenAI，major，持续 146 分钟）

前三条一眼能看出影响和位置，最后一条范围较宽，需要点进去看组件。中文模板如下：

```text
【部分中断】轻量模型组请求失败率升高
开始时间：2026-10-16 14:05（北京时间）
影响：轻量模型组约一半请求返回 5xx，其他模型组和控制台正常。
当前进展：已定位为上游供应商错误率升高，正在将流量切换到备用供应商。
用户需要做什么：无需修改配置；如有重试逻辑，建议使用指数退避。
下次更新：30 分钟内。
```

模板里的时间和比例是示例。AGI Plan 的公开数据里确实能看到类似的小时：cdnping 镜像的快照中，10 月 16 日北京时间 14 时起连续两个小时桶，失败请求分别是 722 和 877 次，多于同一小时的成功数（664 和 455）。像这样的小时，状态页上应该有对应的事故记录，否则用户会觉得页面没有反映实际情况。

另外两条规则：每次更新都写“下次更新时间”，到点没进展也要发一条“仍在处理”；已恢复的事故不要改写前面的更新，保留原文，补充说明即可。

## 历史保留多久？要不要提供 RSS 和 JSON？

历史建议至少保留 30 天，足够覆盖“最近一个月稳不稳”这个最常见的问题；条件允许可以更长。cdnping 的 /status 目前保留 30 天，而且采集从 2026-10-17 才开始，历史还很短，页面上会如实标出。

机器可读的出口建议都给：

- JSON：给用户的监控系统和机器人用。cdnping 的开放数据接口 `/api/status` 以 CC BY 4.0 发布；AGI Plan 在 `https://agiplan.dev/api/status/requests?month=YYYY-MM` 提供逐小时、逐能力组的成功和失败计数，不需要登录。
- RSS / Atom：给只想订阅事故公告的人用，每次事故更新生成一条。
- Webhook 或邮件订阅：用户量大以后再加。

JSON 的字段可以参考下面这个结构（示例，不是某个现有接口的定义）：

```json
{
  "updated": "2026-10-23T12:00:00Z",
  "components": [
    {"id": "gateway", "status": "operational", "uptime_30d": 0.999},
    {"id": "group-fast", "status": "partial_outage", "uptime_30d": 0.98}
  ],
  "incidents": [
    {"id": "inc-001", "title": "轻量模型组请求失败率升高",
     "impact": "minor", "started": "2026-10-16T06:05:00Z", "resolved": null}
  ]
}
```

字段一旦公开就尽量别改名，下游会有人写死解析。

## 用什么搭：需不需要服务器？

开源和托管方案很多，这里不排名，只按部署方式分三类，选哪类取决于你愿意维护什么：

| 类型 | 做法 | 适合 | 要注意 |
|---|---|---|---|
| 无服务器 | 用 CI 定时任务或边缘定时任务做探测，结果写进仓库或对象存储，生成静态页 | 小团队、组件少 | 探测频率受定时任务限制，探测位置单一 |
| 自托管程序 | 常驻服务 + 数据库，自带后台和事故编辑 | 需要人工发布、订阅通知 | 状态页要和主服务分开部署，否则主服务挂了它也一起挂 |
| 托管服务 | 第三方托管页面和订阅 | 不想维护 | 数据口径受平台限制，接入自家请求统计要自己推送 |

不管哪一类，有一条要坚持：状态页和被监控的服务不要共用同一套基础设施，包括域名解析、CDN 和数据库。如果你的主站在 Cloudflare 上，状态页可以放在另一家托管，反过来也一样。2026 年 10 月中旬 Cloudflare 自己的状态页就登记过 Workers 定时触发器（Cron Triggers）和 Durable Objects 的故障，探测程序如果跑在这些组件上，那几天就可能缺数据。

## 上线前检查表

- [ ] 组件按用户能分辨的故障边界拆分，模型组单独列出
- [ ] 每个组件写明数据来源：探测、请求统计还是人工
- [ ] 探测点至少两个地区，单点失败不直接判红
- [ ] 请求统计设了最低请求数，样本不足时显示“数据不足”
- [ ] 等级阈值和可用率口径写在页面或方法说明里
- [ ] 事故模板包含现象、范围、开始时间（带时区）、用户需要做什么、下次更新时间
- [ ] 上游依赖单独成区，不计入自家可用率
- [ ] 历史至少 30 天，并标明采集起始日期
- [ ] 提供 JSON 和 RSS，字段名写进文档
- [ ] 状态页与主服务的 DNS、CDN、数据库分开
- [ ] 演练一次：手动制造一个组件故障，看页面多久变色、公告多久发出

最后一项最容易跳过，也最能暴露问题。上线后可以用 [/down](/down) 这类综合官方状态、API 探测和用户报告的页面对照自己的状态页，看两边的判断是否一致；想了解过去一段时间各家官方状态页实际登记了什么，可以看 [2026 年 9–10 月 AI 服务故障盘点](/blog/ai-service-incidents-sep-oct-2026)。
