01谁会调用这个——每个产品团队,还是少数几个?
每个团队:gateway 是通往模型供应商的唯一入口——一个团队一把 API key,一个使用场景一套策略,让 failover、配额与脱敏只存在一次,而不是四十次。
免费完整指南
设计一套 LLM inference gateway,位于内部产品团队与多家模型供应商/后端之间,在公司规模下处理路由、流式、配额与安全管控。
面试节奏保持精简,让页面能把注意力花在真正的设计决策上。
不要只是陈述需求,要主动问出来。每张卡把设计约束和一句你可以在画架构前说出口的澄清问句配成一组。
01谁会调用这个——每个产品团队,还是少数几个?
每个团队:gateway 是通往模型供应商的唯一入口——一个团队一把 API key,一个使用场景一套策略,让 failover、配额与脱敏只存在一次,而不是四十次。
02某个供应商开始出错——这是谁的问题?
gateway 的:每个使用场景声明一条 schema 兼容的模型 fallback 链,逐供应商做健康检查,回应带有 model_used 与 fallback_reason,让调用方能分辨。
03用户是看着答案一个词一个词出现吗——到第一个词的时间对产品重要吗?
会直通——供应商一吐出 token,就穿过 gateway,绝不缓冲;gateway 在流式途中计量 token,让配额与成本也看得见流式流量。
04限额是以请求数计,还是以 token 计?
以 token:一个请求可能花 100 个或 100,000 个 token,所以每个团队有每分钟 token 速率与每月美元预算——请求数对真正的成本单位是盲的。
05同一个 prompt 进来一千次——就生成一千次?
不——一模一样的重复请求可以只回答一次再复用,但只限提问的那个团队之内;个性化或用户专属的流量一律必须新鲜生成。
06供应商推出新模型版本——谁升级,何时升级?
各团队策略:一个团队可以为输出稳定钉住某版本,或随供应商发布接受升级——而被钉住的团队在供应商宣布淘汰其模型的那天就会收到倒计时。
范围外训练或微调模型(只服务推理流量) · 打造 GPU 服务栈本身(那是供应商那侧的事) · 终端用户身份与 session——调用方是内部服务
01gateway 本身可以加多少延迟?
在全组织每日约 200 万个请求上,gateway 在请求路径上加约 10-20 ms——first-token 延迟才是产品指标,而 gateway 绝不被允许成为它翻倍的原因。
02一个垂死的供应商必须多快被检测到?
垂死的供应商要在数秒内被检测到,逐供应商、逐模型——而到底是几秒是一个产品决策,因为检测每晚一秒,就是一秒的用户请求在失败。
03从 prompt 与回应中要记录什么?
metadata 一律记录(token、模型、成本、延迟、trace id);prompt 与回应内容只有在 PII(个人可识别信息)脱敏 hook 跑过之后才记——日志里的原始 prompt 会把 gateway 变成一起合规事故。
04团队的预算上限有多硬——如果请求正好在额度边上突发涌到,小幅超支可以容忍吗?
上限是绝对的:一百个并行请求不能各自都把最后一美元花掉——团队的预算永远不能被并发冲破,因为这些是真实开票的美元。
05凌晨两点花费暴涨——我们多快能知道是谁、为什么?
每次调用都落进一本用量账本,带着团队、使用场景、模型、token、成本、cache 与 fallback 标志——归属是近实时可查的,不是月底才从供应商发票重建出来。
真实面试探得比一份整齐清单深得多。这些范围问句,区分出真正拷问问题的人和只是背诵的人。
把每个估算都当成一种压力,用来合理化一个组件:缓存、队列、分片、副本、worker pool 或退路。
成本归属——按 token,不是按请求
一个团队:每日 200,000 个请求,每个约 3,000 input + 800 output token,input 每 1M 收 $3、output 每 1M 收 $15600M input × $3 + 160M output × $15 = $1,800 + $2,400 = $4,200/天 ≈ $126K/月
按请求的限流根本看不见这笔账单——配额与预算必须以 token 计价,input 与 output 分开定价。
failover 检测预算
组织量约每日 200 万请求(NFR 里给定):2M ÷ 86,400 s ≈ 平均 23 requests/s,工作日峰值约为平均的 4 倍 ≈ 100 requests/s,大多落在主要供应商上;breaker 用 10 s 滑动窗口搭配 20% 错误阈值100 requests/s × 10 s ≈ 窗口内约 1,000 次调用;全面中断时,1,000 的 20% = 200 个错误在 200 ÷ 100 ≈ 2 s 后累积到位——所以 breaker 打开前约有 200 个请求失败
窗口长度本身就是一份用户痛苦预算:越短跳得越快、但会被一秒的抖动误触——把它当成一个产品数字来选,并搭配 half-open 探测。
流式 vs 缓冲的第一个 token
一个 800-token 的答案以约 60 tokens/s 生成;缓冲式 gateway 在转发前先扣住完整回应缓冲第一个 byte:800 ÷ 60 ≈ 13 s;直通第一个 token:~0.5-1 s → 感知延迟约差 15-25×
每在流式路径上加一个同步跳点,都会被所有请求付账——流必须在流动中被检查,绝不停放。
语义缓存的经济账
全组织每日 2M 请求,精确 + 语义合计 15% 命中率,每请求约 $0.021 供应商成本(来自上面的 token 算式)300,000 次命中 × $0.021 ≈ $6,300/天 ≈ $190K/月 节省;一次命中约 50 ms 回应,而不是约 13 s
真金白银加上巨大的延迟胜利——但每一次命中都是一次服务错答案的机会,所以 key 必须包含租户、模型版本与模板版本。
半故障时的队列深度
一次半故障把主要供应商的吞吐在峰值约 100 requests/s 时砍半、持续 5 分钟:100 进来、50 服务、什么都不卸载backlog 增长 (100 - 50) × 300 s = 15,000 requests;恢复后以约 20 requests/s 的余量容量,排空还要约 12 分钟
把一切都排队,会把 5 分钟的半故障变成约 18 分钟的劣化与 15K 条打开的连接——改成卸载批量流量、并让交互流量 fail over。
决策示例
四十个团队每日两百万个请求、每个大约两美分,约是每日 $42,000 的供应商花费——跑在每家每月都有某周半瘫个几分钟的供应商上。
我会建一条 gateway 路径:认证团队、对其预算预留 max_tokens、先查精确匹配再查语义缓存、按使用场景的模型链路由并带逐供应商错误率 breaker,然后把供应商 token 直接流式过去、同时在流式途中计量。用量结算进逐团队账本;prompt 内容只有在脱敏 hook 之后才碰日志;模型版本是逐团队策略——钉住并附淘汰倒计时,或在 eval canary 后方自动升级。
我不会做的事:让团队直接调用供应商——那是四十套 failover 实现、零共用归属。我不会用请求数当配额:一个 100-token 的 ping 和一个 100,000-token 的 agent 循环不是同一笔花费。我也不会为了检查而缓冲流——一个等待完整回应的 gateway,会把 1 秒的第一个 token 变成 13 秒的沉默。
如果只有一个团队、一个模型、每月四位数的花费,一个带重试的薄共用 client library 才是诚实的答案——只有当团队、供应商或花费成倍增长时,gateway 才配得上它的复杂度。
先看一张完整的图,再把每条路径各自画成一张图 —— 写入路径与读取路径承载不同流量,合理化不同的组件。
完整全貌
热路径是 auth → 预留预算 → cache → 路由 → 流式;账本结算与健康记账在它之外。一次 breaker 跳闸只改变路由器的选择——调用方维持同一份契约,只会看到 model_used 改变。
路径 1
gateway 在 token 流动时计数,并在流式结束时把账本从预留结算成实际——配额与成本看流式流量就跟看阻塞调用一模一样。
路径 2
fallback 必须与主要模型 schema 兼容,而回应会说是哪个模型回答的——无声替换会弄坏每一个依赖输出形状的团队。
在优化之前,先让契约可被检视:端点、实体、所有权、重试与状态。
POST/v1/responses
请求{ use_case, messages, max_tokens, stream: true, output_schema? }
响应SSE token 流;trailers 带有 model_used、token 数、成本、cache/fallback 标志
团队身份来自 API key,绝不来自 request body——每家供应商前面都是同一份契约,所以换供应商永远不动到产品代码。
GET/v1/usage (team_id, window=month)
响应{ tokens, cost_usd, by_model, by_use_case }
把成本归属当成产品功能——团队主管与财务读这个,而不是供应商发票。
PUTinternal: policy(team_id, changes)
响应热重载的策略:pins、预算、模型链、kill switch
关掉一个失控的团队是一次 config 写入,不是一次紧急部署。
核心实体
TeamPolicyteam_id (PK) · use_case · model_chain (primary → fallbacks) · version_policy: pinned/auto · tokens_per_min · monthly_budget_usd · redaction_profile
可热重载——一次预算变更或一个 kill switch 不能等到部署。
UsageLedgerEntryrequest_id (PK) · team_id · model_used · input_tokens · output_tokens · cost_usd · cache_hit · fallback_reason?
归属的真实来源——调用前先以预留写入,调用后结算成实际值。
ProviderHealthprovider + model · error_rate (sliding window) · p95 latency · breaker: closed/open/half-open
路由器在每次派发前读的东西;half-open 探测决定何时允许流量回来。
CacheEntryembedding key · tenant_scope · model + template version · response · ttl
只要忽略这些 key 的任何一个,就会发出一个陈旧或跨租户的答案。
在面试最后三分之一挑一条路线。每条路线给你主题、它该回答的面试官问题,以及要避免的失败模式。
一个流在 800 个 token 的第 400 个时因供应商 500 而断掉。客户端看到什么,而你能不能对一个进行中的生成做 failover?
用一个明确的错误事件来结束这个流。绝不能悄无声息,也绝不能把另一个模型的 token 拼接进来——它接不上那句写了一半的话。生成没法中途续上,所以 failover 是在 fallback 上明确地重新开始。那次挂掉的调用,在账本里就按它实际产出的 400 个 token 结算。
悄悄在供应商 B 上重新生成并把 token 接起来——客户端已经渲染了半个答案,而新模型不会产生同样的接续;resume 是一次 restart,必须明确。
某个团队失控的 agent 循环在两天内烧光了组织的整月预算。按照它们应该触发的顺序,走一遍本该存在的控制。
先跑 reserve-then-settle 检查。每次调用先预留它的 max_tokens,用完再按实际用量结算,这样并行的循环不会同时把最后一块钱都花掉。接着,每个团队一个 tokens-per-minute 上限来给循环踩刹车。一个按每小时美元算的 burn-rate 告警第一天就能抓到它——月度上限只是最后的兜底。
把月结发票当成唯一的控制——逐次调用 token 计量、逐团队上限、以及对烧钱速率(每小时美元对基线)的告警,会在第一天而不是第三十天抓到它。
用户把 prompt 里一个关键字改掉,却仍拿到旧 prompt 的缓存答案。语义缓存哪里出错,什么在约束它?
错在只信相似度。否定词能在 0.98 cosine similarity 的情况下把意思翻个个儿,所以一个几乎一模一样的 prompt 并不是同一个 prompt。先做精确匹配,语义那一层拿不准时宁可放过。每条缓存都按 key 划范围:tenant、模型版本、模板版本。把个性化流量挡在外面,再给每次命中配一个 TTL。
把相似度阈值当成整个安全故事——否定在 0.98 cosine 相似度下就翻转了意思;key 需要租户、模型与模板版本,个性化流量排除在外,命中还要带 TTL。
供应商宣布你钉住的模型 90 天后死亡。那是谁的问题,而 gateway 的升级路径长什么样?
gateway 负责把它摆出来,团队来决定。倒计时从供应商宣布的那天就开始,不是到第 90 天才开始。然后是一道 eval 关卡:拿团队的 golden prompt 在新版本上重放,用一小片真实流量做 canary,等他们签字确认再切换。悄悄地把一个 pin 住的团队自动升级,会毁掉他们当初 pin 就是为了要的那份稳定。
无声地自动升级每个人——为输出稳定而钉住的团队,会拿到针对他们自己黄金 prompt 的 eval gate、一个 canary 切片、以及一次签核,并从第一天就把倒计时摊开来。
安全在生成前加了一个同步审核调用,first-token 延迟翻倍。你如何同时保住护栏与延迟预算?
这些检查并行跑,别挡在前面。把输入审核和路由、供应商派发一起发出去,一旦它没过就取消生成。这样它的延迟就藏在本来就在跑的活儿后面了。输出这边,用滚动窗口边流边扫,配一个硬性的中途截断——别为了到最后再检查,把一个 13 秒的回答整个缓冲下来。
把每个检查都串在供应商调用前面——input 检查与路由并行跑,output 审核则以滚动窗口扫描流并设一个 cut-off,而不是缓冲整个答案。
把 LLM 推理网关 大声讲一遍,让 AI 为你的说明评分。