模型降级
当主模型返回错误或超时时,模型降级会透明地使用一组备份模型重试请求。客户端收到的是链路中最终成功的那个模型返回的一次成功响应,无需感知任何故障或切换。
降级的工作原理
Section titled “降级的工作原理”降级链路是一个附加到主模型的有序备份模型列表。链路中的每个条目定义了触发该条目降级的条件,网关按顺序评估每个条目。当主模型失败且第一个降级条目触发时,请求使用该备份模型重试。如果该备份模型也失败且下一个条目触发,网关继续尝试后续条目,直到某个模型返回成功响应或链路耗尽。
降级仅在主模型产生故障时生效。返回有效内容但质量较差的响应不会触发降级。判断依据是传输层面的故障:超时和 HTTP 状态码。
每个降级链路条目携带四个触发器:
| 字段 | 类型 | 描述 |
|---|---|---|
model | string | 要尝试的备份模型名称。 |
on_timeout | bool | 如果前一个模型超时,则触发此降级条目。 |
on_status | list of u16 | 如果前一个模型返回了列表中的某个 HTTP 状态码,则触发此降级条目。空列表表示任何非成功状态码都会触发此条目。 |
max_retries | u32 | 该降级模型的最大重试次数。 |
链路以主模型名称为键。每个主模型声明一条链路。降级条目按顺序评估:索引 0 先尝试,然后是索引 1,依此类推。
超时触发的降级
Section titled “超时触发的降级”当某个条目的 on_timeout 设为 true 时,仅在前一个模型超时时才会尝试该条目。当你了解某些模型速度快但在负载下不够可靠时,超时降级很有用。主模型超时会将请求发送到可能更慢但更可靠的备份。
状态码触发的降级
Section titled “状态码触发的降级”每个条目可以通过 on_status 指定 HTTP 状态码列表。当前一个模型以列表中的某个状态码响应时,网关尝试此备份条目。如果 on_status 留空,该条目将在任何非成功状态码时触发。这提供了精细控制:你可能希望在 5xx 服务端错误时降级,但让 4xx 客户端错误原样传播回调用方。
与模型路由集成
Section titled “与模型路由集成”降级链路与模型路由互补。如果使用模型路由按复杂度分类请求,你可以为每个复杂度路由独立配置降级链路。简单路由可能在超时时从 gpt-3.5-turbo 降到 llama-3-8b,而复杂路由在 5xx 错误时从 gpt-4o 降到 claude-3-opus。每个路由保持自己的降级策略。
当主模型失败时,网关调用 resolve_fallback,传入当前模型名称、状态码(如有)、是否超时以及当前尝试次数。该函数执行以下步骤:
- 在内部注册表中查找主模型的链路。
- 使用尝试次数索引降级条目。尝试 0 表示主模型失败,因此检查索引 0 处的条目。尝试 1 检查索引 1 处的条目,依此类推。
- 评估条目的触发条件:如果故障是超时且该条目配置了
on_timeout: true,则触发。如果故障带有状态码且该状态码包含在条目的on_status列表中(或列表为空),则触发。 - 返回要尝试的下一个模型,或当链路耗尽时返回
None。
调用方负责跟踪尝试计数器。每次降级模型失败,调用方递增尝试计数器并再次调用 resolve_fallback。当 resolve_fallback 返回 None 时,链路已全部尝试完毕,网关将最后一个错误返回给客户端。
你可以定义多条降级链路,每个主模型一条。网关以主模型名称为键存储链路,因此查找是哈希表键查找。这意味着你可以为同一路由使用的不同模型配置不同的降级策略:
fallback: chains: - primary: gpt-4o fallbacks: - model: claude-3-sonnet on_timeout: true max_retries: 1 - primary: gpt-3.5-turbo fallbacks: - model: llama-3-8b on_status: [500, 502, 503] max_retries: 2与 AIService 重试的交互
Section titled “与 AIService 重试的交互”AIService 规范已支持带有 maxRetries 和 backoff 的 retry 块。降级模块的 max_retries 字段控制每个降级模型的重试次数。这两种重试机制是独立的:AIService 重试管辖主模型和降级模型在 HTTP 传输层面的重试,而降级链路管辖模型切换决策。一次请求可能因瞬时网络错误重试降级模型一次,之后降级模块才移动到链路中的下一个条目。
降级模块发出指标,便于你监控链路健康状况:
| 指标 | 描述 |
|---|---|
| 降级尝试次数 | 网关尝试降级模型的总次数。 |
| 降级成功次数 | 降级模型返回成功响应的总次数。 |
追踪成功率与尝试次数的比率,以识别那些频繁触发但很少成功的链路。高尝试次数、低成功率说明你的备份模型也不可靠。
一个有用的告警模式是关注在某个时间窗口内降级尝试超过阈值的链路。针对特定主模型的尝试次数突增通常表明上游提供商存在问题,早于用户报告服务质量下降。
检查链路状态
Section titled “检查链路状态”ModelFallback 结构体暴露了用于诊断的辅助方法:
| 方法 | 返回值 | 描述 |
|---|---|---|
primary(model) | Option<&str> | 返回给定链路键的主模型名称。 |
has_fallbacks(model) | bool | 给定模型是否配置了降级链路。 |
fallback_count(model) | usize | 模型降级链路中的条目数量。 |
这些方法在集成测试和健康检查流程中很有用。例如,你可以在配置加载后断言 fallback_count 与预期的条目数量一致,或验证 has_fallbacks 对不应有降级链路的路由返回 false。
此示例定义了一条降级链路,gpt-4o 是主模型。超时时网关降到 claude-3-sonnet。如果 claude-3-sonnet 返回 5xx 状态,网关降到 llama-3-70b:
apiVersion: gateway.nantian.dev/v1alpha1kind: AIServicemetadata: name: resilient-router namespace: nantian-demospec: provider: openai format: openai model: gpt-4o fallback: chains: - primary: gpt-4o fallbacks: - model: claude-3-sonnet on_timeout: true max_retries: 1 - model: llama-3-70b on_status: [500, 502, 503, 504] max_retries: 1此配置的含义是:先尝试 gpt-4o。如果超时,尝试 claude-3-sonnet(1 次重试)。如果 claude-3-sonnet 返回 5xx 状态,尝试 llama-3-70b(1 次重试)。如果 llama-3-70b 也失败,网关将最后一个错误返回给调用方。