AI API 网关架构设计:如何实现多模型统一路由与自动故障转移

张开发
2026/5/23 4:31:46 15 分钟阅读
AI API 网关架构设计:如何实现多模型统一路由与自动故障转移
一个 API Key调用 Claude、GPT、Gemini、DeepSeek 所有主流大模型。听起来简单但背后的工程细节远不止换个 endpoint 那么简单。为什么需要 AI API 网关如果你的业务只用一个模型提供商直接调用官方 API 没什么问题。但现实中大多数团队会遇到以下场景多模型并存不同功能模块用不同模型有的用 Claude 做代码审查有的用 Gemini 做文档摘要有的用 DeepSeek 跑批量任务单点故障风险OpenAI 在 2024 年多次出现 API 中断Anthropic 也会有限流。没有 fallback 就意味着你的业务直接挂掉计费混乱每个提供商有独立账单token 单价不同月底对账是噩梦合规与审计企业客户要求记录所有 AI 调用方便审计、排查问题AI API 网关就是解决这些问题的基础设施层。它站在你的应用和各个模型提供商之间统一入口、统一协议、统一计费、统一监控。核心架构四层设计我们在设计 TheRouter 时把整个请求链路分成四层每层职责明确客户端请求 │ ▼ ┌─────────────────────────────────┐ │ 1. 请求解析层Ingress Layer │ ← 协议适配、鉴权、参数校验 └─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ 2. 模型路由层Router Layer │ ← 模型映射、路由选择、健康过滤 └─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ 3. Provider 适配层 │ ← 协议转换、错误归一化、重试 └─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ 4. 计费层Billing Layer │ ← Token 计量、费用记录、余额扣减 └─────────────────────────────────┘ │ ▼ 上游 ProviderOpenAI / Anthropic / Bedrock / Vertex AI / ...第一层请求解析层所有入站请求首先到达这里。主要职责协议适配支持 OpenAI Chat Completions 格式messages数组、OpenAI Responses APIinput字段、Anthropic Messages API 等多种请求格式统一转换为内部标准格式鉴权验证 API Key 合法性加载租户配置路由策略、允许使用的模型、消费上限参数校验检查model字段是否存在、请求体格式是否合法在路由前快速返回错误这一层的关键设计原则是快速失败——所有能在路由前拒绝的请求不要带进下游。第二层模型路由层这是整个网关最核心的部分。两层模型抽象我们设计了两层模型命名体系Standard Model标准模型对外暴露的模型 ID格式为品牌/模型名比如anthropic/claude-sonnet-4.6、openai/gpt-5、google/gemini-2.5-pro。这是客户看到的也是/v1/models接口返回的。Upstream Model上游模型实际调用时使用的提供商内部模型 ID比如通过 Bedrock 调用 Claude 时上游模型是us.anthropic.claude-sonnet-4-5-20251001-v1:0。两层抽象的好处是客户代码里只出现标准模型 ID内部路由切换对外完全透明。我们把一个 Anthropic 直连路由切换成 Bedrock 路由客户完全无感知。配置文件结构src/config/ ├── standard-models.yaml ← 标准模型定义 售价 └── provider-models/ ← 每个 provider 一个文件 ├── anthropic-api.yaml ← Anthropic 直连 ├── bedrock-us-east-2.yaml ← AWS Bedrock us-east-2 ├── openai-api.yaml ← OpenAI 直连 └── vertex-ai-us-central1.yaml← Google Vertex AI每个 provider 文件里通过standard_model字段把上游模型挂载到标准模型上# bedrock-us-east-2.yaml (示意)upstream_models:us.anthropic.claude-sonnet-4-5-20251001-v1:0:standard_model:anthropic/claude-sonnet-4.6priority:20# 优先级越小越优先cost:input:3.00# $/MTok成本价output:15.00路由选择算法路由层根据以下因素决定用哪个 provider优先级Priority每条路由有一个priority值数字越小越优先。同一个标准模型可以挂多条路由形成有序的 fallback 链能力过滤Capability Filter如果请求用了tools函数调用或vision图片输入过滤掉不支持这些能力的 provider健康状态Health Filter过滤掉当前不健康的 provider下文详述客户偏好Customer Preference租户可以通过请求头或 API 参数指定only只用某些 provider、ignore排除某些 provider、order自定义排序支持两种路由算法可以按租户或按请求切换priority按优先级排序优先选最高优先级的健康路由lowest_cost在健康路由中选当前成本最低的第三层Provider 适配层每个 provider 是独立的微服务负责协议转换把网关内部格式翻译成 provider 原生 API 格式Anthropic 的 Messages API、OpenAI 的 Chat Completions、Bedrock 的 InvokeModel 等错误归一化把各家的错误码统一映射到网关内部错误类型error_5xx、error_4xx、timeout、rate_limit让上层路由决策逻辑不需要感知具体 provider内部重试provider 层做短暂的内部重试只针对 transient 5xx与路由层的跨 provider failover 分离关键设计决策每个上游 API 必须有独立的 provider 服务。即使两个 provider 的 API 格式兼容比如许多第三方都兼容 OpenAI 格式也要给它们各自的服务。原因provider 特有的错误处理、reasoning token 格式、Rate Limit 行为各不相同共用镜像会埋下难以排查的 bug也让独立升级变得困难。第四层计费层每次请求完成后计费层负责Token 计量从响应的usage字段读取实际消耗的 input/output token 数成本计算根据实际使用的 provider 的成本价计算原始成本按售价计算向客户收取的费用记账写入计费流水扣减余额计费层和路由层共享同一份定价配置——标准模型有售价provider 路由有成本价——两层价格独立维护网关统一管理 margin。故障转移机制这是 AI 网关区别于普通 API 网关的核心能力之一。Provider 健康检查网关维护一个 provider 健康状态缓存来源有两个主动探测定期向各 provider 发送探测请求根据响应时间和错误率更新状态healthy/degraded/unhealthy被动感知每次真实请求如果返回 5xx 或超时记录失败事件动态调整该 provider 的健康分数自动 Fallback 流程请求 → 路由层选出有序候选列表 [A, B, C] │ ▼ 尝试 A │ A 返回 503 ──→ 记录失败标记 A 健康分下降 │ ▼ 尝试 B │ B 成功 ──→ 返回响应记录 fallback_depth1路由层在构建候选列表时已经过滤掉unhealthy的 provider但degraded的仍然会保留排在后面。这样在所有健康 provider 都不可用时降级 provider 还能作为最后兜底。我们在 Prometheus 指标里专门追踪 fallback 深度gateway_fallback_depth和 fallback 总次数gateway_fallback_total用于告警和 SLA 评估。流式响应的特殊处理Fallback 在流式SSE请求下有一个关键约束一旦响应头已经发送HTTP 200 Content-Type: text/event-stream就不能再切换 provider 了。所以流式请求的 fallback 只能在第一个 token 到达之前触发。具体做法建立 SSE 连接后先不立即向客户端发送响应头等待 provider 开始返回数据流拿到第一个 chunk第一个 chunk 确认成功后再向客户端发送响应头 开始转发数据如果在第一个 chunk 到来前 provider 报错可以切换到下一个 provider 重试这个设计增加了首 token 延迟TTFT但保证了流式请求的可靠性。另一个挑战是流式过程中断数据已经开始传输中途 provider 连接断掉了怎么办这种情况我们选择向客户端发送一个特殊的错误 chunk然后关闭连接——此时重连到新 provider 并续传是不现实的因为我们无法知道客户端已经收到多少内容。实践中踩过的坑1. SSE 连接泄漏早期版本里如果客户端提前断开连接比如用户刷新了页面网关侧不会立即感知上游的 SSE 流还在跑消耗资源还在计费。现在我们监听客户端连接的close事件客户端断开时立即 abort 上游请求。2. 跨 Provider 的 Token 计数差异不同 provider 对同一段文本的 token 计数略有差异因为分词器不同。如果用预估 token 数做余额预扣误差会导致少扣或超扣。我们的做法是预扣时用一个保守估算留 20% buffer请求完成后根据实际usage做精确结算。3. Bedrock 的特殊性AWS Bedrock 不是一个简单的 HTTP API它需要 AWS SigV4 签名。我们把 Bedrock 做成一个独立的 provider 服务所有签名逻辑都封装在里面网关主体不感知 AWS SDK。4. 响应里的模型名字必须回显标准模型 IDClaude 官方 API 返回的响应里model字段会是类似claude-sonnet-4-5-20251001这样的内部版本号。我们必须把它替换成用户请求时用的标准模型 ID比如anthropic/claude-sonnet-4.6否则客户代码里做模型判断的逻辑会出错。架构总结一个生产可用的 AI API 网关需要解决的问题远比转发请求复杂得多。上面提到的两层模型抽象、能力感知路由、流式 fallback 策略、精确 token 计费每一块都有相当多的工程细节。如果你正在构建自己的 AI 基础设施建议不要直接暴露 provider 名字给业务代码——用抽象层隔离方便未来迁移从第一天就做健康检查和 fallback——AI provider 的稳定性远不如传统 SaaS流式请求单独处理——SSE 的错误处理逻辑和普通请求完全不同不能复用双层定价——成本价和售价分开管理方便调整 margin 和做成本分析如果不想自己造轮子TheRouter 提供了一个已经解决以上所有问题的 AI API 网关一个 API Key 接入所有主流大模型支持自动故障转移和统一计费。

更多文章