
1. 多模型接入的乱局为什么统一管理成了刚需我最早接触多模型接入是在两年前当时团队同时用着三家厂商的对话模型、两家的向量模型还有一套自部署的开源模型。每个项目组各自申请密钥、各自记账、各自写调用代码结果就是月底对账时财务拿着五份账单来问“这个月怎么涨了这么多”没人说得清哪笔钱花在了哪个业务上。更麻烦的是某次一家厂商接口临时抖动三个业务线同时报障排查了半天才发现是同一个上游问题但因为没有统一入口每个组都在重复定位。这就是大模型 API 统一管理要解决的核心问题。说白了它要做的事情是把散落在各个业务代码里的模型调用收敛到一个中间层由这个中间层统一负责鉴权、路由、计费、限流、日志和故障切换。这个中间层业内通常叫AI 网关。它适合谁来参考三类人最需要一是中小团队的技术负责人人手有限但接的模型不少二是平台工程或基础架构的同学被业务方追着要“给我一个能用的 key”三是做 AI 应用但不想被单一厂商绑死的开发者。不管你用的是对话模型、绘图模型还是多模态模型只要调用量上来了、模型数量超过两个统一管理这件事就绕不过去。我下面讲的东西都是基于实际落地过的方案总结的不是纸上谈兵。涉及具体参数和配置的地方我会把为什么这么选讲清楚你可以直接抄也可以按自己的情况改。2. 整体架构怎么设计从“各调各的”到“一个入口”2.1 先想清楚要收敛什么动手之前先别急着选型先把要收敛的东西列清楚。我一般会从五个维度盘凭证现在有多少个厂商密钥分别被哪些服务引用有没有硬编码在代码里的模型实际在用的模型有哪些哪些是主力、哪些是备用各自的能力边界是什么流量每个业务线大概的调用量级峰值和谷值差多少成本各厂商的计费方式按 token、按次、按订阅有没有预算上限合规哪些数据不能出内网哪些模型必须走私有化部署这五个维度盘完你基本就知道网关要具备哪些能力了。我见过不少团队一上来就搭网关结果发现最该管的私有化模型没接进去等于白做。2.2 网关的核心分层一个能打的大模型网关我习惯把它拆成四层从下往上说第一层是适配层。不同厂商的接口协议、参数命名、返回结构都不一样。有的用messages数组有的用prompt字符串有的流式返回用 SSE有的用 chunked。适配层的职责就是把这些差异抹平对上暴露一套统一的接口。这一层最脏最累但也是最值得投入的因为一旦适配好上层业务就再也不用关心底层是哪家。第二层是路由层。它决定一次请求该发给哪个模型。路由策略可以很简单比如按模型名直接映射也可以很复杂比如按成本优先、按延迟优先、按可用性做故障转移。我建议初期先做最简单的映射跑通了再逐步加策略别一上来就搞智能路由容易把自己绕进去。第三层是治理层。鉴权、限流、配额、审计日志都在这一层。这是统一管理价值最集中的地方。业务方拿到的是一把网关颁发的虚拟 key而不是厂商的真实 key这样密钥轮换、权限回收、用量统计全都可控。第四层是观测层。调用量、成功率、延迟分布、token 消耗、成本归集这些指标要能按业务线、按模型、按时间段切出来。没有这一层前面三层做得再好也是黑盒。2.3 为什么是网关而不是 SDK有人会问我封装一个统一的 SDK 不就行了为什么非要搞个网关服务这个问题我认真对比过结论是两者定位不同但网关在“统一管理”这个目标上优势明显。SDK 的问题在于它是代码级的。每个语言要维护一份版本升级要推动所有业务方改代码密钥还是散落在各处的配置文件里。而网关是服务级的业务方只需要改一个 base_url剩下的全在服务端控制。密钥轮换、限流调整、模型切换改配置就行不用动业务代码。当然网关也有代价多了一跳网络开销多了一个要运维的组件。但对于“多家大模型统一管理”这个诉求这点代价完全值得。实测下来同机房内网多一跳的延迟通常在个位数毫秒相比模型本身几百毫秒到几秒的推理时间可以忽略。3. 鉴权与密钥管理统一管理的第一道关3.1 虚拟密钥的设计统一管理最核心的一步是把厂商的真实密钥藏起来对外只发虚拟密钥。虚拟密钥的格式我一般设计成sk-前缀加一段随机串和主流厂商的格式保持一致这样业务方接入时几乎无感。虚拟密钥背后要绑定几个东西所属业务线、可用模型范围、配额上限、有效期。业务方拿到的 key 只能调它被授权的模型超额了直接被拒过期了自动失效。这样一来某个业务线的 key 泄露了影响范围是可控的不会波及整个账号。密钥的存储我强烈建议加密落库用的时候解密。别图省事直接明文存配置文件我踩过这个坑某次代码仓库权限配错差点把一堆真实密钥暴露出去。加密方案用主流的对称加密就行密钥本身放在环境变量或密钥管理服务里不要和密文放一起。3.2 鉴权流程的落地一次请求进来鉴权大概走这么几步从请求头里取出虚拟 key先做格式校验格式不对直接 401拿 key 去缓存里查绑定的元信息缓存没命中再查库校验 key 是否过期、是否被禁用校验请求的模型是否在授权范围内校验配额是否还有余量全部通过后把请求标记上业务线标识放行到路由层这里面缓存很关键。鉴权是每个请求都要走的路径如果每次都查库数据库压力会很大。我一般用内存缓存加短过期时间比如 60 秒配合密钥变更时的主动失效。这样既保证了性能又保证了密钥状态变更能在秒级生效。注意配额校验如果放在鉴权阶段做精确扣减会有并发问题。我的做法是鉴权时只做粗粒度的余量判断真正的扣减放到请求完成后异步做用消息队列削峰。这样既不会因为并发把配额算错也不会拖慢主链路。3.3 密钥轮换与回收厂商密钥是会轮换的人员离职、业务下线也会导致虚拟 key 需要回收。统一管理的好处在这里体现得淋漓尽致。厂商密钥轮换时只需要在网关后台更新一次所有业务方无感。虚拟 key 回收时把状态置为禁用缓存失效后立即生效不需要去翻哪个业务代码里还引用着这个 key。我建议给每个虚拟 key 都记录创建人、创建时间、最后使用时间。最后使用时间这个字段特别有用能帮你识别出哪些 key 是僵尸 key可以定期清理。我们内部就靠这个字段半年清掉了三成没人用的 key减少了大量潜在风险。4. 路由与故障转移让调用稳下来4.1 基础路由策略路由层最基础的能力是模型名映射。业务方请求里写的是统一的模型别名比如chat-default网关根据配置把它映射到具体的厂商模型比如某家的对话模型。这样业务方不用关心底层换没换模型网关改个配置就能切换。映射关系我建议做成可热更新的配置不要写死在代码里。用配置中心或者数据库都行关键是改完能立即生效不用重启服务。我们内部用的是数据库加本地缓存改完配置发个通知各节点刷新缓存秒级生效。4.2 故障转移怎么做才靠谱故障转移是路由层最有价值的能力之一。某家厂商接口挂了网关能自动把流量切到备用模型业务方几乎无感。但要做好并不简单有几个坑我踩过。第一个坑是误判。不能因为一次超时就判定厂商挂了可能是网络抖动或者单个请求的问题。我的做法是滑动窗口统计比如最近 30 秒内错误率超过 50% 且请求数超过阈值才触发熔断。阈值设太低会频繁误切设太高又起不到保护作用需要根据实际流量调。第二个坑是切换后的模型能力差异。备用模型和主模型的能力可能不一样直接切过去可能导致输出质量下降。我的做法是给每个模型别名配置一个优先级列表切换时按优先级选下一个可用的同时记录切换事件方便事后复盘。第三个坑是恢复后的流量回切。主模型恢复了不能一下子把流量全切回去容易把它再次打挂。我一般用渐进式回切比如先放 10% 流量观察稳定了再逐步加。故障场景检测方式处理策略恢复方式单次超时请求级超时重试一次自动持续错误滑动窗口错误率熔断并切换备用渐进回切限流拒绝返回码识别切换备用或排队配额恢复后回切全厂商故障多厂商同时异常降级到本地模型手动介入4.3 多厂商并行的价值除了故障转移多厂商还有一个价值是成本优化。不同厂商、不同模型的定价差异很大同样的任务用便宜模型能省不少钱。网关可以根据请求的特征做智能路由比如简单问答走便宜模型复杂推理走贵模型。但这个策略要谨慎别为了省钱牺牲体验。我的建议是先跑一段时间收集数据看看不同模型在你们实际业务上的表现差异再决定哪些场景可以降级。盲目降级导致用户投诉省的那点钱不够赔的。5. 限流、配额与成本归集把账算清楚5.1 限流的多维度设计限流要分维度做我一般设三层全局限流保护整个网关不被压垮设一个总 QPS 上限业务线限流每个业务线有自己的 QPS 上限防止一个业务挤占其他业务的资源密钥限流单个虚拟 key 的 QPS 上限防止某个调用方异常刷量限流算法用令牌桶比较合适能应对一定的突发流量。实现上可以用 Redis 做分布式限流保证多网关节点之间的计数一致。如果网关是单机部署本地令牌桶就够了性能更好。提示限流阈值不要拍脑袋定要根据实际流量分布来。我一般会先观察一周的流量曲线取 P99 峰值再上浮 20% 作为初始阈值然后根据实际拒绝率调整。5.2 配额与成本归集配额管理要区分“次数配额”和“token 配额”。对话模型通常按 token 计费所以 token 配额更准确。但 token 数要等请求完成才知道所以扣减是异步的。成本归集的关键是打标。每个请求进来时网关要记录业务线、虚拟 key、模型、输入 token 数、输出 token 数、单价请求完成后把这些数据落到明细表。有了明细月底按业务线、按模型、按项目出账单就是分分钟的事。我们内部的做法是明细数据先写消息队列再由消费程序批量入库避免高频写库影响主链路。明细保留三个月聚合数据长期保留。这样既能查细账又不会让存储无限膨胀。5.3 预算告警光有配额还不够还要有告警。我一般设两级告警用量达到预算 80% 时预警达到 100% 时告警并可选自动停用。预警发给业务负责人让他心里有数告警发给平台负责人及时介入。告警渠道用邮件加即时通讯工具都行关键是别只发一次。我见过因为告警被淹没在消息里没人看结果超额跑了一整天的案例。重要告警要能升级比如 30 分钟没人处理就升级到上一级。6. 可观测性没有日志和指标就是黑盒6.1 要采集哪些指标网关的指标我分四类流量指标QPS、请求数、按业务线和模型维度切分质量指标成功率、错误码分布、超时率性能指标延迟 P50/P95/P99、首 token 延迟、吞吐成本指标token 消耗、费用、按维度归集这些指标要能实时看也要能按时间段回溯。实时看用监控面板回溯用明细查询。我建议至少保留 30 天的明细指标聚合指标保留一年。6.2 日志怎么记才有用日志不是记得越多越好关键是要能定位问题。我一般记三类日志访问日志每个请求的元信息包括请求 ID、业务线、模型、耗时、状态码、token 数错误日志失败的请求要记详细错误信息包括上游返回的原始错误审计日志密钥变更、配置变更、配额调整等管理操作请求 ID 特别重要要贯穿整个链路。业务方报障时提供请求 ID你就能一路查到上游厂商的返回定位效率高很多。我习惯用 UUID 做请求 ID在网关入口生成透传到上游。6.3 链路追踪如果团队已经有链路追踪体系把网关接进去会很有帮助。一次请求从业务方到网关再到厂商完整链路能看清每一跳的耗时。特别是排查“为什么这次调用特别慢”这类问题时链路追踪比看日志高效得多。没有链路追踪体系也不强求网关自己的日志加上请求 ID 已经能解决大部分问题。先把基础做好再考虑进阶。7. 实操落地从零搭一个最小可用网关7.1 技术选型网关本身的技术栈我建议用团队最熟悉的语言。这东西逻辑不复杂关键是稳定和好维护。Python 的 FastAPI、Go 的 Gin、Node 的 Express 都能胜任。如果团队没有明显偏好我倾向 Go性能和并发处理上有优势部署也简单。存储方面配置和密钥用关系型数据库缓存用 Redis明细数据用消息队列加时序库或数据仓库。这些都是成熟组件不用追求新潮。7.2 最小可用版本的范围第一版别贪多我建议只做这几件事统一的请求接口兼容主流厂商的请求格式虚拟密钥鉴权模型名映射基础限流访问日志故障转移、成本归集、智能路由这些都可以放到第二版。先把主链路跑通让业务方用起来再根据反馈迭代。我见过太多团队想一次做全结果做了三个月还没上线业务方早就不耐烦了。7.3 关键配置示例模型映射配置大概长这样models: chat-default: primary: provider: vendor-a model: chat-pro endpoint: https://api.vendor-a.com/v1/chat fallback: - provider: vendor-b model: chat-standard endpoint: https://api.vendor-b.com/v1/chat timeout: 30s retry: 1 embedding-default: primary: provider: vendor-c model: embed-v2 endpoint: https://api.vendor-c.com/v1/embeddings timeout: 10s限流配置rate_limits: global: qps: 1000 business: team-alpha: qps: 200 team-beta: qps: 100 key: default: qps: 50这些配置我建议放数据库通过管理后台维护改完热更新。配置文件只放启动必需的基础配置。7.4 上线节奏上线我一般分三步走第一步灰度接入一个非核心业务观察一周确认稳定性和功能符合预期。第二步接入核心业务但保留直连厂商的降级通道万一网关出问题能快速切回去。第三步全部业务接入关闭直连通道完成统一管理。每一步都要有回滚预案。网关是单点一旦挂了影响所有业务所以高可用要做足。至少两个节点前面挂负载均衡数据库和缓存也要有冗余。8. 常见问题与排查技巧实录8.1 典型问题速查问题现象可能原因排查方向解决方法大量 401密钥失效或缓存未刷新查密钥状态和缓存刷新缓存或更新密钥延迟突然升高上游厂商抖动或网关瓶颈看上游延迟和网关资源切换备用或扩容配额算不准并发扣减或异步延迟查扣减日志改异步扣减加对账流式响应中断超时设置或网络问题查超时配置和链路调整超时或加重试模型切换后质量下降备用模型能力差异对比输出质量调整优先级或换备用8.2 几个我踩过的坑坑一流式响应的超时设置。流式请求的总时长可能很长但首 token 延迟很短。如果按总时长设超时长回答会被误杀如果按首 token 设又保护不了慢响应。我的做法是设两个超时首 token 超时和总超时分开首 token 超时短一些总超时长一些。坑二重试导致重复计费。请求超时后重试如果上游其实已经处理了就会产生两次计费。我的做法是给每个请求带唯一 ID上游支持幂等的话就传过去不支持的话就只在明确失败比如连接失败时重试超时这种不确定的情况不重试。坑三缓存穿透。虚拟 key 查缓存没命中就查库如果大量无效 key 请求打进来会把数据库压垮。我的做法是对不存在的 key 也做短时间缓存比如缓存 10 秒的空结果挡住恶意刷量。坑四配置热更新的原子性。配置更新时如果多个节点刷新时间不一致会出现短暂的行为不一致。我的做法是配置带版本号节点刷新时对比版本确保拿到的是同一版本。8.3 性能优化的几个点网关本身要尽量轻别在里面做重逻辑。我见过在网关里做内容审核的结果审核服务一慢整个网关都卡住。重逻辑应该异步做或者放到独立服务。连接池要配好。和上游厂商的 HTTP 连接要复用别每次请求都新建连接。连接池大小根据并发量调太小会成为瓶颈太大浪费资源。序列化和反序列化是容易被忽视的开销。请求和响应体可能很大用高效的序列化库能省不少 CPU。JSON 是通用选择如果追求极致性能可以考虑更紧凑的格式但兼容性会差一些。9. 私有化模型怎么接进来9.1 私有化模型的特殊性私有化部署的模型和云端 API 有几个不同一是地址在内网网关要能访问到二是通常没有标准的鉴权机制或者鉴权方式自定三是性能和容量有限限流要更严格。接入方式和云端模型类似也是走适配层只是适配的目标从公网地址换成内网地址。鉴权如果私有化模型没有可以在网关侧做对业务方仍然要求虚拟 key。9.2 混合路由很多团队是云端和私有化混用的。敏感数据走私有化普通请求走云端。网关可以根据请求的标记或者内容特征来决定路由。标记的方式更可靠业务方在请求里带上数据敏感级别网关按级别路由。私有化模型的容量通常有限要做好排队和降级。请求量超过容量时要么排队等待要么降级到云端。降级要谨慎涉及敏感数据的请求不能降级到云端这种情况只能排队或者拒绝。9.3 容量规划私有化模型的容量规划要基于实测。用压测工具测出单实例的 QPS 上限和延迟曲线再根据业务量决定部署几个实例。留足余量别跑到满载满载时延迟会急剧上升。我一般按峰值流量的 1.5 倍来规划容量再考虑一定的增长空间。私有化模型的扩容不像云端那么灵活要提前规划。10. 一些个人体会这套东西我从最早的脚本拼凑到后来的统一网关前后迭代了三四版。最大的体会是统一管理的价值不在于技术多先进而在于把混乱收敛成秩序。技术选型用最普通的就行关键是流程和规范要立起来。另一个体会是别追求一步到位。第一版能解决 80% 的问题就够了剩下的 20% 在用的过程中会自然浮现到时候再针对性解决比一开始就设计一个完美方案要务实得多。还有就是数据是迭代的基础。没有调用数据你根本不知道该怎么优化。所以第一版一定要把日志和指标做扎实哪怕功能少一点数据不能少。有了数据后面每一步优化都有依据。最后说个具体的虚拟 key 的命名规范。我建议用“业务线-环境-用途”的格式比如alpha-prod-chatbot。这样一看 key 就知道是谁在用、干什么用的排查问题时特别省事。这个规范我们内部推行后密钥管理的混乱程度下降了一大截。