登录联系我们免费开始
Reliability and Routing2026年8月1日Flatkey Team

模型回退策略:三种工作流操作手册

一份面向生产环境的操作手册,帮助决定何时重试、切换模型,或停止并协调不安全的 AI 工作流。

模型回退策略:三种工作流操作手册

模型回退并不是单一行为。它是一组具有不同安全边界的恢复决策。

生产环境中的模型回退策略应当区分三种工作流:

  1. 重试或等效故障转移:当请求仍然可以安全重放时。
  2. 跨模型回退:当另一种模型可以满足相同的能力和质量契约时。
  3. 停止、对账或升级处理:当输出已经到达用户,或者工具侧效应可能已经发生时。

这种区分很重要,因为最快的恢复动作并不总是最安全的。重放一次失败的分类请求通常风险较低。在流式答案进行到一半时,或在一次不确定的支付工具调用之后,悄悄切换模型则不是如此。

本操作手册将回退策略转化为三种可由团队实现、测试和观测的运营工作流。

一张表看懂模型回退决策

先看请求状态,而不是提供方名称。

请求状态 首选工作流 典型操作 不要这样做
没有响应字节,瞬态传输错误 工作流 1 有边界地重试,然后切换到等效端点故障转移 没有截止时间或预算地重试
没有响应字节,速率限制或过载 工作流 1 遵循重试指引,施加抖动,然后切换到等效容量 制造同步重试风暴
主目标不可用,但存在兼容模型 工作流 2 检查回退契约,然后路由到已批准的替代模型 假设每个模型都支持相同的工具、模式或上下文
结构化响应验证失败 工作流 2 修复一次,或尝试符合模式契约的已批准模型 把 HTTP 200 当作任务成功
部分流已送达 工作流 3 停止,标记为部分完成,提供明确的重新开始 将第二个模型无痕拼接进同一个答案
写入侧工具可能已执行 工作流 3 使用幂等性记录对齐工具状态 自动重放整个模型与工具工作流
安全或策略分类不确定 工作流 3 根据产品策略升级处理或失败关闭 为了维持可用性而降低安全门槛

核心规则很简单:重试保持目标不变,等效故障转移保持模型契约不变,而跨模型回退会改变契约风险。 每一步都需要更强的资格校验。

关于断路器、错误归一化以及供应商中立控制器的更深入说明,请参见 LLM API 回退路由操作手册

在这些工作流之前:先定义一个回退信封

每个请求都应带着一个有边界的信封进入路由层。这个信封告诉系统:在请求必须停止之前,允许进行多少恢复。

type FallbackEnvelope = {
  requestId: string;
  deadlineMs: number;
  maxAttempts: number;
  maxAddedLatencyMs: number;
  maxCostUsd?: number;
  allowEquivalentFailover: boolean;
  allowCrossModelFallback: boolean;
  allowAfterPartialOutput: false;
  sideEffectMode: "none" | "read_only" | "write_possible";
  requiredCapabilities: string[];
  requiredSchemaVersion?: string;
};

这些值应该来自产品工作流,而不是全局默认值。后台摘要任务可以容忍比交互式编码助手更高的延迟。没有工具的聊天回复,可以容忍与能够部署代码或发送邮件的代理不同的恢复行为。

这个信封还可以防止嵌套重试。如果 SDK、应用程序、网关和提供方适配器都各自独立重试,一次小型事故就可能放大为大规模的尝试突发。选择一层来负责总尝试预算,并要求所有更低层报告它们已经消耗了多少。

工作流 1:重试,然后进行等价故障切换

当操作可以重放,并且系统尚未暴露部分输出或进入不确定的副作用状态时,使用此工作流。

等价目标是另一条路由,它保持重要合同不变:相同的模型行为类别、所需能力、模式预期、安全配置以及兼容的上下文限制。它可以是不同的区域、部署、提供方端点或容量池。

步骤 1:规范化故障

将特定于提供方的响应映射到一个较小的内部分类中:

  • transport_transient
  • rate_limited
  • provider_overloaded
  • provider_server_error
  • authentication_or_permission
  • invalid_request
  • deadline_exhausted
  • contract_failure
  • partial_output
  • side_effect_uncertain

通常只有前四类才符合自动重放的条件。身份验证、权限和无效请求错误应停止,因为不同的端点不太可能修复该请求。合同失败属于工作流 2。部分输出和不确定的副作用属于工作流 3。

步骤 2:计算剩余预算

在每次尝试之前,检查:

remaining time > estimated next-attempt latency + response safety margin
remaining attempts > 0
remaining added latency > 0
remaining cost budget > estimated attempt cost, when a cost ceiling exists

如果任何必需预算已耗尽,则退出,而不是再尝试一个提供方。

步骤 3:使用退避和抖动进行重试

如有可用,使用提供方的重试指导。否则,采用带抖动的指数退避,并将延迟控制在请求截止时间内。

function retryDelayMs(attempt: number, retryAfterMs?: number): number {
  if (retryAfterMs !== undefined) return retryAfterMs;

  const base = Math.min(250 * 2 ** attempt, 4_000);
  const jitter = Math.random() * base * 0.3;
  return Math.round(base + jitter);
}

抖动很重要,因为否则许多同时发起请求的客户端可能会按同一节奏重试,从而延长过载事件。你的LLM 限流指南应当定义 RPM、TPM、队列、并发和重试预算如何相互作用。

步骤 4:切换到等效容量

如果同一个目标仍然处于不健康状态,只有在检查以下内容之后,才路由到等效端点:

  • 熔断器已关闭,或处于半开状态以进行探测。
  • 目标支持所需的输入和输出模式。
  • 目标可以在其上下文限制内接受该请求。
  • 目标使用预期的安全和数据处理配置。
  • 此次尝试仍符合截止时间和成本范围。

等效故障转移通常比更换模型风险更低,因为它的目标是保持响应契约。

步骤 5:记录恢复原因

返回如下路由结果:

{
  "workflow": "retry_equivalent_failover",
  "primary_attempts": 2,
  "equivalent_failover_attempts": 1,
  "recovered": true,
  "recovery_reason": "provider_overloaded",
  "added_latency_ms": 684
}

除非你的产品承诺提供这种透明度,否则不要向终端用户暴露内部提供商细节。但请将它们保留在追踪和运维日志中。

工作流 2:受控的跨模型回退

只有当备用模型已针对该任务预先批准时,跨模型回退才适用。能返回文本并不够;它必须满足工作流契约。

步骤 1:创建能力契约

为每一类路由定义不可协商的要求。

{
  "route_class": "support_ticket_triage_v3",
  "required": {
    "input": ["text"],
    "output": ["json_schema"],
    "tools": [],
    "minimum_context_tokens": 24000,
    "schema": "triage-result-v3",
    "languages": ["en", "es", "de"],
    "safety_profile": "customer-support-standard"
  },
  "fallback_models": [
    "approved-model-b",
    "approved-model-c"
  ]
}

对于使用工具的路由,请包含工具选择行为、并行工具支持、参数模式处理,以及模型是否能够可靠地遵循“不要调用”的条件。对于结构化输出,在每次尝试后都要根据模式验证实际响应。

步骤 2:区分传输成功和任务成功

HTTP 成功响应仍然可能让产品工作流失败。至少评估三个层面:

  1. 传输成功:提供商返回了完整响应。
  2. 契约成功:响应已解析、符合模式,并且正确使用了受支持的工具。
  3. 任务成功:输出确实以可接受的质量水平完成了用户的工作。

在比较回退候选项时,这一区分至关重要。一个响应率很高但经常出现模式或工具失败的模型,并不是可靠的回退方案。

步骤 3:按策略对已批准候选项排序

生产路由器可以使用运营信号对符合条件的目标进行评分,而不是假装某一个模型在所有情况下都最优。

type Candidate = {
  id: string;
  capabilitiesPass: boolean;
  circuitOpen: boolean;
  estimatedLatencyMs: number;
  estimatedCostUsd: number;
  recentContractSuccess: number;
  recentTaskSuccess: number;
};

function eligible(candidate: Candidate, envelope: FallbackEnvelope): boolean {
  return (
    candidate.capabilitiesPass &&
    !candidate.circuitOpen &&
    candidate.estimatedLatencyMs <= envelope.maxAddedLatencyMs &&
    (envelope.maxCostUsd === undefined ||
      candidate.estimatedCostUsd <= envelope.maxCostUsd)
  );
}

不要为每个任务都使用静态的“主模型、备份模型、再备份模型”列表。用于代码生成的最佳回退集合,可能与用于抽取、翻译、视觉或工具执行的最佳集合不同。

步骤 4:验证回退输出

先应用确定性检查:

  • JSON 或 schema 验证
  • 必填字段检查
  • 工具参数验证
  • 引文或 URL 格式检查
  • 长度和语言约束
  • 禁止的输出模式

然后再添加工作流特定的质量检查。这些检查可以是轻量规则、任务评估器、抽样人工审核,或经过验证的 judge 模型。如果质量门禁失败,不要将该回退标记为已恢复。

步骤 5:灰度发布策略变更

在扩展新的回退模型之前:

  1. 回放离线评估集。
  2. 在策略允许的情况下运行影子流量。
  3. 仅对一小部分符合条件的失败启用该候选模型。
  4. 比较契约成功率、任务成功率、延迟和成本。
  5. 只有在恢复收益大于回归风险时才扩大范围。

使用一个 LLM API 可观测性 schema 跟踪这些指标,该 schema 为每次尝试记录一条 route 和一个 span。

工作流 3:停止、协调或升级

有些失败不应触发另一轮模型调用。正确的回退是受控停止。

情况 1:部分流式输出

一旦响应 token 已经到达用户,悄然切换模型可能会造成矛盾、重复内容、损坏的代码块,或风格突然变化。它还会让最终响应难以归因和调试。

应改为使用以下明确结果之一:

  • 以可恢复错误结束流,并提供“重试”操作。
  • 提供从头重新开始回答的选项。
  • 只有在应用具有设计好的恢复协议,并且新模型接收到了完全一致的已接受前缀时才继续。

默认应为 allowAfterPartialOutput: false

情况 2:不确定的工具副作用

假设某个模型选择了支付、邮件、部署、工单或数据库写入工具。即使在你的编排器记录结果之前连接失败,该工具也可能已经执行成功。重放完整工作流可能会重复产生副作用。

用以下方式保护写入类工具:

  • 基于用户操作而不是提供方尝试次数的幂等键。
  • 具有 plannedstartedsucceededfailedunknown 状态的持久执行记录。
  • 在工具边界进行去重。
  • 在任何重放之前先执行对账查询。
  • 对于仍然存在不确定性的高影响操作进行人工审核。
type ToolExecution = {
  operationId: string;
  toolName: string;
  state: "planned" | "started" | "succeeded" | "failed" | "unknown";
  externalReference?: string;
};

function nextAction(execution: ToolExecution): "continue" | "reconcile" | "stop" {
  if (execution.state === "succeeded") return "continue";
  if (execution.state === "failed") return "stop";
  return "reconcile";
}

将提供方凭据与工具凭据分开管理。安全 API 密钥管理指南介绍了相关的密钥和访问控制模型。

情况 3:安全、权限或策略不确定性

可用性不应削弱安全或授权决策。如果回退候选项不支持所需的策略控制,则该路由不具备资格。如果系统无法判断某项操作是否被允许,则应根据产品的风险模型进行拒绝关闭或升级处理。

情况 4:没有候选项满足契约

返回应用程序可以处理的类型化失败:

{
  "status": "unavailable",
  "reason": "no_eligible_fallback",
  "retryable": true,
  "retry_after_ms": 30000,
  "request_id": "req_123"
}

清晰的降级响应,胜过一个看似成功但违反了 schema、使用了错误工具或执行了错误副作用的答案。

将这三种工作流放入一个状态机

编排层应明确地表达这一转换。

START
  -> PRIMARY_ATTEMPT
     -> SUCCESS: validate and return
     -> TRANSIENT + replayable: WORKFLOW_1
     -> CONTRACT_FAILURE + approved alternate: WORKFLOW_2
     -> PARTIAL_OUTPUT or SIDE_EFFECT_UNCERTAIN: WORKFLOW_3

WORKFLOW_1
  -> retry inside budget
  -> equivalent failover inside budget
  -> if compatible alternate allowed: WORKFLOW_2
  -> otherwise: STOP

WORKFLOW_2
  -> capability check
  -> alternate attempt
  -> contract and task validation
  -> return only on validated success
  -> otherwise: STOP

WORKFLOW_3
  -> mark partial or uncertain state
  -> reconcile external side effects when possible
  -> offer explicit restart or human escalation
  -> never silently replay unsafe work

这也是多模型网关的正确边界。通过一个兼容 OpenAI 的端点集中管理模型访问,可以减少集成重复,但应用程序仍然需要提供工作流意图:截止时间、副作用模式、所需工具、schema 版本,以及是否允许跨模型回退。Flatkey 为希望在不同模型提供商之间使用同一个密钥和同一套集成接口的团队提供统一的 API 访问层;但最安全的路由策略仍然始于明确的应用契约。

模型回退策略上线检查清单

策略

  • [ ] 每个路由类别都有回退封套。
  • [ ] 可重试错误在各提供商之间被标准化。
  • [ ] 总重试预算只有一个负责人。
  • [ ] 等价端点与替代模型被区分开来。
  • [ ] 跨模型候选项具有版本化能力契约。
  • [ ] 默认情况下,部分输出会禁用透明回退。
  • [ ] 写入侧工具使用持久化的幂等性记录。

验证

  • [ ] 传输、契约和任务成功分别进行度量。
  • [ ] 结构化输出在回退后进行验证。
  • [ ] 工具参数和工具选择行为按模型进行测试。
  • [ ] 回退评估集应代表真实的路由类别。
  • [ ] 新候选项需通过离线评估和生产金丝雀测试。

运维

  • [ ] 每次尝试都会记录路由原因、目标、延迟和结果。
  • [ ] 仪表盘分别展示主路径、重试、等价故障转移和跨模型恢复。
  • [ ] 告警包含截止时间耗尽和无可用回退率。
  • [ ] 熔断器使用受控的半开探测。
  • [ ] 事故复盘包括用户可见质量和重复副作用风险。

证明回退确实有帮助的指标

不要只针对提供商错误率进行优化。要跟踪用户结果。

指标 回答的问题
重试恢复率 针对同一目标的重试是否值得其带来的延迟?
等价故障转移恢复率 冗余容量是否能安全地恢复服务?
跨模型契约成功率 替代响应是否满足所需接口?
跨模型任务成功率 用户是否仍然完成了预期工作?
额外回退延迟 恢复会增加多少延迟?
回退成本差值 恢复路径的成本是多少?
部分流失败率 系统多久会进入无法恢复的展示状态?
副作用协调率 系统在继续之前需要多久验证外部状态?
重复副作用事件 重放保护是否失效?
无可用回退率 是路由契约过于严格,还是容量不足?

按路由类别划分这些指标。总体恢复率可能会掩盖这样一个事实:回退在抽取任务上表现良好,但在代码生成或工具使用上表现不佳。

常见问题

什么是模型回退策略?

模型回退策略是一种决策政策,用于判断何时 AI 请求应重试同一目标、故障转移到等效容量、切换到已批准的替代模型,或者因为重放存在安全风险而停止。

重试和回退有什么区别?

重试是在同一目标或部署上重复请求。等效故障转移会将请求移到旨在保持相同模型契约的容量上。跨模型回退会更换模型,因此需要进行能力和质量验证。

每个 429 错误都应该触发另一个模型吗?

不应该。首先要对限制类型进行分类,遵循重试指导,检查剩余截止时间,并使用有边界的重试或队列。若存在已批准的替代容量,切换模型可能会有所帮助,但它也可能改变输出质量、工具行为或成本。

流式响应能在回答中途回退吗?

通常更安全的做法是,在 token 已经到达用户之后,不要透明地切换。应停止流,并提供明确的重新开始,除非应用已经实现并测试过恢复协议。

一个路由应该配置多少个回退模型?

使用最小的已批准集合,只要它能提供有意义的恢复即可。每增加一个候选项,就会增加评估、监控和事件响应工作。一个很长但未经测试的列表并不等于韧性。

回退逻辑应该放在哪里?

在网关或编排层中集中处理提供方规范化、路由、尝试预算和可观测性。将特定于工作流的意图——副作用风险、schema 要求、安全策略和质量阈值——尽量靠近应用层。

围绕工作流风险构建回退

最佳的模型回退策略不是“尝试下一个模型”。它是一个有边界的决策系统:

  • 工作流 1 使用重试和等效容量恢复可重放请求。
  • 工作流 2 仅在完成能力和质量检查后切换模型。
  • 工作流 3 当输出或副作用使恢复不安全时,停止自动重放。

这种设计在不掩盖契约失败或重复用户操作的前提下提高了可用性。如果你的团队正在标准化跨模型提供方的访问,请使用 Flatkey 的统一 OpenAI 兼容 API 层作为集成入口,然后将这些特定于工作流的封装附加到每条生产路由上。

来源与延伸阅读