什么是 LLM 网关?限流、降级、多模型路由怎么设计?
谁在问:中大厂平台组二面;有多个业务线共用模型预算的团队、正在建 AI 中台的组
口语化问法
- 你们公司这么多业务线都在调模型,是怎么统一管理的?
- 如果让你设计一个 LLM 网关,你会放哪些能力进去?限流怎么做?
- 网关这一层会不会成为瓶颈?什么情况下你觉得不该上网关?
考察意图
这是平台组的标准题,面试官在判断:
- 你有没有意识到 LLM 限流和普通 API 限流是两回事。 只说 QPS 的人,一定没接过真实的上游配额。
- 你知不知道网关的代价。 只讲好处的回答等于没做过——网关是一跳、是单点、是新的故障域。
- 你能不能识别场景差异。 这道题最强的开场是一个反问:上游是商业 API 还是自建推理? 两者的限流量纲和负载均衡信号完全不同。
参考答案
60 分答案(及格线)
LLM 网关是所有模型调用的统一出入口,把散落在各个业务里的 SDK 调用收敛到一层。核心能力大概有这几块:
- 统一 API:屏蔽各家厂商的接口差异,业务方只对一套协议编程;
- 鉴权与配额:给每个团队发虚拟 key,设预算上限;
- 限流:防止单个业务把配额吃光;
- 重试与降级:上游报错时自动重试,或者切到备用模型;
- 可观测与分账:记录每次调用的 token 数和成本,按团队出账;
- 缓存:对重复请求直接返回,省钱省延迟。
限流一般用令牌桶配合 Redis,按 key 或者按团队维度限制每分钟的请求数和 token 数。降级方面,配置一个 fallback 链,主模型失败就自动走备用模型。
好处是治理集中、成本可见、切换供应商方便。
为什么只有 60 分:能力清单是完整的,但全是"有什么",没有"为什么难"。限流那段是普通 API 网关的答案照搬——完全没提 LLM 特有的"输出 token 事前不可知"这个硬问题。降级说成"配一个 fallback 链",也没意识到它的三重代价。
90 分答案(有生产经验的回答)
我会先问一个问题:上游是商业 API 还是自建推理集群? 因为这决定了后面几乎所有设计。商业 API 侧要保护的是厂商给的配额,量纲是 token;自建推理侧要保护的是 KV Cache 显存,量纲是并发数。把这两件事混起来,限流一定会失效。
先说形态。 网关有三种,混为一谈是最常见的失分点:SDK 形态零网络跳数但无法跨服务统一治理;自托管 Proxy 有统一入口但你自己承担单点和容量;托管 SaaS 零运维但你的 prompt 会流经第三方——这一条在强合规场景是死穴。我们选的是自托管 Proxy,因为核心诉求是分账和可撤退,不是省运维。
限流是这道题真正的技术点,它有一个 LLM 特有的硬问题:输出 token 在请求发出前是不可知的。 业界只有三种解:
- 悲观预扣:按
max_tokens预扣配额。代价是配额被大量浪费,还会出现一个反直觉现象——用量指标看着很低却一直 429。这不是 bug,是设计。 - 后验记账:先放行,响应回来读实际用量记账,超额影响的是下一次。代价是单次超大请求一定会漏过限流。
- 预扣 + 回填:按
max_tokens预占,响应回来按实际用量归还差额。实现要事务性计数器,但这是生产上的正解。
我们用的是第三种。同时做了一件收益最大的事:把默认 max_tokens 从 4096 压到 512——因为限流是按预估扣的,这一改直接把 429 率降了一个数量级。
还有一条必须配上的:并发闸门。 官方明确承认过,并发请求下 token 消耗会临时超过配置的限额——因为 token 数要等响应回来才知道,并发窗口内的请求都是"盲发"的。所以并发数是唯一能在请求发出前就生效的硬约束,token 限流和并发限流不是二选一,是必须都有。
降级这块,我最想强调的是 429 和 529 完全不是一回事。 429 是你超限了,读 retry-after 做指数退避加随机抖动,同厂商重试;529 是上游过载,重试不但无用还会加重雪崩,正确动作是切 fallback;403 配额耗尽和 413 请求过大都是不可重试的。而且有一条反直觉的官方警告——失败的请求同样计入你的每分钟配额,所以盲目重试是在用配额买配额。
跨厂商 fallback 的真实成本是三重的,不是配一行 config:缓存归零(跨厂商必然 100% 未命中,即使同厂商跨模型降级,也可能因最小可缓存长度门槛跳档而让输入成本涨十倍)、输出契约破裂(tool schema、结构化输出格式、流式事件语义都可能不兼容)、合规越界(主链路合规不代表降级链合规)。我们的做法是给降级链单独跑一遍输出契约测试、单独过一遍合规评审,敏感流量的降级目标只能在同等合规级别内选。
负载均衡这块有个细节我觉得很能说明问题:面向商业 API 时,成熟网关默认用的是每输出 token 耗时而不是端到端延迟做打分。因为 LLM 的端到端延迟主要由输出长度决定,用端到端做负载均衡等于惩罚那个恰好接到长回答的健康节点。而面向自建推理时信号完全不同——KV Cache 利用率、队列深度、前缀缓存命中、LoRA 亲和。
最后是代价,我觉得不讲代价的网关方案都是不可信的:
- 限流计数存储是隐藏的单点。Redis 挂了,限流器 fail-open 还是 fail-close?前者成本失控,后者全量 AI 功能瘫痪。这个取舍必须提前写进预案。
- 网关自报的延迟不含排队时间(它从 handler 开始计时),会出现"日志说 10 秒、用户说 20 秒",必须用 in-flight 请求数交叉验证。
- 流式会让网关的三项能力同时降级:限流从精确变估算、响应侧护栏架构性失效、缓存写入时机变复杂。
什么时候不该上网关:单服务、单厂商、没有分账需求时,SDK 形态就够了,Proxy 只是白加一跳和一个单点;首字延迟预算低于 300 毫秒的实时链路要慎重;以及组织还没开始追问 AI 账单的时候——那时候上网关是提前优化。
追问链
max_tokens从 4096 压到 512,429 率就降一个数量级,为什么?期望限流按估算扣、计费按实际收:估算取的是max_tokens,设 4096 而实际只输出 200,配额被白白浪费 20 倍,账单上却毫无异常 —— 这正是「用量指标很低却一直 429」的成因。动作是按场景分档:分类 128、问答 512、长文生成单开一条链路,别用全局一个值信号解释得出「按估算扣、按实际收」这个错位 → 被这坑咬过;答「请求变小所以省配额」 → 没理解机制Redis 挂了,你的限流器 fail-open 还是 fail-close?
期望fail-open 几分钟能烧掉一大笔钱、或把上游配额打爆、所有业务一起 429;fail-close 则全量 AI 功能瘫痪。答案是分层:全局成本兜底(日预算)走 fail-close,钱是不可逆的;单租户公平限流走 fail-open,保的是体验。本地再留个粗粒度计数器兜底信号能分层、并点出「钱不可逆所以走 fail-close」 → 想过这件事;只选一边不说后果 → 没预案网关引入之后延迟涨了多少?你怎么测的?
期望先质疑数字:同一家官方给过 P95 8 毫秒和 P99 257 毫秒,前者打的是假上游。看性能数先查三件:mock 上游没有、日志护栏缓存开没开、P50 还是 P99。盲区是网关自报延迟从 handler 起算、不含排队,得客户端侧测端到端再与自报值对差信号讲得出「日志说 10 秒、用户说 20 秒」这个具体现象 → 一定排过网关的障多个业务线共用配额,怎么保证不互相饿死?
期望三层:① 配额隔离:每团队独立虚拟 key 与TPM/RPM、预算上限,不共池;② 优先级借用:核心链路保底,非核心只借空闲、高峰先挤出;③ 可观测先行:用量成本按租户看得见才谈分配。批处理一次提交极大量,最易饿死在线链路,得走独立池或上游批处理接口(五折、不占实时配额)信号提到「异步任务走独立池 / 走批处理接口」 → 真管过多租户配额;只说「给每个团队设个限额」 → 没遇过尖峰踩踏上线半年,业务方说「网关是瓶颈,我们要绕过它直连」,你怎么处理?
期望① 先拉数据,别争论:客户端端到端 vs 自报延迟,差值即排队 → ② 真是网关,先做不改架构的优化:日志回调异步化、护栏按场景开、缓存查找加短超时 fail-open、扩容 → ③ 优化不掉的(首字延迟预算 300 毫秒的实时链路)给受控例外:可直连,但用量成本照报 → ④ 底线不发长期密钥,只签短时效令牌信号第一动作是「拉数据验证」而不是辩解或答应 → 成熟;能把「绕过网关」和「绕过治理」分开、给出 SDK 形态这个中间选项 → 有架构判断
评分要点
- 先反问"上游是商业 API 还是自建推理",并说得出两者限流量纲不同
- 区分网关的三种形态(SDK / 自托管 Proxy / 托管 SaaS)及各自代价
- 说得出限流要按 TPM / ITPM / OTPM,不是只按 QPS
- 说得出输出 token 事前不可知的三种解,并选一种给出理由
- 知道并发闸门是唯一在请求发出前生效的硬约束
- 429 与 529 分叉处理,且知道失败重试也消耗配额
- 说得出跨厂商 fallback 的三重代价(缓存归零、契约破裂、合规越界)
- 谈负载均衡时提到每输出 token 耗时而非端到端,并说得出原因
- 主动讲网关的代价:单点、可观测盲区、流式下三项能力降级
- 说得出什么时候不该上网关