一把 key 上的降级链:主后端变差时,谁来接这一单
本文介绍如何在单把 API key 上设计多后端降级链,涵盖触发条件(报错、拒答、延迟飙升、形状不合)的判定,客户端如何提示已切换而不改动提示词契约,并给出实现示例与最佳实践。
在聚合站中,一把 key 可以调用多个模型。但不同后端稳定性不同,主后端可能临时故障。设计一个有顺序的降级链,能在不破坏提示词契约的前提下,自动切换到备用后端。
为什么需要降级链
单点依赖风险高。如果只用一个后端,遇到限流、服务故障或响应异常时,请求会直接失败。降级链让请求按优先级依次尝试多个后端,提高整体成功率。
定义降级顺序
降级链是一个有序列表。通常将质量最高或成本最优的后端放在前面,备用后端依次排列。例如:Claude → GPT → DeepSeek → Qwen → GLM → Kimi。顺序可根据业务需求调整,但应保持稳定,避免频繁变动。
触发降级的条件
降级不是随意切换,需要明确触发条件:
- 报错:HTTP 错误码(如 5xx、429)或连接超时。
- 拒答:模型明确拒绝回答,且该拒答不符合预期(例如因内容策略误判)。
- 延迟飙升:响应时间超过预设阈值,且持续一段时间。
- 形状不合:返回内容不符合预期格式(如 JSON 解析失败、缺少关键字段)。
每个条件应有单独的开关和阈值,便于调整。
客户端如何提示已切换
切换后端时,客户端应感知并提示,但不要改动提示词契约(即发送给模型的 messages 结构保持不变)。常见做法:
- 在响应头中添加自定义字段(如
X-Backend-Used: gpt-4),客户端可读取并记录。 - 在响应体中增加元数据字段(如
_meta.backend),但需确保不影响主内容解析。 - 客户端收到切换提示后,可决定是否重试或通知用户。
注意:切换不应修改请求中的提示词,以免影响模型行为。
实现示例(伪代码)
backends = ["claude", "gpt", "deepseek", "qwen", "glm", "kimi"]
for backend in backends:
try:
response = call_api(backend, messages)
if is_valid(response) and not is_refusal(response) and latency_ok(response):
return response_with_meta(response, backend)
except (APIError, TimeoutError):
continue
raise AllBackendsFailed()
最佳实践
- 为每个后端设置独立的超时和重试策略。
- 记录降级事件,便于监控和优化顺序。
- 定期评估后端质量,调整顺序。
- 确保降级链中的后端都支持相同的提示词格式(如 chat completions)。
通过合理的降级链设计,可以在单把 key 上实现高可用,同时保持接口契约稳定。