1. 多模型接入的混乱现场:从三套密钥到一张账单
如果你所在的公司只有一支团队、只调一家大模型的 API,那这篇文章大概率帮不上你什么忙。但只要公司规模稍微上来一点,事情就会变得非常具体:算法组在用一家做推理,客服团队接了另一家做意图识别,市场部又自己申请了一个账号跑文案生成,财务月底对账时发现有三张不同平台的账单,而安全部门在例会上问了一句“这些 Key 都存在哪、谁能看到”,全场安静。
这就是“企业如何统一管理多家大模型 API”这个问题的真实起点。它不是一道架构题,而是一道管理题——统一管理这四个字,管的从来不只是接口调用,而是密钥、额度、权限、日志、成本、模型路由这六件事。标题里没有“网关”两个字,但热搜词里出现了“AI网关”“鉴权”“统一管理”,说明大家心里其实都清楚,最终要落到的就是一层中间层。
我先把结论摆在这里:企业统一管理多家大模型 API,本质上是自建或引入一个LLM Gateway(大模型网关),把上游 N 家厂商的差异(鉴权方式、请求格式、返回结构、计费口径、限流策略)全部收敛到一层,对下游只暴露一套统一的 OpenAI 兼容协议。下游业务方不需要知道背后是智谱、DeepSeek 还是别家,只需要拿一个内部 Key,调一个地址。
这篇文章适合三类人看:一是正在被多平台密钥管理折磨的后端或平台工程师;二是需要给公司做 AI 基础设施选型的技术负责人;三是想搞清楚“网关到底解决什么问题”的开发者。我会从需求拆解讲到落地实现,包括数据库表怎么设计、路由怎么做、鉴权怎么防绕过、成本怎么归集,以及我自己踩过的几个坑。
先说一个反直觉的判断:很多团队一开始觉得“统一管理”就是写个转发代理,几十行代码搞定,结果上线两周就发现根本不够用。因为转发只是最表层的能力,真正难的是当业务量上来之后,你要回答“哪个部门这个月花了多少钱”“某个 Key 泄露了怎么快速定位和吊销”“某家厂商挂了怎么自动切到备用模型”这些问题。转发代理回答不了这些,网关才能。
2. 先想清楚要收敛什么:多模型管理的六个真实痛点
在动手写代码之前,我建议先花半天时间把公司内部所有在用的模型 API 盘一遍。这一步很多人跳过,直接上来就搭网关,结果搭完了发现漏了两个业务线,又得返工。盘点的目的是明确你到底要收敛哪些东西。
2.1 密钥散落:最危险也最容易被忽视的问题
密钥管理是统一管理里优先级最高的一件事,但往往被排在最后做。我见过太多团队把 API Key 直接写在业务代码的配置文件里,然后这个配置文件被提交到了代码仓库。更糟的是,有些 Key 是个人账号申请的,员工离职之后 Key 还在用,出了事根本追不到人。
统一管理的第一步,是把所有上游厂商的 Key 收到网关这一层,业务侧再也拿不到真实的上游 Key。业务方拿到的是网关自己签发的内部虚拟 Key,这个 Key 只对网关有效,即使泄露,你也能在网关上立刻吊销,并且能通过日志查到它被谁用了、用在哪。
这里有个细节值得展开:内部 Key 的格式设计。我建议用sk-internal-前缀加上一段随机串,和上游厂商的 Key 格式区分开,避免有人误把内部 Key 填到上游 SDK 里。同时内部 Key 不要用自增 ID,防止被枚举。
2.2 额度失控:谁在偷偷跑批量任务
额度问题在多团队场景下特别突出。某个团队为了跑一次数据清洗,写了个脚本循环调用,一晚上烧掉几千块,第二天财务才发现。如果没有网关做统一限流和配额,这种事你只能事后追责,没法事前拦截。
网关层面可以做的控制包括:按 Key 设置每分钟请求数(RPM)、按 Key 设置每日 Token 上限、按部门设置月度预算。这些策略在网关统一配置,业务方无感知。当某个 Key 触达阈值时,网关返回明确的错误码,而不是让请求直接打到上游产生费用。
2.3 模型路由:不同任务该走哪家
不同模型的能力和价格差异很大。简单分类任务用便宜的小模型就够,复杂推理才需要上大模型。如果每个业务方自己决定用哪家,就会出现“杀鸡用牛刀”的浪费,或者“小马拉大车”的效果问题。
网关可以做基于规则的路由:请求里带一个逻辑模型名(比如chat-default、chat-cheap、chat-reasoning),网关根据配置映射到具体的上游模型。这样业务方只关心“我要一个便宜的对话模型”,不关心背后是谁。后续要换供应商,改网关配置就行,业务代码一行不动。
2.4 故障切换:某家挂了不能全公司停摆
单一供应商依赖是真实风险。某家厂商出现过区域性故障,导致依赖它的业务全线不可用。如果网关层做了多供应商配置,当主供应商连续返回错误或超时,可以自动切到备用供应商,业务侧几乎无感。
这里要注意,故障切换不是简单地把请求转发到另一家就完事。不同模型的返回格式、上下文长度、甚至对同一个 Prompt 的理解都可能不同。所以切换策略要谨慎,最好只对“格式兼容、能力接近”的模型做自动切换,能力差异大的模型之间切换要人工确认。
2.5 成本归集:月底对账不再靠猜
成本归集是网关最被低估的价值。没有网关时,你只能看到每家厂商的总账单,但不知道钱花在哪个部门、哪个项目、哪个功能上。有了网关,每次请求都记录调用方、模型、输入输出 Token 数,月底按部门或项目聚合,一目了然。
要做到这一点,网关必须能拿到准确的 Token 数。有些厂商在返回里带 usage 字段,有些需要自己用 tokenizer 估算。我建议优先信任厂商返回的 usage,拿不到时再用估算兜底,并在日志里标记数据来源,避免对账时口径不一致。
2.6 审计与合规:谁在什么时候调了什么
最后是审计。企业环境下,安全部门需要知道每一次模型调用的来源、内容摘要、时间。网关作为所有请求的必经之路,天然是审计点。记录请求元信息(不一定要存完整 Prompt,涉及隐私的要脱敏)和响应状态,形成可追溯的调用链路。
把这六个痛点列清楚之后,你会发现网关的功能边界其实很清晰。下面进入具体设计。
3. 网关的核心架构:请求进来之后发生了什么
理解了要收敛什么,接下来看网关内部怎么运转。我用一个请求的完整生命周期来串这条链路,这样比干讲架构图更容易理解。
3.1 一次请求的完整链路拆解
假设业务方发来一个请求,目标是chat-default这个逻辑模型。请求到达网关后,依次经过这几层:
第一层是接入层,负责解析 HTTP 请求,提取 Header 里的内部 Key。这一层要尽量轻,只做协议解析和基础校验,不做业务逻辑,保证高并发下的吞吐。
第二层是鉴权层,拿内部 Key 去查数据库或缓存,确认这个 Key 是否有效、是否被吊销、绑定了哪些权限。鉴权结果要缓存,否则每个请求都查库会成为瓶颈。缓存过期时间建议设短一点,比如 30 秒,这样吊销 Key 能较快生效。
第三层是配额与限流层,检查这个 Key 对应的配额是否还有余量,当前 RPM 是否超限。这一层通常用 Redis 做计数器,因为要跨多个网关实例共享状态。
第四层是路由层,把逻辑模型名映射到具体的上游厂商和模型。路由规则可以配置在数据库里,支持按权重、按优先级、按故障状态动态调整。
第五层是适配层,把统一的请求格式转换成目标厂商的格式。不同厂商的请求体字段名、参数默认值、甚至 system message 的处理方式都可能不同,这一层负责抹平差异。
第六层是转发与响应处理层,真正发起上游请求,拿到响应后再转换回统一格式返回给业务方。如果是流式响应,这一层还要处理 SSE 的透传和格式转换。
第七层是日志与计量层,记录这次调用的所有元信息,异步写入,不能阻塞主链路。
这七层里,鉴权、限流、路由、适配是核心,其他是辅助。下面重点讲几个容易做错的地方。
3.2 为什么选 OpenAI 兼容协议作为统一出口
统一出口的协议选择很关键。我的建议是直接用OpenAI 兼容格式,原因有三个。
一是生态成熟。市面上绝大多数 SDK、框架、工具都默认支持 OpenAI 格式,业务方接入成本最低。你不需要为每个业务团队写接入文档,他们照着 OpenAI 的用法来就行。
二是厂商支持度高。现在很多厂商都提供 OpenAI 兼容的接口,适配层的工作量小很多。即使某家不兼容,转换逻辑也相对固定。
三是迁移成本低。将来如果业务方想从网关直连某家厂商,代码几乎不用改,只是换个 base_url 和 Key。
提示:统一出口用 OpenAI 格式,不代表内部存储也用这个格式。建议内部保留一份标准化的请求模型,适配层负责双向转换,这样将来要支持非 OpenAI 风格的厂商时更灵活。
3.3 流式响应的透传陷阱
流式响应是网关实现里最容易出问题的地方。很多厂商用 SSE(Server-Sent Events)返回流式内容,但每家的 chunk 格式不完全一样。有的在最后一个 chunk 里带 usage,有的不带;有的用data: [DONE]结尾,有的用别的标记。
网关做流式透传时,不能简单地把上游的字节流原样转发,因为你要在中间插入计量逻辑。我的做法是:网关解析上游的每个 chunk,提取需要的信息(比如 Token 计数、结束标记),然后按统一格式重新组装 chunk 发给业务方。这样虽然多了一层解析开销,但保证了格式统一和计量准确。
实测下来,流式场景的延迟增加通常在几十毫秒以内,业务方基本无感。但如果你的网关和上游之间网络抖动大,建议给流式请求单独设置更长的超时时间,避免中途断开。
4. 鉴权体系怎么设计才不会被绕过
鉴权是网关的安全底线。热搜词里出现了“鉴权绕过”“无限鉴权授权”这类词,说明这是大家普遍关心的问题。我结合自己的实践,讲讲怎么设计一套不容易被绕过的鉴权体系。
4.1 内部 Key 的生成、存储与吊销
内部 Key 的生成要用密码学安全的随机数,长度建议 32 字节以上。存储时绝对不能存明文,要存哈希值。这样即使数据库泄露,攻击者也无法直接拿到可用的 Key。
吊销机制要设计成即时生效。我的做法是在 Redis 里维护一个吊销列表,鉴权时先查缓存。吊销一个 Key 时,同时更新数据库和缓存。缓存用短过期时间兜底,即使缓存更新失败,最多 30 秒后也会失效。
这里有个经验:给每个 Key 绑定一个用途标签和负责人。比如“客服意图识别 - 张三”。这样出问题时能快速定位到人,而不是面对一堆无意义的 Key 字符串。
4.2 权限模型:Key 能调哪些模型
不是所有 Key 都应该能调所有模型。一个只做文本分类的 Key,没必要给它调用最贵推理模型的权限。我建议做基于角色的权限控制:给每个 Key 分配一个角色,角色决定它能访问哪些逻辑模型。
权限检查放在鉴权层之后、路由层之前。如果 Key 没有权限访问目标模型,直接返回 403,不要转发到上游。这样既省了上游费用,也避免了信息泄露。
4.3 防止 Key 泄露后的横向扩散
即使做了上面这些,Key 还是可能泄露。关键是泄露之后的影响要可控。几个措施:
- 绑定来源 IP 段:如果业务方是从固定 IP 段调用的,可以在 Key 上绑定 IP 白名单,非白名单来源直接拒绝。
- 设置单 Key 速率上限:即使 Key 泄露,攻击者也无法用它发起大规模请求。
- 异常检测:监控每个 Key 的调用模式,如果突然出现调用量激增、调用模型变化、来源地变化,触发告警甚至自动冻结。
注意:IP 白名单在容器化、弹性伸缩的环境下可能不适用,因为出口 IP 会变。这种情况下可以改用请求签名机制,让业务方用密钥对请求签名,网关验签。
4.4 一个真实的鉴权绕过排查过程
说个我亲身经历的排查。有段时间监控发现某个内部 Key 的调用量异常高,但业务方说他们没改代码。排查链路是这样的:
先看网关日志,发现这个 Key 的请求来源 IP 和平时不一样。查 IP 归属,发现是某个云厂商的机房 IP,不是业务方的办公网。初步判断 Key 泄露了。
然后查这个 Key 是怎么泄露的。翻代码仓库的提交历史,发现两周前有个开发把测试配置提交上去了,里面带着这个 Key。虽然很快删了,但 Git 历史里还在。
最后处理:吊销旧 Key,重新签发,同时给所有 Key 加上 IP 白名单。这件事之后,我们加了一条 CI 检查,扫描提交内容里是否有疑似 Key 的字符串,命中就阻断合并。
这个案例说明,鉴权不只是技术问题,还涉及流程和工具。网关能做的是一旦泄露能快速止损,但防泄露要靠开发规范。
5. 路由与适配:让业务方只认一个模型名
路由和适配是网关的“翻译层”,决定了业务方用起来顺不顺。这块设计好了,业务方几乎感觉不到背后有多家厂商。
5.1 逻辑模型与物理模型的映射设计
核心思路是逻辑模型名和物理模型解耦。业务方只认逻辑名,比如chat-default、chat-fast、chat-reasoning。网关维护一张映射表,把逻辑名映射到一个或多个物理模型。
映射表的设计我建议包含这些字段:逻辑模型名、上游厂商、物理模型名、权重、优先级、启用状态。权重用于灰度或负载均衡,优先级用于故障切换。
举个例子,chat-default可以映射到两家厂商的模型,权重各 50%,这样既能分摊压力,也能在真实流量下对比两家的效果和稳定性。等积累够数据,再调整权重。
5.2 故障切换的触发条件与回切策略
故障切换不能太敏感,否则上游偶尔一次超时就切走,会造成大量请求打到备用模型,反而放大问题。我的经验是设置连续失败阈值:比如连续 5 次请求失败或超时,才触发切换。同时设置一个冷却期,切换后一段时间内不再切回,避免来回抖动。
回切策略同样重要。主供应商恢复后,不要立刻全量切回,而是先放少量流量试探,确认稳定后再逐步恢复。这个过程可以自动化,也可以人工确认,取决于业务对稳定性的要求。
5.3 参数差异的适配处理
不同厂商对同一个参数的处理可能不同。比如temperature的取值范围,有的支持 0 到 2,有的只支持 0 到 1。max_tokens的默认值和上限也不一样。适配层要做参数归一化:把业务方传的标准参数转换成目标厂商能接受的范围,超出范围的做截断或映射。
还有一个容易忽略的点是system message 的处理。有些厂商把 system message 作为独立字段,有些要求拼接到第一条 user message 里。适配层要根据目标厂商的要求做转换,保证语义一致。
5.4 上下文长度超限的兜底
热搜词里有一条“maximum context length is 1048576 tokens”的报错,这是很典型的上下文超限问题。不同模型的上下文窗口差异很大,从几万到上百万 Token 不等。网关在路由时,应该根据请求的预估 Token 数,选择上下文窗口足够的模型。
如果请求本身就超过了所有可用模型的窗口,网关要返回明确的错误,而不是让上游返回一个难懂的报错。更好的做法是在网关层做上下文裁剪:保留 system message 和最近的若干轮对话,把中间的历史摘要化或丢弃,保证请求能发出去。当然,裁剪策略要业务方知情,不能悄悄改语义。
6. 成本与可观测性:让每一分钱都有迹可循
网关跑起来之后,最有价值的产出其实是数据。这些数据能回答很多管理问题,也是网关区别于简单代理的核心。
6.1 Token 计量:信任厂商还是自己算
Token 计量是成本归集的基础。我的建议是优先信任厂商返回的 usage,因为厂商的计费就是基于它自己的 tokenizer,你用自己的算法算出来的数可能和账单对不上。
但有些厂商在流式响应里不返回 usage,或者只在最后一个 chunk 返回。这种情况下,网关需要在流式处理时累积计算。如果厂商完全不返回,就用开源 tokenizer 估算,并在日志里标记为估算值。
这里有个坑:不同厂商对“输入 Token”的定义可能不同。有的把 system message 算进去,有的不算。对账时如果发现网关统计和厂商账单有差异,先检查口径是否一致,不要急着怀疑代码。
6.2 按部门、项目、Key 三个维度的成本归集
成本归集要支持多维度,因为不同部门关心的口径不同。财务关心按部门的总账,项目经理关心按项目的花费,运维关心按 Key 的异常。网关的日志表设计要能支持这三个维度的聚合查询。
我的做法是在日志里记录完整的维度信息:Key ID、部门 ID、项目 ID、模型、Token 数、时间戳。然后用定时任务做预聚合,生成日报、月报。实时查询走明细表,报表走聚合表,避免大表扫描。
6.3 日志该记什么、不该记什么
日志记录要平衡可观测性和隐私。我建议记录:请求 ID、Key ID、逻辑模型、物理模型、输入输出 Token 数、耗时、状态码、错误信息。不记录完整的 Prompt 和响应内容,除非业务方明确要求且做了脱敏。
如果确实需要记录内容用于调试,建议单独存一个表,设置更短的保留期,并且做脱敏处理(比如把手机号、身份证号替换掉)。这块要和安全部门对齐,不能自己拍脑袋决定。
6.4 告警指标:哪些异常必须第一时间知道
网关的告警指标我建议至少覆盖这几类:单 Key 调用量突增、单 Key 错误率突增、某上游厂商整体错误率上升、配额即将耗尽、响应延迟明显上升。这些指标能帮你在问题扩大前介入。
告警阈值不要设得太死,要根据历史数据动态调整。比如调用量突增,可以设成“相比过去 7 天同一时段均值增长 3 倍”触发,而不是一个固定数字。
7. 落地路径与踩坑复盘
前面讲了设计和实现,最后讲讲怎么落地,以及我自己踩过的坑。这部分是文档里不会写的,但往往最有用。
7.1 从最小可用版本开始,别一上来就大而全
我见过有团队想一步到位,把网关做成一个功能齐全的平台,结果做了三个月还没上线,业务方等不及又各自接回了直连。正确的做法是先做最小可用版本:能鉴权、能转发、能记日志,先跑起来,让业务方用上,然后再迭代加功能。
最小版本的开发量其实不大,一个熟悉后端的人一两周能搞定。关键是先建立“所有请求走网关”的习惯,后面加功能才有意义。
7.2 灰度迁移:怎么让业务方愿意切过来
让业务方从直连切到网关,最大的阻力是“怕出问题”。我的做法是提供双跑对比:业务方同时走直连和网关,对比两边的响应,确认一致后再切。这个阶段网关只记录不拦截,业务方没有风险,自然愿意配合。
迁移顺序上,先切非核心业务,比如内部工具、测试环境,积累信心后再切核心业务。核心业务切换要选在低峰期,并且准备好回滚方案。
7.3 我踩过的三个坑
第一个坑是缓存穿透。早期鉴权缓存没做好,大量无效 Key 的请求直接打到数据库,把库压垮了。后来加了布隆过滤器,无效 Key 在缓存层就被拦掉。
第二个坑是流式响应的超时设置。一开始用了统一的超时时间,结果长文本生成经常被网关提前断开。后来给流式请求单独设了更长的超时,并且支持业务方自定义。
第三个坑是成本统计的时区问题。日志时间戳用了 UTC,但财务对账用的是本地时间,导致月初月末的数据对不上。后来统一在聚合层做时区转换,明细表保持 UTC。
7.4 后续可以扩展的方向
网关跑稳之后,可以往上叠更多能力。比如语义缓存:相似的请求直接返回缓存结果,省下上游调用。比如Prompt 模板管理:把常用 Prompt 集中管理,业务方引用模板 ID 而不是自己拼。再比如模型效果评估:在网关层做 A/B 测试,对比不同模型在同一批请求上的表现。
这些扩展都建立在网关已经统一接管流量的基础上。所以回到最初的问题——企业如何统一管理多家大模型 API?答案不是某个神奇的工具,而是先把流量收敛到一层,然后在这层上持续做管理和优化。工具可以选开源的,也可以自研,但收敛这件事本身,越早做越省心。
我在实际项目里的体会是,网关的价值在接入的前两周可能不明显,但一旦业务量上来、团队变多,它就成了不可或缺的基础设施。那些一开始觉得“没必要”的团队,往往在踩过几次坑之后,还是会回来补这一课。与其被动补课,不如一开始就把它做对。