作者总结自研LLM Gateway的四个核心决策:JWT+RBAC认证、模型别名路由+配额+故障转移、用量计费,以及异步控制面管理模型注册表和预算。
你的团队现在是把服务直接硬编码连到提供商的 API 上。每个应用都有自己的 API Key、自己的重试逻辑、自己写死的模型名称。没人能回答"我们这个月在 LLM 上花了多少钱",当某个模型被弃用时,你只能通过生产环境里的 500 错误才知道。
这几年我一直从事 LLM 基础设施工作,最终反复回归的模式是自建 LLM 网关:一个无状态的代理加一个小的控制面。不是"AI 平台"——只是一个枯燥但可靠的层级。下面是在生产环境中真正重要的四个决策。
flowchart LR
subgraph Clients
A[Service A<br/>team: payments]
B[Service B<br/>team: growth]
H[Developer<br/>IDE / CLI]
end
subgraph GW["LLM Gateway (stateless)"]
AUTH[Auth: JWT, RBAC]
ROUTE[Routing: alias, quotas, failover]
METER[Metering: usage, cost]
end
subgraph CP["Control plane (async)"]
REG[Model registry: aliases, prices]
Q[Quotas / budgets]
end
subgraph Providers
PA[Provider A]
PB[Provider B]
end
A -->|short-lived JWT| AUTH
B -->|short-lived JWT| AUTH
H -->|user token, OBO| AUTH
AUTH --> ROUTE --> PA
ROUTE --> PB
ROUTE -.-> REG
PA -->|usage| METER
PB -->|usage| METER
METER --> BUS[(message bus)] --> ROLL[(rollups)] --> DASH[Dashboards + alerts]
一个控制面,一个数据面。 人类修改的所有东西(注册表、角色、预算、价格)都放在控制面。代理是无状态的,只读取控制面的状态。
一切皆可计量。 如果一个请求没有产生计量事件,它就没有发生。计量事件和 HTTP 响应一样真实。
请求中不放密钥。 线路上唯一的凭证是短期身份令牌。提供商凭证永远不会离开网关的密钥视图。
用枯燥的技术。 一种语言,一种消息格式,一种流。网关的职责是成为你架构中最无聊的组件。
负载路径:客户端 → 认证 → 路由 → 提供商 → 流式返回 → 计量 → 消息总线 → 聚合 → 仪表盘 → 告警。控制面永远不在热路径上;它写入状态,网关以较短的 TTL(1-5 秒即可)获取变化。
锁定是悄悄发生的。某天提供商弃用了一个模型名称,你的服务就挂了。解决方案是一个带别名的模型注册表:
两张表,一个定时任务。没有微服务森林。
每个请求都会产生一个使用对象:输入/输出的 tokens、模型、别名、团队、用户。
使用事件发送到持久化的消息总线;聚合任务将它们汇总到 per-model / per-tenant / per-user 表。
预算是计数器(Redis)加策略(SQL),在每个团队和每个模型的月度预算达到 80% 和 100% 时告警。
聚合 DB 可以有延迟,但不能丢失数据。从总线重新计算。
一旦这套机制建立起来,"这个功能要花多少钱?"就不再是产品会议讨论的问题,而是一个仪表盘查询。
如果 Agent 或工具要调用模型,它们应该通过同一个网关来对话,用 Model Context Protocol(MCP)作为稳定接口。一个端点,任何提供商在背后。网关成为你公司里唯一知道今天到底是哪个提供商在提供服务的地方。
一个无状态服务加定时同步任务。没有编排框架,没有第二个数据库。其他所有东西(portal、per-user 预算、细粒度 failover)都可以后续添加而不破坏边界。
我把所有学到的写成了一本书——参考架构、配置详解、操作手册和生产发布清单:The AI Gateway Playbook(32,000 字,$19,PDF + 图表)。收益会继续支持这类写作。
如果你正在构建一个 LLM 网关(或者你已经有了那个满是 API Key 和写死模型名的烂摊子),你遇到的最难的生产问题是什么?我很想听听。