2026年9月3日,多家主流AI服务在相近时间段出现异常。
OpenAI状态页记录了ChatGPT与Codex错误升高;Anthropic状态页则确认Claude Fable、Mythos和Opus多个模型受到影响。海外媒体和用户监测数据还显示,Grok、Gemini等服务也在相近时段出现访问问题。
需要先说明:
多个平台在相近时间出现异常,不等于它们一定由同一个故障引起。
但这次事件仍然暴露了一个现实问题:当AI已经进入客服、编程、搜索和业务自动化流程后,只连接一个模型,可能已经不够可靠。
一、多家AI服务出现了什么问题?
根据官方状态记录:
- OpenAI报告ChatGPT和Codex出现错误升高;
- Anthropic报告Fable、Mythos、Opus多个模型出现请求错误;
- Grok等服务也出现大量用户故障反馈;
- 部分平台在实施修复后逐步恢复。
OpenAI和Anthropic均未将这次事件描述为永久性故障。
不过对于正在运行的应用来说,即使服务只中断几十分钟,也可能造成:
- AI客服无法回复;
- 编程Agent任务中断;
- 工作流停在中间状态;
- 自动化任务重复执行;
- 用户请求大量积压;
- 重试流量进一步放大故障;
- 已经调用的外部工具无法回滚。
普通聊天失败一次,用户可以刷新页面。
但如果Agent已经修改文件、发送消息或者调用业务接口,简单地"再试一次"可能产生新的风险。
二、为什么只配置一个模型不够?
很多AI应用的调用结构非常简单:
User request
↓
Business service
↓
Fixed model
↓
Return result
这种结构开发成本低,但模型或上游接口出现故障时,整个应用都会停止工作。
更稳妥的结构应该是:
User request
↓
AI call layer
├── Primary model
├── Same-tier fallback model
├── Low-cost degraded model
└── Final fallback strategy
这里的"备用模型"不能只是在名称后面换一个版本。
如果所有模型最终依赖相同的服务商、区域或者基础设施,那么它们仍然可能同时不可用。
真正的容灾需要考虑多个层级:
| 容灾层级 | 作用 |
|---|---|
| 同模型重试 | 处理短暂网络抖动 |
| 同厂商模型切换 | 处理单个模型异常 |
| 跨厂商模型切换 | 处理供应商级故障 |
| 跨区域部署 | 处理区域网络或云服务异常 |
| 本地规则兜底 | 在全部模型失败时维持基本服务 |
| 人工接管 | 处理高风险和不可恢复任务 |
三、哪些错误适合重试?
并不是所有API错误都应该重试。
适合重试的错误
常见的临时性错误包括:
- 连接超时
- 读取超时
- 429 Too Many Requests
- 500 Internal Server Error
- 502 Bad Gateway
- 503 Service Unavailable
- 504 Gateway Timeout
这些错误可能由网络抖动、限流或者上游服务异常引起。
可以采用:
- 较短的首次等待;
- 指数退避;
- 随机抖动;
- 最大重试次数;
- 超过阈值后切换模型。
不适合盲目重试的错误
下面这些错误通常需要先修改配置或请求:
- 400 请求参数错误
- 401 API Key无效
- 403 权限不足
- 404 模型不存在
- 额度或余额不足
- 内容安全策略拒绝
- 上下文长度超限
如果对这些错误持续重试,不仅无法恢复,还可能制造更多请求和费用。
尤其是安全拒绝,不能被误判为普通服务故障后,自动切换到另一个模型绕过限制。
四、Python实现模型自动切换
下面使用兼容OpenAI SDK的接口,实现一个基础的重试和模型回退方案。
模型名称只是配置项,请替换成控制台中实际可用的模型ID。
import os
import random
import time
from openai import (
APIConnectionError,
APIStatusError,
APITimeoutError,
OpenAI,
)
client = OpenAI(
api_key=os.environ["AI_API_KEY"],
base_url="https://genvis.xyz/v1",
timeout=30,
max_retries=0,
)
MODEL_CANDIDATES = os.getenv(
"MODEL_CANDIDATES",
"primary-model-id,fallback-model-id,degraded-model-id",
).split(",")
RETRYABLE_STATUS_CODES = {
408,
429,
500,
502,
503,
504,
}
def wait_before_retry(attempt: int) -> None:
delay = min(2 ** attempt, 8)
jitter = random.uniform(0, 0.5)
time.sleep(delay + jitter)
def request_model(model: str, messages: list[dict]) -> str:
response = client.chat.completions.create(
model=model,
messages=messages,
)
return response.choices[0].message.content or ""
def chat_with_fallback(messages: list[dict]) -> tuple[str, str]:
last_error = None
for model in MODEL_CANDIDATES:
model = model.strip()
if not model:
continue
for attempt in range(2):
try:
answer = request_model(model, messages)
return model, answer
except (APIConnectionError, APITimeoutError) as error:
last_error = error
wait_before_retry(attempt)
except APIStatusError as error:
last_error = error
if error.status_code not in RETRYABLE_STATUS_CODES:
raise
wait_before_retry(attempt)
print(f"{model} temporarily unavailable, switching to fallback model")
raise RuntimeError("All candidate models failed") from last_error
messages = [
{
"role": "system",
"content": "You are a technical support agent. Answer accurately and concisely.",
},
{
"role": "user",
"content": "Why does an API request return 503?",
},
]
used_model, answer = chat_with_fallback(messages)
print(f"Model actually used: {used_model}")
print(answer)
这段代码做了四件事:
- 关闭SDK内置重试,避免与业务重试叠加;
- 只对临时性故障进行重试;
- 为每个模型设置有限的重试次数;
- 当前模型持续失败后,自动尝试下一个模型。
五、为什么必须使用指数退避?
假设上游服务突然出现故障,同时有一万个客户端立即重试。
如果每个客户端都以固定间隔持续发送请求,上游服务即使开始恢复,也可能再次被重试流量压垮。
指数退避会逐渐增加等待时间:
First failure: wait about 1 second
Second failure: wait about 2 seconds
Third failure: wait about 4 seconds
Fourth failure: wait about 8 seconds
再加入少量随机时间,可以避免大量客户端在完全相同的时刻再次发送请求。
不过,指数退避不能无限进行。
生产环境通常还需要限制:
- 单模型最大重试次数
- 整个请求最大耗时
- 全链路最大调用次数
- 单个任务Token预算
- 同一用户并发数量
六、只做模型切换还不够
如果服务已经持续故障,每个新请求都先等待主模型超时,再尝试备用模型,会让用户一直承受额外延迟。
因此还需要熔断器。
熔断器一般有三种状态:
| 状态 | 行为 |
|---|---|
| Closed | 正常请求主模型 |
| Open | 暂时跳过故障模型 |
| Half-Open | 发送少量请求测试是否恢复 |
例如,一个模型在60秒内连续失败5次,可以暂时熔断2分钟。
熔断期间,新请求直接使用备用模型,不再等待主模型反复超时。
两分钟后,可以放行少量探测请求:
- 探测成功:恢复正常调用;
- 探测失败:重新进入熔断状态。
这比"每个请求都重新试一遍"更加稳定。
七、Agent任务不能直接整段重跑
普通文本生成通常是幂等的:失败后重新生成一次,影响不大。
Agent任务却可能已经执行了一部分操作。
例如:
Step 1: Generate refund plan
Step 2: Call refund API
Step 3: Send notification
Step 4: Write processing record
如果第三步发生超时,系统无法立即判断通知到底有没有发送成功。
此时直接从第一步重新执行,可能导致重复退款或重复通知。
因此,Agent容灾还必须记录任务状态:
- task_id
- current_step
- tool_call_id
- operation_status
- request_fingerprint
- last_successful_step
对于付款、退款、发券、删除数据和发送消息等操作,应当增加:
- 幂等键;
- 操作前确认;
- 操作结果查询;
- 状态持久化;
- 人工复核入口;
- 不可逆操作白名单。
模型负责决定"做什么",业务系统必须决定"这项操作是否允许再次执行"。
八、降级模型应该怎样选择?
备用模型不是随便选择一个便宜模型。
至少需要比较以下能力:
| 指标 | 说明 |
|---|---|
| 上下文长度 | 能否容纳当前任务资料 |
| 工具调用 | 是否支持稳定的函数调用 |
| 结构化输出 | 能否返回要求的JSON结构 |
| 多模态能力 | 是否需要识别图片或文件 |
| 延迟 | 能否满足实时业务需求 |
| 价格 | 是否适合大量兜底请求 |
| 安全边界 | 是否允许当前任务类型 |
| 服务商依赖 | 是否与主模型共享故障域 |
例如,代码审查任务切换模型后,备用模型仍然需要理解大型代码上下文。
如果备用模型上下文不足,系统应该缩减输入、生成摘要或者转人工处理,而不是直接截断关键代码。
九、所有模型都失败时怎么办?
多模型并不代表永远不会失败。
当全部模型均不可用时,应用仍然需要最低限度的服务能力。
AI客服
可以返回预设提示:
Smart service is temporarily busy. Your issue has been recorded.
For account, payment, or security issues, please wait for manual handling.
内容生成
可以把任务写入队列,等待服务恢复后继续执行。
编程Agent
应保存当前工作区、执行步骤和最后一次成功操作,避免恢复后从头运行。
高风险业务
付款、退款、账号操作和数据删除等请求,应该立即停止自动化流程并转人工确认。
一个好的兜底方案,不一定能继续完成任务,但必须避免把暂时故障扩大成业务事故。
十、生产级AI调用检查清单
上线前可以逐项确认:
- 是否设置连接和读取超时;
- 是否限制单模型重试次数;
- 是否只重试临时性错误;
- 是否使用指数退避和随机抖动;
- 是否准备同厂商备用模型;
- 是否准备跨厂商备用模型;
- 是否设置熔断和恢复探测;
- 是否记录实际使用的模型;
- 是否记录状态码、延迟和Token用量;
- 是否设置单任务成本上限;
- 工具调用是否使用幂等键;
- 不可逆操作是否需要人工确认;
- 全部模型失败时是否有兜底方案;
- 是否定期进行故障切换演练。
十一、几个常见问题
多模型切换一定能避免宕机吗?
不能。
如果多个模型共享云服务、网络、区域或者同一个上游通道,它们仍然可能同时故障。多模型只能降低风险,不能消除风险。
遇到429应该立即换模型吗?
不一定。
短时间限流可以先进行有限重试;如果持续收到429,或者预计等待时间过长,再切换备用模型。
内容安全拒绝可以切换模型重试吗?
不应该将安全拒绝当作普通故障自动绕过。系统需要识别拒绝原因,并按照业务合规规则处理。
为什么要记录实际使用的模型?
因为切换后,输出质量、延迟和费用可能发生变化。只有记录实际模型,才能分析故障期间的成功率和成本。
备用模型需要和主模型能力完全相同吗?
不需要,但必须满足业务的最低能力要求。无法完成原任务时,应明确降级或者转人工,而不是返回看似成功但实际不可用的结果。
总结
这次多家AI服务在相近时间出现异常,提醒开发者重新审视AI应用的可靠性设计。
真正的生产级AI系统,不应该只是:
调用模型 → 返回结果
而应该具备:
Timeout control
→ Limited retry
→ Exponential backoff
→ Circuit breaker
→ Model switch
→ State recovery
→ Final fallback
模型能力越强、Agent执行的步骤越多,故障产生的影响也越大。
选择更强的模型可以提高任务上限;设计可靠的调用架构,才能决定业务能不能持续运行。
参考资料
- OpenAI状态记录:ChatGPT与Codex错误升高
- Anthropic Claude服务状态
- Ars Technica:多家AI服务出现重叠故障
- Axios:多家AI服务发生异常