把失败当默认前提:LLM 服务的重试、降级与兜底设计
按错误语义决定重试,用总截止时间控制等待;分清模型重复调用与业务幂等,处理流式中断、缓存串用和降级质量,并用 SLO 验证兜底。
更新与核对 · 2026-10-11
LLM 失败不只有接口报错:还可能答错,或输出半段后断流。可靠性设计需要分别回答:能否安全重试,用户还能等多久,替代路径能否保留正确性与权限边界。 以下以交互式 Agent 为例,参数需按实测调整。
按失败语义分类
| 失败 | 处理方向 | 常见误区 |
|---|---|---|
| 临时限流、可恢复的 5xx | 根据响应头和截止时间退避 | 所有实例立即重试 |
| 余额不足、鉴权失败、参数错误 | 修配置或请求,停止无效调用 | 所有 429/4xx 都当瞬时故障 |
| 网络超时、断开 | 结果可能未知,查任务状态 | 假定上游没执行 |
| 内容安全拒绝 | 解释边界,提供允许的帮助 | 改措辞绕过同一限制 |
| 答案无据、参数语义错误 | 补证据、质量检查或拒答 | HTTP 200 就算成功 |
错误体比状态码更能说明问题。额度耗尽不会因等一秒恢复,具体分类以 Claude 错误文档[1]和 OpenAI 限流文档[2]为准。
限流与超时:共享一份预算
网关按上游配额限制请求和 token,按用户、任务分配公平份额。多实例共享额度要统一协调;并发与队列也设上限,排队过久应尽早告知。
每个任务设一个总截止时间,调用、退避、重试和降级共享剩余时间。SDK、网关与业务统一重试策略,否则每层三次会叠成九次甚至更多。
Full jitter 可写成:
delay = random(0, min(cap, base × 2^attempt))
它与“固定退避上下浮动 50%”不同。Retry-After 超过剩余预算时进入替代路径,不能截短等待后提前冲击上游。分别记录连接超时、首内容超时、流空闲超时和总超时。
幂等:业务效果一次,不等于模型只收费一次
业务任务 ID 防重复提交,attempt ID 记录每次模型尝试。自定义幂等头不代表供应商支持去重;重试生成仍可能执行和计费,必须按端点确认。
有副作用的工具需要自己实现幂等:
- 键绑定用户、操作类型和内容摘要。
- 原子创建任务;同键同内容返回已有状态,同键异内容拒绝。
- 写入与完成状态在事务内提交,或用 outbox 衔接外部系统。
- 外部操作结果未知时查询或对账,不盲目重做。
先查“键不存在”再写数据会在并发下重复执行。去重记录保留期要覆盖业务重放窗口;离线设备很久后重发,不能照抄 24 小时。Stripe 幂等文档[3]是具体实现范例,其他 API 不自动继承这些保证。
流式失败:已经展示的内容怎么办
首字前切换模型可以重新生成;首字后要处理已展示文本。备用输出接在半句话后面,可能重复、矛盾,甚至重复动作。
客户端事件携带 task_id、attempt_id 和序号,终止时明确 completed、interrupted 或 failed。断流后保留草稿并提示未完成;重新生成时显式替换整段,或者使用可验证的续传协议。执行工具前确认完整参数,不能执行半截 JSON。
图 1 · 降级有触发条件和质量门槛,安全拒绝不进入绕过式重试。
降级路径也要先评测
可选备用模型、精确答案缓存、原文检索和固定提示,顺序按业务决定。合法精确缓存可先查;权益或高风险答案可能必须停止自动处理。
备用模型要验证工具、结构化输出、中文质量、上下文容量和安全规则。小模型不保证更快,也不保证有独立限流池;共享故障域时切换可能无效。
语义相似不等于答案可复用。 配置问题改一个数字,向量仍很接近。优先对象 ID、规范化请求和参数的精确键;允许近似的任务使用语义缓存时,评测误命中,并限定租户、权限、内容、知识库版本与有效期。相似度阈值不能跨模型照搬。
熔断器按故障域维护关闭、打开、半开三态:失败摘除、冷却后少量探测、恢复才放量。正常安全拒绝和用户参数错误不应熔断整个上游。
一个请求场景
假设总预算 8 秒,主模型在第 2 秒返回临时限流,要求等 1 秒。等待后剩 5 秒:备用路径历史 p95 为 2 秒且质量达标,可尝试;若时间不足则展示检索原文和稍后重试入口。
每次转换记录原因、耗时、费用和结果。这个算例说明“用剩余预算决策”,不是统一推荐 8 秒或固定重试次数。
SLO 与故障演练
SLI 是测量,SLO 是目标,SLA 是对外承诺。分开看传输成功率、任务完成率、抽样正确率、首字延迟和降级率。引用存在不能代替正确率。
任务完成率目标 99.5%,100 万个纳入统计的任务允许 5,000 次未完成;分母和用户取消规则事先固定。错误预算持续消耗时优先修可靠性。
演练覆盖主模型故障、余额耗尽、首字后断流、缓存故障、工具结果未知与双上游失败。验收包括无重复业务效果、无跨用户缓存、费用有记录、用户知道任务是否完成。
落地检查
- 错误体与语义一起分类,永久错误和拒绝不盲目重试。
- 重试与降级共用截止时间,检查 SDK 自动重试。
- 业务键与 attempt 分离,用事务、唯一约束或对账保护副作用。
- 断流显式标记,备用文本不直接续接原输出。
- 缓存与备用模型通过权限、质量回归后再启用。
- 用 评测闭环验证替代路径。
参考资料
正文中的编号可跳转至对应来源。工程报告、官方文档与研究论文分别标注;支撑范围说明该资料能证明什么,以及不能推导什么。
- [1]官方文档Claude — API errors
支撑范围: Claude API 错误类别与请求追踪信息;重试仍需截止时间和副作用判断。
- [2]官方文档OpenAI — Rate limits
支撑范围: OpenAI 限流及请求/用量约束;限流、配额与业务重试需要区分。
- [3]官方文档Stripe — Idempotent requests
支撑范围: Stripe 幂等键的具体契约;不能假设所有外部服务具有相同行为。
- [4]技术文章AWS — Timeouts, retries and backoff with jitter
支撑范围: 超时、重试、退避与抖动的分布式系统经验;参数要按负载和依赖验证。
- [5]官方文档Google SRE — Implementing SLOs
支撑范围: SLI、SLO 与错误预算的制定方法;本文目标数值仅为示例。