假如你管着一家大型客服中心,客户只需要记住一个总机号码,拨通后说出需求,接线员就会把电话转给最合适的专家——擅长闲聊的快嘴阿发、擅长推理的深思老陈,还有性价比均衡的全能小慧。客户不需要知道每个专家的分机号,更不用在打错电话时沮丧地重拨。今天要讲的“大模型统一网关”,正是这座智能总机:业务方只对接一个 API,网关在背后默默完成路由分发、负载均衡、限流降级、密钥管理、计费统计、日志审计、多模型容灾和统一接口协议这八件大事。本文会用这座总机贯穿始终,带你把每个模块的设计逻辑都捋一遍,学完你就能动手搭一个生产可用的 LLM 网关,让多模型混用不再是绕不开的乱麻。

岗位关联

对 AI 从业者而言,掌握网关架构意味着你拥有了“管住所有模型调用”的能力——无论做平台架构、后端开发还是 SRE,这都是从“调 API”迈向“设计 API 基础设施”的关键一跃。

目录
  1. 可视化演示
  2. 路由分发策略
  3. 负载均衡算法
  4. 限流降级机制
  5. 密钥安全管理
  6. 计费统计报表
  7. 日志与审计
  8. 多模型容灾切换
  9. 统一接口协议
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示大模型统一网关的架构设计实践的核心机制,通过基础/核心/应用/扩展四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

大模型统一网关的架构设计实践:LLM网 LLM网关架构总览与统一接入定 多模型路由分发与负载均衡设计 核心机制可视化 大模型统一网关的架构设计实践整体架构与关键组件

路由分发策略

云海集团话务中心刚开业时,接线员小云收到一个来自“快嘴阿发”的教训:一位客户想咨询养老金理财规划,阿发秒回一句“您可以去银行问问”,客户当场挂机投诉。小云这才意识到,三位专家各有脾气——阿发擅长简短闲聊,深思老陈擅长一步步推演,全能小慧则什么都能接但单项不算顶尖。如果电话来了不分青红皂白乱转,服务质量就会崩盘。它需要的是一套“转接规则”:先判断客户的真实意图,再决定把电话交给哪位专家。

技术里这套“转接规则”就是模型路由(Model Routing)。网关收到一个请求后,不会盲目把提示词塞给默认模型,而是先分析请求属于什么任务类型——写代码、数学推理、情感陪伴还是内容摘要——再基于模型画像做匹配。实现上通常有两个层次:入门做法是用意图分类器或关键词模板把请求分类;进阶做法是给每个模型计算一个综合得分,谁分高就选谁。这种“打分路由”能同时把任务类型、质量要求、成本预算都揉进同一个决策里。

打分路由的经典公式可以写成三个维度的加权和:

小云后来把这条规则做成了一张“专家名片卡”,每个专家都标注擅长领域、平均响应时长和每分钟报价。客户来电时,它先在心里默念三秒钟“这通电话考的是啥”,再掏出名片卡算一算该给谁。有了这套打分路由,总机的转接终于从“拍脑袋”变成了“有据可依”。

Scorei=α×Ci+β×Ei+γ×Ki,α+β+γ=1\displaystyle \text{Score}_i = \alpha \times C_i + \beta \times E_i + \gamma \times K_i,\quad \alpha + \beta + \gamma = 1
这个公式的意思很直白:把“能力、速度、便宜程度”三项分别打分后乘上权重再求和,总分最高的模型赢得这次转发。
  1. 能力分 C_i衡量模型对当前任务类型的熟练程度,取值范围为0到1,越接近1表示越擅长这类任务
    Ci∈[0,1]C_i \in [0, 1]
  2. 效率分 E_i衡量模型响应速度,基于平均延迟做归一化,延迟越低该值越接近1
    Ei=1−latencyimax⁡(latency)E_i = 1 - \frac{\text{latency}_i}{\max(\text{latency})}
  3. 成本分 K_i衡量模型调用单价,价格越低得分越高,用来防止“杀鸡用牛刀”
    Ki=1−priceimax⁡(price)K_i = 1 - \frac{\text{price}_i}{\max(\text{price})}
  4. 加权合成 Score_i通过权重系数调整三者重要性,得到每个模型的最终路由评分
    Scorei=α×Ci+β×Ei+γ×Ki\text{Score}_i = \alpha \times C_i + \beta \times E_i + \gamma \times K_i

负载均衡算法

路由规则解决的是“转给谁”,但很快就碰到了新问题:全能小慧口碑好,一天有三百通电话点名找她,快嘴阿发却闲得在工位上打瞌睡。小云发现,哪怕路由打分再准,如果“忙闲不均”,照样会让专家过劳、客户久等。这就跟银行柜台叫号一样——业务能力再强的柜员,窗口前队伍排成长龙也无济于事,得先让各个窗口的队列长度保持基本一致。

在网关世界里,同一个模型服务往往会部署多个副本实例,就像一位专家开了好几个业务窗口。负载均衡(Load Balancing)就是负责把流量均匀地分发到这些实例上,避免某个实例被打爆、其他实例空转。最常见的算法有三种:轮询(Round Robin)按顺序一字排开轮流分配;加权轮询(Weighted Round Robin)让性能强的实例多分到一些流量;最少连接(Least Connections)则实时观察每个实例正处理的请求数,谁最闲就先给谁。

加权轮询的分配概率可以写成:

小云在自己的排班表上给每位专家画了一条“承压警戒线”,并给能干的小慧安排了两个分身窗口。这样就算三百通电话同时涌进来,也能按照各窗口的空闲程度自动分流。总机的日常从“手忙脚乱”变成了“有条不紊”,这正是负载均衡的功劳。

Pi=wi∑j=1nwj\displaystyle P_i = \frac{w_i}{\sum_{j=1}^{n} w_j}
每个实例被抽中的概率,等于它的权重占所有健康实例权重总和的比重。权重好比各窗口安排的人手数量,人多的窗口自然应该承接更多电话。
  1. 权重 w_i第i个实例被期望承担的流量比例,取值非负,性能越强或配额越高则权重越大
    wi≥0w_i \ge 0
  2. 总权重把当前所有可用实例的权重加在一起,作为归一化的基准
    Total=∑j=1nwj\text{Total} = \sum_{j=1}^{n} w_j
  3. 选择概率 P_i每个新请求落入实例i的概率,权重越大概率越高
    Pi=wi∑j=1nwjP_i = \frac{w_i}{\sum_{j=1}^{n} w_j}

限流降级机制

促销节那天,电话像潮水一样涌了进来,总机瞬间涌入上千通来电。小云慌慌张张把电话全接起来,结果所有人都听到一段滋滋声——交换机过热差点宕机。冷静下来后它学到一个道理:与其让所有电话一起卡死,不如先放进来一部分,其余电话礼貌地提示“当前话务繁忙,请稍后再拨”。这就是限流与降级的雏形。

限流的本质是保护下游模型服务不被突发流量冲垮。最简单粗暴的做法是“每秒最多放行100个请求”,但这样会出现一个尴尬场景:刚过0点的一瞬间涌来200个请求,后80个被一律拒之门外;过了三秒没人打电话了,又白白浪费了配额。业界更常用的方案是令牌桶(Token Bucket):系统按固定速率往桶里放令牌,每个请求必须取走一个令牌才能通过。桶里攒了一些令牌时,就能应对短时间的突发流量,同时长期速率又被牢牢控制住。

令牌桶的更新规则如下:

除了限流,小云还给总机加了“降级预案”:当某位专家忙不过来时,自动播放一段语音让客户先留言,或者把一些不太重要的咨询转给低成本的快速通道。这就好比餐厅等位时先发个排队小票,客人不至于饿着肚子干等,后厨也不至于手忙脚乱。

Bt=min⁡(Bmax⁡,  Bt−1+r×Δt)\displaystyle B_{t} = \min\left(B_{\max},\; B_{t-1} + r \times \Delta t\right)
桶里的令牌数按时间流速递增,但最多不能超过桶容量。满了就溢出不累积,这模拟了“短时突发可容忍、长期滥发不可行”的限流直觉。
  1. 桶容量 B_max令牌桶最多能存放的令牌数量,决定了系统允许的瞬间突发上限
    Bmax⁡∈Z+B_{\max} \in \mathbb{Z}^{+}
  2. 补充速率 r每秒钟向桶内补充的令牌数,它决定了系统的长期平均吞吐量
    r>0r > 0
  3. 时间差 Δt当前时间与上一次取走令牌时刻的间隔,用来计算这段时间补充了多少令牌
    Δt=tnow−tlast\Delta t = t_{\text{now}} - t_{\text{last}}
  4. 更新规则先按时间补充令牌,再与容量上限比较取较小值,确保不会无限累积
    Bt=min⁡(Bmax⁡,  Bt−1+r×Δt)B_{t} = \min(B_{\max},\; B_{t-1} + r \times \Delta t)

密钥安全管理

总机开始向外部公司开放后,新的麻烦来了:不同客户付的钱不一样——金牌会员可以调用最贵的深思老陈,普通客户只能用快嘴阿发。可小云怎么知道来电人是谁?而且,三位专家各自有自己的内部工号(调用厂商 API 所需的密钥),这些工号绝不能发给客户,否则客户就能绕过总机直接找专家,账就没法算了。

在网关架构里,密钥管理的核心是“身份认证 + 权限隔离”。客户调用网关时,只需要出示自己的一个 API Key,这个 Key 相当于总机的会员卡——网关先验证这张卡的合法性,再从卡的配置里查出这名客户被允许使用哪些模型、每月有多少配额。而各厂商的真实密钥被集中托管在网关的“保险柜”中,从不对外暴露。常见的实现方法包括:用 KMS(密钥管理服务)做加密存储、按用户或团队做 Key 的权限绑定、设置定期轮换策略以降低泄露风险、以及审计每次 Key 的使用记录。

小云把客户的会员等级、可转接专家范围、每月通话分钟数都写进了一张“客户档案卡”。客户打电话时先报会员号验证身份,小云再根据档案卡决定放行还是婉拒。至于专家们的内部工号,则锁在保险柜里,连客户服务部门的同事都看不到。总机的管理一下子就规范了起来,再也没有人能用别人的工号乱打电话了。

计费统计报表

月底财务把一沓账单拍在小云桌上:三家客户的费用对不上账。小云这才发现,自己光顾着转接电话,没记录每通电话打了多久、用了哪位专家、各自什么单价。就像话费账单要区分本地通话和长途一样,模型调用也需要把“输入提示词”和“输出结果”分开计量——它们消耗的 token 数量不同,单价也不同。

计费模块是网关里离“钱”最近的模块,它在上层做的事叫 Token 计量:每完成一次请求,网关从模型响应里读出输入 token 数和输出 token 数,再乘以对应模型的单价,得到本次费用。更进一步,还要按用户维度做分账(每个部门/项目各花了多少钱)、按模型维度做成本分析(哪个模型性价比最高、是否应该调整路由权重)。对于企业客户,这些报表通常会导出成每日/每月的汇总账单。

单次请求的费用公式非常简单:

小云从此养成了好习惯:每通电话结束,立刻在话单上记下“几点几分、打了多久、找的哪位专家、客户是谁”。月底账单一出,每家客户清清楚楚,连深夜里阿发偷偷接的一通闲聊电话都无所遁形。总机从“赔本赚吆喝”变成了“明码标价”,财务再也没来找过麻烦。

Bill=nprompt+ncompletion1000×p\displaystyle \text{Bill} = \frac{n_{\text{prompt}} + n_{\text{completion}}}{1000} \times p
把输入的提示词 token 数和输出的结果 token 数相加,除以 1000 换算成“千 token”,再乘以每千 token 的单价 p,就是一次调用的费用。
  1. Token 总量一次调用消耗的总 token 数,由输入提示词与输出结果两部分相加得到
    tokens=nprompt+ncompletion\text{tokens} = n_{\text{prompt}} + n_{\text{completion}}
  2. 单位价格 p该模型每千 token 的计费单价,不同模型价格差异较大
    p=price per 1000 tokensp = \text{price per 1000 tokens}
  3. 账单金额总 token 数除以 1000 后乘以单价,得到本次调用的金额
    Bill=tokens1000×p\text{Bill} = \frac{\text{tokens}}{1000} \times p

日志与审计

有一天,一位客户气冲冲地打电话投诉:“上次你们总机转接的专家,回答里出现了无礼的话!”小云傻眼了,因为当时没有录音,谁也说不清那位专家到底说了什么。吃一堑长一智,它开始给每一通电话配一个唯一的“案件编号”,把来电时间、来电人、转给了谁、专家说了什么、耗时多久全部记在一张通话单上。必要时,还能把整通对话重新回放一遍。

在网关架构里,这个“案件编号”就是 Trace ID(追踪标识)。网关是每一次模型调用的必经之路,所以它是记录日志、做全链路追踪的最佳位置。网关收到请求时生成一个 Trace ID,让它随着请求一路传到模型服务的内部环节,所有组件都在日志里带上这个 ID。以后想排查“某条回复为什么慢”或“这条违规内容是谁触发的”,只需要按 Trace ID 一查,整条链路一目了然。

典型的网关日志会记录这些字段:

此外,网关还会在请求发送给模型之前、以及收到响应之后,各做一次内容安全审核——类似总机的质检员随机旁听电话。一旦输入提示词或输出内容命中敏感词、涉政违规、注入攻击等规则,网关会直接拦截或打回,从源头避免违规内容流出。这一点对金融、政务客户来说几乎是强制要求。

小云把“录音”和“质检”两件事都安排得明明白白:任何一通电话都能凭案件编号调出录音,任何一句敏感内容都过不了质检员的耳朵。总机的服务质量有了铁证,客户投诉率大幅下降,连监管部门来抽查时也夸它“资料齐全”。

多模型容灾切换

上午十点,晴天霹雳——深思老陈突发急病请假了!如果小云还继续把推理类电话都转给他,客户只能听到无人接听的忙音。好在总机早就有一套应急预案:每当一位专家连续三次没能正常接起电话,系统会自动把他标记为“请假状态”,后续属于他的电话全部改派给其他备用专家。这就是多模型容灾切换(Failover)的朴素直觉。

在网关的设计里,容灾不是一个“事后补救”的动作,而是一套“事前预防 + 事中切换”的机制。网关会周期性地向每个模型发送健康探测请求(探活),同时统计真实的请求失败次数。当某个模型的连续失败次数超过设定的阈值后,网关执行熔断——把它从可用实例列表中摘除,不再分配任何新请求。与此同时,流量会按事先配置的优先级列表切换到备用模型;如果所有备用模型都失败,网关则返回自定义的降级提示,而不是让调用方无限等待。

熔断判定的状态机可以写成:

小云在排班表上给每位专家都标注了一两位“替补专家”。老陈请假的瞬间,系统自动把案件转给全能小慧,并给运维人员发出告警短信。客户那边几乎毫无感知,只是觉得这次回复稍慢了一点点而已。这就是容灾的价值:宁可让备用专家顶上,也绝不让客户对着忙音干等。

statusi={normal,if faili<θunhealthy,if faili≥θ\displaystyle \text{status}_i = \begin{cases} \text{normal}, & \text{if } \text{fail}_i < \theta \\ \text{unhealthy}, & \text{if } \text{fail}_i \ge \theta \end{cases}
连续失败次数达到阈值,模型就被标记为不健康。这相当于总机观察到专家连续三次没接电话后,果断把来电改派给其他人,而不是继续做无用尝试。
  1. 连续失败数 fail_i统计模型i最近连续失败的请求次数,成功一次则清零重计
    faili∈N\text{fail}_i \in \mathbb{N}
  2. 熔断阈值 θ人为设定的失败次数上限,通常取3或5,太小容易误伤,太大反应太慢
    θ≥3\theta \geq 3
  3. 状态判定根据失败次数是否达到阈值,将模型标记为正常或不健康
    statusi={normal,faili<θunhealthy,faili≥θ\text{status}_i = \begin{cases} \text{normal}, & \text{fail}_i < \theta \\ \text{unhealthy}, & \text{fail}_i \ge \theta \end{cases}

统一接口协议

日子一长,客户们提出了一个奇怪的要求:“我们不想分别学习三位专家的'说话格式'——有人爱用 XML 传参数,有人非要 JSON 不可,还有人要用流式打字机才能说话。能不能让我们永远只对总机说普通话?”小云一拍大腿:对啊,客户本来就不该关心幕后专家用什么方言。只要总机当个翻译,把客户的统一请求“翻译”成各专家能听懂的话,再把专家的回答“翻译”回统一格式就行了。

这正是网关的统一接口协议设计——目前业界事实上的标准是 OpenAI 兼容协议。业务方只需要按照 OpenAI 的请求结构写一套代码,网关内部的“协议适配器”负责把标准请求转换为各家厂商的原生格式:调用百度文心时拼成它的参数结构,调用阿里通义时用它的签名算法,调用 Anthropic 时转成它的消息格式。响应回来时再反向转换,把各家不同的错误码、字段名、流式格式统一映射回标准格式。这样一来,业务方想从 Azure 换到国产模型,只需要在网关配置里改一个模型名称,业务代码一行都不用动。

协议适配层通常还要处理流式输出:OpenAI 的 SSE 格式、各家厂商的流式 chunk 结构各不相同,网关需要把服务端推送的每个事件重新封装成统一的事件流,才能保证前端“打字机效果”不中断。此外,像函数调用、多模态输入这类高级特性,各家差异更大,都要在适配器里逐项对齐。

小云在总机前台立了一块牌子:“对客统一普通话,背后翻译我负责。”客户果然满意了——他们只需要学会拨一个号码、说一套请求格式,剩下的事全交给总机。以前签一个模型要改一次代码,现在签约接入就像往通讯录里加一个联系人那么简单。总机大楼真正成了集团对外服务的唯一入口。

AI 应用场景

跨境电商客服混用多模型

阶段:应用集成与上线运维

解决的问题:客服场景流量波动大,直接用 GPT-4 成本高且高峰期常被限流,不同咨询类型又适合不同模型,硬编码调用让代码耦合严重。

具体案例:某跨境电商平台把客服机器人全部接入统一网关:日常问候和订单查询走低成本模型,复杂售后纠纷走强推理模型;网关按会话意图自动路由,并在 GPT-4 触发限流时自动 Failover 到国产模型。上线后月度模型成本下降约 35%,高峰期客服平均响应时间反而缩短了 20%。

金融企业 AI 开发平台统一管控

阶段:平台建设与资源治理

解决的问题:多家分行业务部门各自申请模型密钥,费用分散失控,密钥还可能随着员工离职而泄露,缺少统一的配额和审计机制。

具体案例:某股份制银行建设企业级模型网关,所有分行 AI 应用统一通过网关调用模型。平台在 KMS 中集中托管各厂商密钥,按部门配置调用配额和限流阈值,并接入统一日志与账单系统。月底自动生成各分行、各项目的费用报表,安全团队可随时审计某个密钥的完整调用记录。

政务 AI 应用的合规审计

阶段:安全合规与审计

解决的问题:监管要求留存 AI 生成内容记录,出现违规回答时能够快速回溯定位到具体用户和触发请求。

具体案例:某政务热线 AI 助手在网关层开启了全量日志和敏感词审核:所有用户输入先过内容安全审核,命中规则直接拦截;模型输出也经过二次审核才返回给用户。一次安全演练中,管理员凭一条 Trace ID 在几秒内锁定了触发违规内容的用户、模型、提示词和完整响应记录,顺利通过监管检查。

Python 演示

python93 行
"""简化版LLM网关:统一路由+限流+多模型容灾演示"""import timeimport threading  class MockModel:    """模拟一个真实模型服务"""    def __init__(self, name, latency=0.02, fail_rate=0.0):        self.name = name        self.latency = latency        self.fail_rate = fail_rate        self.calls = 0     def invoke(self, prompt):        time.sleep(self.latency)        self.calls += 1        if self.fail_rate > 0 and self.calls % 5 == 0:            raise ConnectionError(self.name + " service down")        return "[" + self.name + "] reply: " + prompt[:12] + "..." class TokenBucket:    """令牌桶限流器:按固定速率补充令牌"""    def __init__(self, capacity=20, refill_rate=10.0):        self.cap = capacity        self.rate = refill_rate        self.tokens = capacity        self.last = time.monotonic()        self.lock = threading.Lock()     def allow(self):        with self.lock:            now = time.monotonic()            self.tokens = min(self.cap, self.tokens + (now - self.last) * self.rate)            self.last = now            if self.tokens >= 1:                self.tokens -= 1                return True            return False  class LLMGateway:    """统一入口:负责路由 负载均衡 限流 容灾"""    def __init__(self):        self.llm_map = {}        self.bucket = TokenBucket(capacity=20, refill_rate=10.0)        self.served = 0        self._rr_idx = -1     def register(self, name, provider):        self.llm_map[name] = {"provider": provider, "available": True, "fails": 0}     def _pick_provider(self):        pool = [n for n, m in self.llm_map.items() if m["available"]]        if not pool:            return None        self._rr_idx = (self._rr_idx + 1) % len(pool)        return pool[self._rr_idx]     def chat(self, prompt):        if not self.bucket.allow():            return {"status": 429, "msg": "rate limited"}        for _ in range(len(self.llm_map)):            name = self._pick_provider()            info = self.llm_map[name]            try:                reply = info["provider"].invoke(prompt)                info["fails"] = 0                self.served += 1                return {"status": 200, "provider": name, "reply": reply}            except Exception as exc:                print("[warn]", name, "fail:", exc)                info["fails"] += 1                if info["fails"] >= 3:                    info["available"] = False                    print("[failover]", name, "removed, switch to backup")        return {"status": 503, "msg": "all model unavailable"}  def main():    gw = LLMGateway()    gw.register("GPT-4", MockModel("GPT-4", latency=0.03, fail_rate=0.0))    gw.register("Claude-3", MockModel("Claude-3", latency=0.05, fail_rate=0.4))    gw.register("Ernie-4", MockModel("Ernie-4", latency=0.02, fail_rate=0.1))     print("=== LLM Gateway Demo ===")    for i in range(12):        result = gw.chat("question %d: how to design gateway" % (i + 1))        print("req[%02d] -> %s" % (i + 1, result))        time.sleep(0.06)  if __name__ == "__main__":    main()
目的:用 100 多行代码演示一个极简 LLM 网关,包含统一调用入口、令牌桶限流、加权轮询路由和连续失败自动摘除的容灾逻辑。
  1. class TokenBucket:实现令牌桶限流器,allow() 每次调用取走一个令牌,没令牌就拒绝请求。
  2. self.tokens = min(self.cap, self.tokens + (now - self.last) * self.rate)按时间补充令牌,但不超过桶容量,对应正文里的令牌桶公式。
  3. pool = [n for n, m in self.llm_map.items() if m["available"]]只从健康模型中挑选目标,实现“故障节点自动摘除”。
  4. self._rr_idx = (self._rr_idx + 1) % len(pool)轮询游标,让请求依次落在不同健康模型上。
  5. if info["fails"] >= 3:连续失败 3 次即触发熔断,把该模型标记为不可用,后续请求自动切换。
  6. if not self.bucket.allow():在路由之前先做限流,保证下游模型不被突发流量打垮。
  7. for _ in range(len(self.llm_map)):最多尝试所有可用模型,全部失败才返回 503,实现 Failover 重试。

常见误区

误区很多初学者觉得,网关无非就是在模型前面加一层转发,配个 Nginx 把 `/api` 转发到 OpenAI 的地址就完事了,路由、限流这些都多此一举。

正解网关真正的价值恰恰在“策略层”而不是“转发层”。它像总机接线员,不只是把电话线插到某个分机上,而是要判断该转给谁、什么时候告诉客户“请稍等”、每通电话怎么收费、出了问题去查哪段录音。普通反向代理只解决了“接通”的问题,路由分发、熔断降级、计费审计这些业务决策才是网关存在的理由。

为何常见:因为从网络拓扑看,网关确实长得像一个代理组件,容易被误认为纯网络层面的工具。

误区我认为限流就是统计 QPS,比如每秒最多放行 100 个请求,第 101 个直接返回 429,简单粗暴挺好用的。

正解朴素计数器的最大问题在于完全不允许突发流量。晚上 8 点整有一波 200 个请求同时进来,其中 100 个被拒,可明明系统此时完全有能力处理更多。令牌桶通过“攒令牌”的方式允许短时间内的突发,同时把长期速率限制在合理范围。更进一步的限流还应该搭配排队缓冲和熔断降级,而不是只有“拒绝”这一个动作。

为何常见:因为“每秒最多 N 个”是最容易想到的数学模型,而“允许短时冲高、长期平滑”需要多一层思考。

误区各厂商的 API Key 通常都放在后端环境变量里,我们的项目也一直这么干,网关再去搞一套密钥管理纯属多此一举。

正解只有两三个服务、一个密钥时,环境变量确实够用。但网关面对的往往是几十个模型供应商、成千上万个调用方,密钥管理的核心已经变成了“授权”和“审计”:A 用户不许调用 B 用户的配额,某把密钥泄露后要能在几分钟内完成轮换,每次调用要查得到是哪把钥匙发起的。这些能力需要一个结构化的密钥管理系统,而不是藏在 .env 文件里的一个字符串。

为何常见:因为小项目里“把密钥配到环境变量”是标准做法,很多人没经历过密钥泄露或跨部门配额纠纷,容易低估规模放大后的管理复杂度。

误区多模型容灾很简单,调用时用 try-catch 包一下,如果第一个模型抛异常了,catch 住再调用第二个模型的 API 不就行了?

正解对零散的几次调用,事后 catch 确实够用。但网关面对高并发流量,必须“事前判断健康”而不是“事后补救”。它要做主动健康探测、连续失败计数,在正式请求发出之前就把不健康的节点从候选池里摘掉,否则故障期间依然会有海量请求撞向已经挂掉的服务。还要处理“刚切换流量又回切到故障实例”的抖动,这需要专门的熔断和恢复策略,不是 catch 一个异常那么简单。

为何常见:因为业务代码里处理单个请求失败的方式就是 try-catch,思维停留在“一次调用”的粒度上,没上升到“集群流量调度”的视角。

误区统一接口协议不就是规定一种 JSON 请求格式吗?让所有厂商都按照这个格式传参,问题就解决了。

正解请求格式统一只是冰山一角。真正麻烦的是响应侧的差异:各家厂商返回的字段名、错误码、重试策略、限流提示都不一样,流式输出更是各有一套协议。网关需要做完整的“协议翻译”:把标准的 OpenAI 格式翻译成各家原生接口,再把各家的响应和流式事件翻译回标准格式。函数调用、多模态输入这些高级特性的差异更深,都需要适配层逐项处理。

为何常见:因为大多数开发者在项目中只对接过一种厂商的 SDK,很少同时面对多种协议,容易低估“协议差异”的深度和广度。

面试题

Q1. 大模型网关的首要职责是什么?

单选题 · easy

  • A.统一路由管理多模型← 正确答案
  • B.部署新模型副本
  • C.微调训练自有模型
  • D.压缩模型推理体积

答案:A。网关的核心是作为统一入口管理多个模型服务的调用,类似总机负责把电话转给合适的专家。部署副本、微调训练、压缩体积都属于模型平台或推理优化的工作,不是网关的职责。

Q2. 令牌桶限流算法中,参数 r 表示什么?

单选题 · easy

  • A.令牌桶的最大容量
  • B.令牌每秒补充速率← 正确答案
  • C.当前剩余令牌数量
  • D.请求执行超时时间

答案:B。r 是令牌的补充速率,决定系统长期平均吞吐量。桶容量由 B_max 决定,剩余令牌数由当前状态记录,超时时间与限流无关。就像总机每秒最多接入多少通新电话,由 r 决定。

Q3. 加权轮询与普通轮询的核心区别是什么?

单选题 · mid

  • A.按实例性能调整分配概率← 正确答案
  • B.按请求内容智能路由
  • C.完全随机选择实例
  • D.自动保存会话状态

答案:A。加权轮询给不同实例分配不同的权重,权重越大被选中的概率越高,对应“人手多的窗口多接电话”;普通轮询则完全均等分配。按内容路由属于路由模块,随机选择是另一类算法,会话保持与负载均衡关系不大。

Q4. 网关的密钥管理通常包含哪些能力?

多选题 · mid

  • A.密钥加密后集中存储← 正确答案
  • B.按用户授权做隔离← 正确答案
  • C.定期轮换降低风险← 正确答案
  • D.将密钥明文下发给前端

答案:ABC。密钥管理要像总机的保险柜一样集中存储且加密保护,按用户权限区分可以访问的模型,定期轮换防止长期泄露。把密钥明文发给前端会直接暴露给浏览器,是最严重的安全反模式。

Q5. 网关进行计费统计时,Token 数量如何计算?

单选题 · mid

  • A.仅统计输入提示词
  • B.仅统计输出内容
  • C.输入与输出之和← 正确答案
  • D.请求报文头部长度

答案:C。一次大型语言模型调用的费用由“输入提示词”和“输出结果”两部分 token 数共同决定,二者按各自单价计费后相加。统计请求头长度属于网络层信息,与模型计费完全无关。

Q6. 多模型容灾切换通常依赖哪些机制?

多选题 · mid

  • A.主动健康检查探测← 正确答案
  • B.连续失败计数统计← 正确答案
  • C.自动摘除故障节点← 正确答案
  • D.修改用户密码参数

答案:ABC。容灾是一套组合拳:主动探活确认模型是否存活,连续失败计数决定何时熔断,达到阈值后自动摘除节点并切换流量。修改用户密码是密钥管理范畴,与容灾无关。

Q7. 网关收到一个请求后,最先应该完成的步骤是什么?

单选题 · hard

  • A.立即统计本次费用
  • B.校验调用方密钥← 正确答案
  • C.缓存模型输出结果
  • D.预热备用节点资源

答案:B。网关的第一道关口是身份鉴权——先确认来电人是不是合法客户、有没有权限,否则后续一切操作都可能被滥用。计费、缓存、预热都应在鉴权通过之后进行。就像总机接起电话先问“您的会员号是多少”。

Q8. 高并发场景下 Failover 时所谓的“抖动”是指什么?

单选题 · hard

  • A.流量回切至故障实例← 正确答案
  • B.网络延迟明显升高
  • C.模型回答内容漂移
  • D.日志写入速度变慢

答案:A。抖动指故障实例刚被摘除,稍一恢复探活又把它加回来,导致流量在故障和健康之间反复横跳,反而让更多请求失败。成熟的熔断器通常需要“冷却期”或“半开试探”来避免抖动,而不是一恢复就立刻回切。

Q9. 设计网关的路由打分时,哪些维度可以被纳入公式?

多选题 · extreme

  • A.模型专业能力分← 正确答案
  • B.平均响应延迟← 正确答案
  • C.单位Token成本← 正确答案
  • D.部署机房地区

答案:ABC。打分路由通常融合能力、效率、成本三类指标,分别对应“是否擅长”“是否够快”“是否便宜”。部署机房地区影响的是网络延迟和数据合规,一般不会直接作为路由打分项,而是通过延迟间接反映。

Q10. 网关请求日志中的 Trace ID 主要作用是什么?

单选题 · easy

  • A.串联标识整条请求链路← 正确答案
  • B.作为模型生成内容
  • C.加密用户历史会话
  • D.代替API密钥鉴权

答案:A。Trace ID 像总机的案件编号,把一次请求从网关到模型再到响应的所有环节串联起来,便于排障和审计。它不是模型输出,也不承担加密和鉴权职责。