什么是LLM Gateway?概念、架构与核心能力全解析(附请求链路与代码示例)

简介: 本文面向后端与平台工程师,详解LLM Gateway核心原理:区别于传统API网关,它专为大模型调用设计,处理长时流式响应、Token级限流与计量、语义缓存等关键问题,并附三段核心代码实现与K8s部署实践。(239字)

本文面向后端与平台工程师。代码为教学示意,省略了错误处理与部分安全细节,不可直接用于生产;接口字段以各模型官方文档为准。

很多团队第一次接触 LLM Gateway,是从一个很小的需求开始的:把散落在各个服务里的模型 API Key 收回来。做着做着就会发现,大模型调用和普通 HTTP 调用有几个根本不同:一次请求可能持续几十秒、响应是流式的、成本由 Token 而不是请求数决定。这几个不同,决定了 LLM Gateway 在架构上和传统 API 网关有明显区别。本文从一次请求的完整链路讲起,把概念、架构和核心能力落到代码和数字上。

一、LLM Gateway 是什么

LLM Gateway(大语言模型网关)是位于应用与大语言模型服务之间的代理层,对外提供统一的模型调用接口,对内负责鉴权、路由、Token 限流与计量、缓存、流式转发和可观测。

与传统 API 网关相比,LLM Gateway 需要处理三个特殊之处:

维度

传统 API 调用

LLM 调用

单次时长

毫秒到百毫秒

数秒到数十秒

响应形式

一次性返回

SSE 流式逐段返回

成本单位

请求数

输入 Token + 输出 Token

结果确定性

确定

不确定,相同输入可能不同输出

二、LLM Gateway 的请求链路:一次流式调用经过什么

以 OpenAI 兼容接口为例,应用发出的流式请求如下:

http

POST /v1/chat/completions HTTP/1.1

Host: llm-gateway.internal

Authorization: Bearer vk-team-a-xxxx

Content-Type: application/json

{

 "model": "general-chat",

 "messages": [{"role": "user", "content": "总结这份周报的三个要点"}],

 "stream": true,

 "stream_options": {"include_usage": true}

}

这里有两个细节:Authorization 中是网关签发的虚拟密钥,而不是模型厂商的真实密钥;model 字段是网关定义的路由别名,具体发往哪个模型由网关决定。stream_options.include_usage 让上游在流的末尾返回 Token 用量,这是网关结算的依据。

网关返回的是 SSE 事件流:

text

data: {"choices":[{"delta":{"content":"一、"}}]}

data: {"choices":[{"delta":{"content":"本周完成"}}]}

data: {"choices":[],"usage":{"prompt_tokens":812,"completion_tokens":156}}

data: [DONE]

在网关内部,这次请求依次经过:

1. 鉴权:解析虚拟密钥,映射到团队、应用和配额。

2. Token 预估与预占:估算输入 Token,加上 max_tokens,从团队的 TPM 令牌桶中预占。

3. 缓存查询:精确缓存或语义缓存命中则直接返回。

4. 路由选择:在别名对应的候选模型中选择端点。

5. 上游转发:替换为真实密钥,转换为目标模型的原生格式。

6. 流式回传:逐段转发给客户端,同时累积输出用于检测与计量。

7. 结算:用上游返回的 usage 修正预占量,写入计量与账单。

三、LLM Gateway 的核心能力:三段关键代码

能力一:流式代理

LLM Gateway 的核心代码,是一个"边收边发"的流式代理。下面是基于 Python 异步框架的示意:

python

async def proxy_stream(req, route):

   upstream = route.pick_endpoint()

   usage, first_token_at = None, None

   async with http.stream("POST", upstream.url,

                          headers=upstream.auth_headers(),

                          json=upstream.adapt(req.body)) as resp:

       async for line in resp.aiter_lines():

           if not line.startswith("data: "):

               continue

           payload = line[6:]

           if payload == "[DONE]":

               yield "data: [DONE]\n\n"

               break

           chunk = upstream.normalize(json.loads(payload))

           if first_token_at is None and chunk.has_content():

               first_token_at = now()          # 记录首字时间

           if chunk.usage:

               usage = chunk.usage              # 末尾的用量

           yield f"data: {json.dumps(chunk.to_dict())}\n\n"

   await settle(req.consumer, usage)           # 按真实用量结算

这段代码中有三个值得注意的工程点:上游连接要设置合理的读超时(按两次数据块之间的间隔,而不是整次请求时长);客户端中途断开时要及时取消上游请求,否则会继续产生费用;如果上游没有返回 usage,需要用本地分词器估算并标记为估算值。

能力二:Token 限流——预占与结算

按请求数限流对 LLM 几乎没有意义,一个 10 万 Token 的请求和一个 100 Token 的请求成本相差上千倍。LLM Gateway 通常按每分钟 Token 数(TPM)做令牌桶限流,但输出 Token 数在请求时未知,所以要分两步:

python

def reserve(consumer, est_input, max_tokens):

   need = est_input + max_tokens          # 按最坏情况预占

   if not bucket[consumer].try_take(need):

       raise RateLimited(retry_after=bucket[consumer].wait_time(need))

   return need

def settle(consumer, reserved, usage):

   actual = usage.prompt_tokens + usage.completion_tokens

   bucket[consumer].refund(reserved - actual)   # 多退

   meter.record(consumer, usage)

预占按"输入预估 + max_tokens"计算,结算时退回多占的部分。如果应用不设置 max_tokens,网关应给一个默认上限,否则预占量会过大,导致限流过早触发。多实例部署时,令牌桶状态放在 Redis 等共享存储中,用原子操作完成预占与退还。

能力三:回退——只在首个 Token 之前

流式场景下的重试有一个硬约束:一旦已经向客户端输出了内容,就不能再透明地切换到另一个模型,否则用户会看到两段拼接在一起的回答。所以回退逻辑是:

python

for endpoint in route.fallback_chain():

   try:

       stream = await open_stream(endpoint, req)

       first = await asyncio.wait_for(stream.first_chunk(), timeout=ttft_timeout)

       return chain_stream(first, stream)    # 首个数据块到达后不再切换

   except (UpstreamError, asyncio.TimeoutError, RateLimited):

       metrics.fallback.inc(endpoint.name)

       continue

raise AllEndpointsFailed()

首字超时(ttft_timeout)是这里的关键参数,设得太短会误判正常的长提示词请求,设得太长会让用户等待过久,建议按模型和提示词长度分档设置。

四、LLM Gateway 的缓存:精确缓存与语义缓存

精确缓存 以请求的规范化内容(模型、消息、关键参数)的哈希作为键,命中条件严格,适合重复的系统调用、批处理任务。

语义缓存 把用户问题转为向量,与历史问题做相似度比较,超过阈值即返回历史答案。它能覆盖"同一个问题的不同问法",但阈值的选择是一个权衡:阈值太低,会把意思不同的问题当成相同;太高则命中率低。实践中常见的做法是按场景分别设置阈值、只对无个性化上下文的问答启用、为缓存条目设置过期时间,并抽样评估缓存答案的正确率。

此外还要区分网关缓存与模型厂商的提示词缓存:后者在模型侧对相同的长前缀给予计价折扣,网关能做的是保持系统提示词和检索内容的前缀稳定,以提高命中率。

五、LLM Gateway 的部署架构:在 Kubernetes 上运行

LLM Gateway 在 Kubernetes 上的部署架构

一个典型的生产部署包含:

  • 网关 Pod(无状态,多副本):处理请求,按 CPU 与并发连接数做水平扩缩。
  • Redis:存放限流计数、精确缓存和会话状态。
  • 向量库:语义缓存(可选)。
  • PostgreSQL:存放配置、虚拟密钥、计量与账单数据。
  • OpenTelemetry Collector:汇总指标与链路,转发到监控平台。

容量规划:并发连接比 QPS 更重要

LLM Gateway 的瓶颈通常不是 CPU,而是长连接数量。用利特尔法则估算:

text

并发流数 = 请求到达率 × 平均请求时长

示例估算:50 请求/秒 × 20 秒 = 1000 条并发流

1000 条并发流意味着网关要同时保持约 1000 个客户端连接和 1000 个上游连接。规划时要关注:每个 Pod 的连接数上限与内存占用、负载均衡器和入口控制器的空闲超时(必须大于流式请求可能的最长间隔,否则长回答会被中途切断)、滚动发布时的优雅终止时间(要足够让存量流完成)。

部署位置

应用集中在一个云上时,网关与应用同集群部署即可;应用和模型分布在多云、多地域时,可以按地域部署多套数据面、共享一个控制面,并关注网关到模型服务之间的网络时延。对 Prompt 内容不能出企业网络的场景,也有把网关数据面私有化部署在企业接入层的做法,例如犀思云私有 AI 网关将脱敏与审计放在企业本地接入设备上完成。

附:数据来源与参考资料

  • stream_options.include_usage 与 SSE data: [DONE](来源:OpenAI 兼容接口文档)
  • 利特尔法则 L = λW(来源:排队论通用结论)
  • 私有AI网关本地脱敏与审计(来源:犀思云官网产品资料)

说明:文中配置与代码为教学示意;时延、比例与容量为量级示意或示例估算,以实测为准;协议与法规以官方原文为准。

相关文章
|
1月前
|
人工智能 安全 Linux
MCP网关技术图谱2026:定义、工具接入、权限治理与落地策略一览
MCP网关是Agent工具调用的统一治理层,面向平台工程师、安全架构师与Agent开发者。它提供工具注册发现、身份认证、细粒度授权、调用审计与内容检测,解决“谁在调用、以谁身份、能做什么、做了什么”等核心问题,保障企业级Agent安全可控落地。(239字)
295 0
|
监控 前端开发 Java
事件驱动的奇迹:深入理解Netty中的EventLoop
事件驱动的奇迹:深入理解Netty中的EventLoop
1142 0
|
Web App开发 缓存 数据安全/隐私保护
解决浏览器自动填充用户名和密码最优雅的解决方案,优雅永不过时
浏览器记住用户名和密码并且自动填充怎么破?百度找的方法好像都不够优雅,优雅永不过时,今天我就带你优雅的解决这个问题。
4048 0
|
2月前
|
运维 安全 BI
中小团队终端安全与运维一体化建设:从资产盘点到边界管控的实施路径
本文针对中小团队IT人少、预算有限的现实,提出终端安全与运维一体化建设路径:分五步推进——先看清资产、再规范基线、后管控外设网络、继而远程提效、最终持续运营。强调用一套系统覆盖全场景,避免多工具叠加负担,每阶段独立见效,务实可行。
中小团队终端安全与运维一体化建设:从资产盘点到边界管控的实施路径
|
24天前
|
运维 安全 网络安全
企业异地组网怎么选?按规模分四档:从组网工具、VPN、SD-WAN 到专线的升级路径
企业异地组网无“最优解”,只有匹配站点规模与业务等级的分阶段方案:从免费组网工具(5人内)、自建IPsec(3–10站点),到SD-WAN(10–100站点),再到专线混合组网(核心/跨境场景)。成本重心随规模上升,从设备线路转向运维与中断损失。(239字)
158 0
|
2月前
|
缓存 自然语言处理 搜索推荐
多语言外贸网站的国际化架构:URL设计、hreflang信号与静态资源多区域加速的工程实践
2026 年再看多语言外贸网站,容易被低估的往往不是翻译工作量,而是国际化架构本身——URL 怎么设计搜索引擎才分得清语种、翻译后的静态资源怎么在多区域就近加速、hreflang 信号上线后怎么持续校验不退化。这篇不聊选型,只聊工程:把一个面向多语种市场的站点,从 URL 骨架、hreflang 双通道、静态资源多区域分发,到线上巡检这几块拆清楚,说清楚每一块在云上怎么落地。 一、URL 设计:子目录为主,权重收拢 多语种站点的 URL 结构有国家顶级域名、子域名、子目录三种。工程上对大多数团队,子目录是默认起点:example.
|
2月前
|
小程序 关系型数据库 数据库
外卖小程序对接的订单同步架构:从门店小票到美团饿了么的消息链路设计
2026 年再回看外卖小程序对接,真正难的从来不是“能不能把美团的单拉进来”,而是订单进来之后那一条看不见的消息链路:门店小票什么时候打、状态怎么在自家系统和平台之间双向流转、每天打烊后两边的账怎么对平。一次重复推送就可能让后厨出两份餐,一次对账遗漏就会让商家以为漏了单。这篇不聊选型,只聊工程——把订单表设计、幂等处理、消息队列解耦、小票图片存储、通知触达和定时对账这几块拆开,说清楚每一块的结构和一致性要求。存储侧我们用 RDS 承载订单业务数据,门店小票这类图片文件放 OSS,订单状态变动的通知走短信服务,每天的对账跑在函数计算上。
|
10月前
|
存储 人工智能 IDE
AI Coding 长文分享:如何真正把工具用起来,从原理到实践
本文从原理到实践系统地分享了如何高效使用AI编程工具。涵盖其底层机制(如Token计算、工具调用、Codebase索引与Merkle Tree)、提升对话质量的方法(如规则设置、渐进式开发)、实际应用场景(如代码检索、绘图生成、问题排查),并推荐了结合AI的编码最佳实践,包括文档、注释、命名规范和安全合规,旨在帮助不同经验水平的开发者真正把AI工具用好。
AI Coding 长文分享:如何真正把工具用起来,从原理到实践
|
人工智能 Java API
构建基于Java的AI智能体:使用LangChain4j与Spring AI实现RAG应用
当大模型需要处理私有、实时的数据时,检索增强生成(RAG)技术成为了核心解决方案。本文深入探讨如何在Java生态中构建具备RAG能力的AI智能体。我们将介绍新兴的Spring AI项目与成熟的LangChain4j框架,详细演示如何从零开始构建一个能够查询私有知识库的智能问答系统。内容涵盖文档加载与分块、向量数据库集成、语义检索以及与大模型的最终合成,并提供完整的代码实现,为Java开发者开启构建复杂AI智能体的大门。
6460 58