多模型路由怎么按失败类型切换:超时、限流和内容拒答的分流规则
来源:17golang原创
时间:2026-08-25 06:04:55 398浏览 收藏
线上同时接入高延迟低吞吐的强模型和低延迟高吞吐的快模型后,最容易踩坑的部分从来不是多候选模型列表的配置,而是请求异常之后的跳转逻辑。一次请求超时、触发上游限流、服务临时不可用,和模型明确返回内容拒答,对应的处理逻辑差异极大。如果不加区分全部写死成“请求失败就自动切下一个模型”,不仅会把本可以快速重试的请求拖成严重长尾,还可能把不该绕过的安全拒答逻辑变成无休止的跨模型轮询,平白浪费大量算力。
- 先把所有失败场景归类为可重试、可降级、需人工处理、不可绕过四个大类,再判断要不要切换后续模型。
- 每一次发往模型的请求都要附带完整的路由尝试记录、剩余重试预算和最终状态标记,避免跨模型重复扣费。
- 超时和限流场景要做有界重试,内容拒答场景必须保留原始返回原因,不能通过换上游模型的方式绕过内容安全策略。
- 上线验收不能只看接口成功率指标,还要核对尾延迟占比、重复请求率、降级请求比例和不同模型拒答规则的一致性。
先把“失败”拆成四种路由信号
假设业务有两个候选:fast-chat 用于低延迟问答,deep-chat 用于需要更长上下文的任务。请求进入路由器后,不要只保存一个布尔值 success,而要记录能决定下一步的状态。
| 异常信号 | 典型表现 | 默认处理动作 |
|---|---|---|
| 超时 | 连接建立阶段或者响应等待时长超出预设预算 | 短退避后执行有限次数重试,重试失败再触发降级逻辑 |
| 限流 | 上游服务返回额度不足或者并发数已达上限 | 优先读取响应携带的等待提示,无提示时切到候选队列或者排队等待 |
| 服务异常 | 网关错误、连接直接中断、返回响应格式损坏 | 直接更换下一个候选模型,同时记录当前服务的故障时间窗口 |
| 内容拒答 | 模型明确返回安全规则或者业务策略拒绝生成 | 停止自动轮询后续模型,直接向用户说明当前服务的可提供范围 |
这张表的关键不在名称,而在“默认动作”。路由器可以把上游状态映射成内部枚举,例如 RETRYABLE_TIMEOUT、RATE_LIMITED、UPSTREAM_UNHEALTHY 和 POLICY_REFUSAL。业务层只消费内部状态,不直接根据某个供应商的文字错误做判断。

为一次请求建立可追踪的路由状态
路由状态结构体至少要覆盖请求唯一标识、候选模型优先级顺序、已经尝试过的模型列表、单次请求等待预算和全链路总耗时预算。下面给出的是示意结构,字段名可以根据自己服务的开发语言灵活调整:
{
"request_id": "req-7f21",
"candidates": ["fast-chat", "deep-chat"],
"attempts": [],
"retry_budget": 2,
"deadline_ms": 8000,
"final_state": "PENDING"
}
每次尝试结束后追加一条记录,而不是覆盖上一条。记录里保留 model、started_at、elapsed_ms、state 和上游请求是否已经接受。这样可以区分“请求根本没发出去”“上游已接收但响应丢失”和“模型正常返回拒答”。
单次超时和总超时必须分开
单次超时只限制当前候选,deadline_ms 则限制整个用户请求。比如总预算是 8 秒,第一次候选已经用掉 6 秒,第二次就不能再拿一个完整的 8 秒窗口。路由器应把剩余时间传给下一次尝试,剩余时间不足时直接返回可解释的降级状态。
同一请求不要重复消耗结果
上游服务在响应完整返回前主动断开连接时,客户端侧根本不知道模型后台是否已经完成生成动作。这时候盲目切换其他模型重试,很可能生成两份结果,甚至让后续的扣费和审计记录完全对不上。对支持幂等键的上游服务,重试时复用同一个幂等键;对不支持幂等机制的上游,至少要在本地标记“结果未知”状态,交给上层业务逻辑判断是否接受这次可能产生重复结果的尝试。
不同失败信号应该走不同的处理链
实现上可以把分类、动作和终态分开。分类只回答“发生了什么”,动作回答“下一步允许做什么”,终态回答“这次请求最终如何结束”。这三个概念混在一个 if error != nil 里,后期很难加监控和回归测试。
超时 -> 检查剩余预算 -> 短退避 -> 同模型或候选模型 限流 -> 读取等待提示 -> 预算允许则排队/换候选 -> 否则降级 服务异常 -> 熔断计数 -> 选择健康候选 -> 失败则返回暂时不可用 内容拒答 -> 保留拒答原因 -> 停止绕路 -> 返回安全范围说明
超时是否换模型取决于请求类型。短问答可以优先换到 fast-chat,长上下文任务如果换到不支持同等上下文的候选,应返回能力不匹配,而不是假装成功。限流则要关注等待提示,固定每次等待相同时间会在高峰期制造新的拥塞。
内容拒答是最容易被误处理的一类。它可能意味着输入或请求方式超出了允许范围,换一个模型并不会改变业务责任。路由层可以把拒答原因映射成统一的 POLICY_REFUSAL,但不要把它当成上游故障,也不要自动继续轮询所有候选。
把重试和降级边界写成可验收规则
重试不等于不加限制地“多试几次”。建议先给每一类失败场景单独定义重试预算,再把最终状态的流转逻辑固定下来:
- 超时:最多允许一次短退避重试,且重试后的总等待时长不能超过预设的全链路截止时间。
- 限流:优先遵守上游返回的等待提示参数;没有携带提示参数时使用带随机扰动的短退避策略。
- 服务异常:同一个候选模型连续失败次数达到预设阈值后临时熔断,避免后续请求继续撞向故障实例。
- 内容拒答:不做重试、不切换其他模型绕过;直接返回安全的替代说明,或者引导用户改写当前的请求内容。
降级也要有能力声明。比如 deep-chat 失败后切到 fast-chat,结果中应带上 degraded=true 和能力差异,而不是让调用方以为拿到了完全等价的回答。对于结构化输出,还应重新校验必填字段;模型切换后格式约束可能并不一致。

用四组实验验证路由不会失控
测试环节不要只简单模拟一个 500 状态码返回。把当前请求参数完全固定,给每一个候选模型注入可复现的指定响应,然后核对路由日志和最终返回结果。
- 让第一个候选的响应等待时长超过单次请求预算,确认路由只会触发允许次数内的重试,转发到第二个候选时拿到的是扣除已耗时时长后的剩余时间。
- 让第一个候选直接返回限流提示,确认路由不会立刻高频重发请求,同时完整记录下本次等待的触发原因。
- 让第一个候选返回格式完全损坏的异常响应,确认切换到下一个候选后依然会完整校验返回结果的结构化字段。
- 让候选直接返回内容拒答,确认路由不会发起第二次模型请求,且最终返回状态里完整保留拒答对应的分类标记。
监控上至少看四个指标:按失败类别统计的请求数、同一 request_id 的尝试次数、降级请求占比和端到端尾延迟。成功率上升但尝试次数和尾延迟同时上升,通常不是路由变好了,而是重试预算过宽。
常见问题
超时后一定要换到更强的模型吗?
不一定。需要先判断剩余可用耗时、任务上下文长度和后续候选的健康状态。短文本问答场景更适合切到低延迟候选模型,长上下文任务则可能需要直接返回服务暂时不可用,避免降级到小模型后丢失用户上传的关键上下文信息。
限流和服务异常为什么要分开?
限流场景通常意味着短时等待或者更换容量充足的候选即可解决,服务异常场景则可能需要触发熔断和运维告警。把两类场景混为同一异常处理,会让系统在上游服务完全故障时依旧持续无效重试,也会错过限流响应里携带的官方等待提示参数。
内容拒答能不能交给另一个模型判断?
可以把拒答结果转发给业务层做友好解释或者生成改写建议,但不能把其他模型当成绕过内容策略的通道。路由层要直接停止自动轮询逻辑,同时保留原始拒答的类别标记,后续用于安全审计和产品策略优化。
把路由器当成有边界的状态机
多模型路由真正要解决的核心问题是异常场景下的可解释性:清晰知道为什么要切换候选模型、还剩多少可用请求预算、当前结果是否属于降级返回、哪一类失败场景绝对不能继续尝试。把失败分类规则、尝试记录、全链路总截止时间和最终状态流转逻辑固化到协议里,再用超时、限流、格式损坏、内容拒答四组场景做完整验收,路由组件才不会从预期的容错机制变成隐形的重复调用生成器。
-
478 收藏
-
484 收藏
-
151 收藏
-
396 收藏
-
167 收藏
-
269 收藏
-
460 收藏
-
科技周边 · 人工智能 | 3小时前 | 人工智能 · gemini · function calling · 结构化输出 · 接口测试 · 结构化输出 JSON Schema Gemini 3 Function Calling 工具调用验收346 收藏
-
289 收藏
-
229 收藏
-
104 收藏
-
394 收藏
-
113 收藏
-
科技周边 · 人工智能 | 8小时前 | 人工智能 · openai · 兼容性 · Chat Completions · 推理模型 · token预算 AI推理模型 max_tokens max_completion_tokens 参数迁移464 收藏
-
148 收藏
-
259 收藏
-
103 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习