一家供应商就是一个单点故障
直接打供应商 API 就是在打赌:他们的端点还在、你还在限流之下、他们那边不会在请求中途变差。多数时候这场赌赢。输的时候,失败归你处理——重试逻辑、第二套 SDK、第二把 key,只有事故时才会被练到的代码。
网关存在就是为了让这场赌没必要。provider/model 字符串如 z-ai/glm-5.2 或 openai/gpt-4o-mini 解析成一份上游候选列表,而不是一个固定目的地,路由器按实时健康度每次请求从中挑选。
回退链
每个请求在一个字节到达上游之前,都走同一段选择序列:
- 按路由策略选出主候选
- 加载该模型配置的每一个上游
- 套用请求级供应商偏好、BYOK 资格和供应商合规策略
- 去掉当前在冷却中的后端
- 返回有序列表 — 主选,然后 fallback 1、fallback 2、…
- 如果每个候选都在冷却,仍然返回完整列表 — 降级服务好过没有
产生主候选的路由策略可按请求配置:
| 策略 | 行为 |
|---|---|
| latency | 最快上游优先 |
| cost | 最便宜上游优先 |
| weighted_round_robin | 按配置权重分配 |
| priority | 按固定优先级尝试上游 |
| random | 加密安全的随机挑选 |
| ab_test | 确定性 userId 哈希 → 变体 |
如果主候选的请求失败,执行器不会把错误抛给调用方——它移到列表里的下一个候选再试,对调用方透明。
断路器停止锤打坏掉的上游
每个请求都去重试死掉的端点既浪费时间,也可能把事故搞得更糟。每个上游后端有自己的断路器,阈值固定:
| Setting | Value |
|---|---|
| Failure threshold | 5 failures |
| Recovery timeout | 60s |
| Half-open max calls | 3 |
| Success threshold to close | 2 |
| Max retries | 2 |
| Retry delay | 1s (exponential backoff) |
后端一旦跳闸,会被直接跳过——没有浪费的往返,也不给调用方加延迟——直到恢复超时过去,断路器放一小批半开探测调用通过。
冷却逐级加码,健康上游才不会饿死
断路器是按后端的、短命的。它下面,一份 KV 支撑的冷却存储在滚动窗口里跟踪失败模式——60 秒观察窗口内 3 次失败就触发冷却——每次再犯把惩罚翻倍,从 60 秒起步,封顶 10 分钟:
Cooldown duration by escalation tier
Base 60s, doubles per tier, capped at 10 minutes
已冷却的后端在路由跑之前就被滤出候选列表,所以抖动的上游恢复时不会持续漏进生产流量。简化后,调度循环像这样:
const candidates = await getFallbackChain(modelId, requestOptions)
// primary + fallbacks, cooled-down backends already removed
for (const backend of candidates) {
if (circuitBreaker.isOpen(backend)) continue
try {
const response = await dispatch(backend, requestBody)
circuitBreaker.recordSuccess(backend)
return response
} catch (err) {
circuitBreaker.recordFailure(backend)
cooldownStore.recordFailure(backend) // may trigger escalating cooldown
// fall through to the next candidate
}
}
throw new AllUpstreamsFailedError(modelId)为什么多出来的那一跳便宜
这里的老实答案不是一个基准数字——而是被比较的两种操作的形状。选候选是一次路由决策加一次缓存读取;生成响应是模型按输出所需时间做推理,一个 token 一个 token。无论路由开销是多少,它每请求只发生一次,而 token 生成贯穿整个响应时长。
它也不会付两遍。网关不会在返回前把上游响应缓冲完——chat completions、Anthropic messages 和 Responses API 流都以 server-sent events 管道穿过,按块做方言到方言的翻译,而不是攒进内存再重放。首 token 时间由上游模型主导,不是前面的路由层。

这给你买到什么
- 供应商宕机时模型 id 仍然可用——请求自动转到下一个已配置上游
- 挣扎中的上游在一个失败窗口内停止收流量,而不是等人注意到
- 恢复是渐进的——半开探测调用,不是后端看起来健康的瞬间把流量全倒回去
- 这些都不要求客户端写重试逻辑——同样的请求、同一把 key、同一种响应形状
经 28+ 家供应商的 170+ 模型路由,自动 failover 内置。
打开 dashboard