AI 服务上线后如何不失控:模型降级、熔断与人工兜底设计
本文定位AI 服务高可用 / 降级设计 / 生产运维示例环境Java 21、Spring Boot 3.3、Resilience4j、Redis、消息队列。供应商错误码和限流策略需要按实际接口适配。摘要AI 服务比普通接口多一层供应商依赖和概率性输出。模型可能超时、限流、返回格式变化、质量波动或临时不可用知识库可能空结果工具可能部分成功用户可能在流式输出中途断开。没有降级设计的 AI 应用往往要么让用户长时间等待要么在故障时继续给出没有依据的回答。本文把降级拆成模型级、能力级、数据级和人工级四个层次设计超时、重试、熔断、备用模型、只读证据、异步任务和人工接管并强调哪些场景必须“失败而不是猜测”。一、降级不是简单换一个模型成功超时/限流不兼容/失败无法回答校验失败请求风险与意图判断主模型输出校验备用模型关键词或缓存能力人工/异步任务不同场景的安全降级不一样普通 FAQ 可以切换更便宜的模型故障诊断可以展示已检索证据并转人工扣款或生产发布不能因为主模型失败就让备用模型自动执行。二、错误分类错误是否重试降级建议参数错误否提示用户补充信息认证失败否告警并修复配置429 限流有条件退避或切换备用供应商网络超时有条件限次重试保留请求 ID供应商 5xx有条件熔断后走备用能力输出 Schema 失败最多一次重试或人工校验权限拒绝否说明无权不得换工具绕过知识库为空否拒答或转人工分类越准确降级越可控。不能把所有异常都包装成“模型繁忙”也不能把权限错误当作模型错误重试。三、阶段超时一个总超时无法说明瓶颈在哪。建议分别配置认证、Embedding、关键词检索、向量检索、Rerank、模型首 Token、模型完成和工具调用超时。publicrecordTimeoutPolicy(Durationembedding,Durationretrieval,Durationrerank,DurationfirstToken,Durationcompletion,Durationtool){}当总预算只剩 2 秒时不要再启动一个预计 10 秒的 Rerank 请求。可以根据剩余预算跳过非关键阶段返回已有证据或进入异步任务。四、熔断与恢复熔断器用于防止下游持续失败拖垮线程池和连接池。状态通常包括关闭、打开和半开关闭时正常调用连续失败后打开等待一段时间后半开试探恢复。CircuitBreaker(nameprimaryLlm,fallbackMethodfallback)publicLlmResultcallPrimary(LlmRequestrequest){returnprimaryClient.call(request);}publicLlmResultfallback(LlmRequestrequest,Throwableerror){metrics.recordFallback(classify(error));returnbackupRouter.route(request);}熔断参数不能照搬普通 HTTP 服务。AI 请求耗时长、成本高失败比例需要结合延迟、Token 和业务风险判断。恢复探测也要限制流量避免供应商刚恢复就被大量请求再次压垮。五、备用模型的兼容性备用模型不一定支持相同的上下文长度、工具格式、结构化输出和多模态能力。切换前要维护能力矩阵能力主模型备用模型是否兼容JSON Schema支持支持是Function Calling支持不支持否最大上下文128K32K需裁剪多模态支持不支持需转人工中文回答好可接受需评测如果备用模型不支持工具调用应该降级为只读检索和人工确认而不是伪造工具成功结果。切换后要记录真实模型便于质量和成本分析。六、能力级降级AI 应用可以把能力拆成多个层次完整 Agent检索、工具、推理和自动执行。受限 Agent只允许只读工具。RAG 问答只检索证据不产生业务动作。关键词检索返回匹配的文档和位置。普通业务流程进入人工或传统页面。publicCapabilitychoose(HealthSnapshothealth,RiskLevelrisk){if(risk.atLeast(RiskLevel.HIGH)!health.primaryModelHealthy()){returnCapability.READ_ONLY_EVIDENCE;}if(!health.vectorStoreHealthy()){returnCapability.KEYWORD_SEARCH;}returnCapability.FULL_AGENT;}降级后的提示要明确当前能力例如“模型暂时不可用以下仅展示匹配资料不能据此自动执行操作”。诚实地降低能力比生成一段看似完整但无法验证的答案更安全。七、异步任务和人工接管对于长文档分析、批量总结和复杂故障诊断可以返回任务 ID让用户稍后查看。任务状态持久化后服务重启、模型短暂故障和回调重复都能处理。人工接管页面要展示问题摘要、已检索证据、当前模型和版本、失败阶段、候选回答、工具计划、风险等级和可执行动作。人工不是简单替代模型而是需要足够上下文快速做出判断。八、流式输出中断流式输出已经发送给用户的内容无法收回。高风险答案不适合边生成边执行。可以把工具动作放在最终确认之后把文本回答先标记为“草稿”完成引用和安全校验后再转为正式结果。客户端断开时要取消可取消的模型请求但对已经提交的业务动作要继续追踪并更新任务状态。否则用户以为失败后台却可能成功最终形成重复提交。九、降级测试使用故障注入模拟主模型超时、主模型返回 429、备用模型不支持工具、Rerank 不可用、向量库连接池耗尽、工具部分成功、客户端中断和回调重复。每种故障都应验证用户提示、状态、日志、指标和成本。TestvoidvectorStoreDownMustNotGenerateUnsupportedAnswer(){when(vectorStore.search(any())).thenThrow(newTimeoutException());AiResultresultservice.ask(question(),user());assertThat(result.mode()).isEqualTo(KEYWORD_OR_HUMAN);verify(llm,never()).generate(any());}测试重点不是“最终页面有没有内容”而是故障时系统有没有越过安全边界。十、指标与告警建议监控主模型成功率、备用模型比例、熔断状态、阶段 P95、Token 成本、降级模式分布、人工接管率、拒答率和工具动作失败率。若备用模型比例突然上升即使接口成功率没变也说明主链路可能正在退化。告警应包含最近发布的模型、Prompt、知识库和配置版本帮助快速判断是否由变更引起。所有自动切换都要能在一个开关下暂停或恢复。十一、恢复流程不能只写在文档里降级方案必须配合演练。可以在测试或预发布环境注入供应商超时、429、错误 JSON、空检索、工具部分成功和消息队列重复投递然后观察系统是否按预期进入状态。演练后记录触发条件、用户体验、恢复时间、遗漏日志和需要人工执行的步骤。演练场景期望状态恢复动作主模型持续超时熔断打开切备用模型或只读证据备用模型不支持工具不执行写操作转人工确认向量库不可用不生成无依据答案关键词检索或异步工具已成功但响应丢失任务处理中查询幂等状态不重复执行客户端断开文本流停止继续追踪已提交动作恢复时要注意“依赖恢复”和“质量恢复”不是同一件事。供应商接口恢复后模型可能仍然返回格式错误或质量异常因此半开探测除了检查 HTTP 成功还应该检查 Schema、引用和安全样本。十二、熔断参数的选择失败率、慢调用比例、最小请求数、打开时长和半开探测数都应该基于真实流量调整。请求量太小时失败率容易被单个异常放大请求量太大时等到熔断才动作可能已经耗尽资源。可以按模型、租户和任务类型分别配置但不要把标签设计成无限增长。对高风险工具熔断器之外还要有独立的动作开关。例如模型质量异常时即使普通问答继续使用备用模型生产发布工具也可以直接冻结等待人工复核。十三、发布前的故障演练记录一次完整演练应该有明确的开始条件、观察指标和结束条件。例如把主模型延迟人为提高到 60 秒确认 30 秒超时后请求进入备用链路再让备用模型返回非法结构确认系统不会把错误 JSON 当成成功答案最后恢复依赖观察半开探测是否逐步放量。演练结果要形成记录包含发现的问题、修复提交和复测证据。如果某个降级分支只能由熟悉代码的人临时操作说明它还没有真正产品化。用户提示、任务状态、告警、日志和恢复开关都应该在演练中验证。十四、总结降级的目标不是让系统在任何情况下都“给出答案”而是让系统在能力下降时仍然诚实、可控、可追踪。模型不可用时可以换模型检索不可用时可以展示已有资料复杂任务可以转异步高风险动作可以转人工但无论怎么降级都不能让模型凭空补全事实或绕过权限。成熟的 AI 服务一定要把失败路径设计出来并用故障注入验证。只测试正常调用成功无法证明系统能够上线。读者讨论建议先给你的 AI 功能定义“完整能力、只读能力和人工能力”三档降级路径再去配置熔断和备用模型。