从零设计一个 AI API 网关:Key、限流、日志、计费、模型路由

API

不用现成方案,自己动手设计一个 AI 网关:请求怎么归一、Key 怎么收口、token 怎么计量、限流和计费怎么在流式响应里做、模型路由怎么落地。一篇把核心链路讲透,给出可落地的模块划分和数据结构。

上一篇《AI API 网关是什么》讲了为什么企业需要网关。这篇讲怎么自己造一个——不是因为造轮子比 LiteLLM、One API 更好,而是因为亲手设计一遍,你才真正理解网关在做什么、现成方案的每个配置项意味着什么、以及你的特殊需求该怎么塞进去。核心链路(转发 + 计量 + 限流 + 计费)其实一周能出可用版本,复杂的是细节。

本文按数据流顺序拆解每个模块的设计,给出关键数据结构。语言用 Node.js 示意,思路与语言无关。

数据中心的服务器与网络架构
数据中心的服务器与网络架构

一个 AI 网关的骨架:入口鉴权 → 路由 → 转发 → 流式计量 → 落账 → 日志。

整体数据流

先把一次请求经过网关的全过程画出来,后面每个模块对号入座:

应用
 │ 带虚拟 Key,OpenAI 兼容格式
 ▼
[1 鉴权]  校验虚拟 Key,取出所属应用/配额
 ▼
[2 限流]  查该应用的 token 预算是否还够
 ▼
[3 路由]  按模型名/策略选定上游厂商 + 真实 Key
 ▼
[4 转发]  翻译成厂商格式,发起请求(多为 SSE 流式)
 ▼
[5 计量]  边转发边统计 token,流结束得到总用量
 ▼
[6 计费]  按模型单价扣该应用余额/记账
 ▼
[7 日志]  异步落审计日志
 ▼
应用(拿到流式回答)

关键设计决定:计量和计费发生在响应流结束时,而限流的预检发生在请求前。这个「先放行、后结算」的时间差,是所有 AI 网关都要处理的核心难点。

模块一:请求归一,统一说 OpenAI 方言

让所有应用统一用 OpenAI 兼容格式/v1/chat/completions),网关内部再翻译成各厂商格式。这样应用换模型零改动。归一层要处理三件事:请求体字段映射(Anthropic 的 system 是独立字段、Gemini 的结构不同)、流式协议差异、错误码统一。

维护一份模型注册表作为路由和计费的单一数据源:

const MODELS = {
  "gpt-5":          { provider: "openai",    inPrice: 1.25, outPrice: 10, ctx: 400000 },
  "claude-fable-5": { provider: "anthropic", inPrice: 3,    outPrice: 15, ctx: 200000 },
  "deepseek-v3":    { provider: "deepseek",  inPrice: 0.27, outPrice: 1.1, ctx: 128000 },
  // 价格为每百万 token 美元,仅示意,以厂商实时定价为准
};

价格这类时效数据不要写死在代码里,应放配置中心或数据库,支持热更新——厂商调价是常态,改价不该发版。

模块二:Key 收口——虚拟 Key 与真实 Key 分离

这是网关的安全核心。厂商真实 API Key 只存在网关(加密存储),应用拿到的是网关签发的虚拟 Key。虚拟 Key 绑定一套元数据:

const virtualKey = {
  key: "sk-gw-xxxx",          // 发给应用
  appId: "team-growth",
  allowedModels: ["gpt-5", "deepseek-v3"],
  dailyBudgetUsd: 50,
  rateLimit: { rpm: 60, tpm: 200000 },
  status: "active",           // 可随时置为 revoked
};

好处立竿见影:某个 Key 泄露,一键吊销且不影响其他应用;能按应用限制可用模型和预算;所有调用可归因到具体应用。真实 Key 的轮换在网关内部完成,应用无感知。

模块三:限流与配额——按 token 而非请求数

大模型请求的成本方差极大,按请求数限流没有意义。要做两层:

  • 频率限流:RPM(每分钟请求数)和 TPM(每分钟 token 数),用滑动窗口或令牌桶,热数据放 Redis;
  • 预算配额:按应用/用户的日或月 token 预算,超了拒绝。

难点在于请求前你不知道会消耗多少 token(尤其输出)。实用做法是「预扣 + 结算」:请求前按 max_tokens 预估上限做一次预检(预算明显不够就直接拒),响应结束拿到真实用量后回补差额。这能防住「余额还剩一点却放行了一个天价请求」的漏洞。

监控面板上的实时流量曲线
监控面板上的实时流量曲线

限流按 token 算:一个请求可能是另一个请求成本的上千倍,请求数维度毫无意义。

模块四:流式计量——最容易翻车的地方

绝大多数请求是流式(SSE)的,网关必须边转发边统计,不能等全部收完——那样首字延迟会毁掉体验。设计要点:

  • 网关作为流的「中间人」,从上游读一块、转一块给应用,同时累加 token;
  • 输入 token 在请求时就能算(或从上游首包的 usage 拿);输出 token 边流边数,多数厂商会在流末尾的 usage 字段给出准确值,优先用它,拿不到再用分词器估算;
  • 必须处理中断:应用断开连接、上游超时,都要把已消耗的部分计入——半截请求也烧了钱。这一点最常被漏掉,导致计费漏账。
// 伪代码:流式转发中计量
let outputTokens = 0;
for await (const chunk of upstreamStream) {
  client.write(chunk);              // 先转发,保证低延迟
  outputTokens += countChunk(chunk);
  if (chunk.usage) usage = chunk.usage; // 优先用上游准确用量
}
// 无论正常结束还是异常中断,finally 里都要结算
settle(appId, model, inputTokens, usage?.output ?? outputTokens);

模块五:计费与日志

计费就是拿最终用量套模型注册表的单价:成本 = 输入token×inPrice + 输出token×outPrice。用了 Prompt Caching 的话,缓存命中部分单价不同,要单独计。落账要保证原子性(并发请求扣同一应用余额),用数据库事务或 Redis 原子操作。

日志分两类:计费流水(必须可靠、可对账,同步写或走可靠队列)和审计日志(请求/响应内容、用于合规排查,量大,异步写、可采样、注意脱敏)。两者别混在一张表里。

工程师查看系统日志与账目
工程师查看系统日志与账目

计费流水和审计日志分开:一个要求准确可对账,一个要求全量可追溯,性质完全不同。

模块六:模型路由

有了统一入口,模型路由就是一层策略。从简到繁:

  1. 别名路由:应用请求 default-fast,网关映射到当前选定的具体模型。换模型只改映射;
  2. 故障切换:上游返回 5xx 或超时,自动重试到备用厂商(注意幂等和重复计费问题);
  3. 灰度:新模型按百分比分流,观察指标再放量;
  4. 成本路由:按请求特征(长度、任务类型)路由到不同档位模型——收益诱人但容易误判,建议先人工规则、留好开关,别一上来就上「智能路由」。

路由策略应可配置、可灰度、可回滚,不要硬编码在转发逻辑里。

落地节奏与常见坑

别一步到位。 第一版只做模块 1/2/5 的最小集:虚拟 Key 鉴权 + 用量记录 + 基础日志,先让「所有流量过网关且能算清账」跑通。路由、缓存、审计按真实需求逐步加。

高频坑清单:

后果对策
流式中断不结算计费漏账finally 里无条件结算已消耗部分
价格写死在代码厂商调价要发版价格进配置,热更新
网关无降级网关挂 = 全公司 AI 挂多实例 + 关键应用直连兜底开关
审计日志同步写拖慢转发延迟异步队列,采样,脱敏
重试导致重复计费成本虚高重试带幂等键,只对真实产生的调用计费

适用人群与替代方案

适合有特殊计费/路由/合规需求、或把网关本身当产品做的团队。大多数团队不该自建——LiteLLM、One API 系开源方案已经把上述模块做得很完善,直接用能省下数周。自建只在三种情况成立:现成方案的计费模型不匹配你的业务(如要按客户多级分账)、有强合规定制、或网关是你要卖的东西。即便自建,也建议先读现成方案的源码,它们踩过的坑就是你的设计检查表。

常见问题

Q:语义缓存要不要放进第一版? A:不要。缓存能省钱,但涉及「什么算相同请求」「缓存多久」等一堆判断,且对话类场景命中率低。先把主链路做稳,缓存作为独立优化项后加。

Q:网关自己会不会成为延迟瓶颈? A:设计得当的话,网关增加的是毫秒级开销,相对秒级的模型生成可忽略。真正要防的是网关的可用性——它是单点,稳定性要求高于任何单个应用。

Q:多租户怎么隔离? A:虚拟 Key 就是隔离边界。每个 Key 绑定独立的模型白名单、预算、限流、日志空间;计费按 Key 聚合。租户间不共享真实 Key,也看不到彼此用量。

小结

一个 AI 网关的核心,是把「先放行、后结算」这条流式链路做对:请求前预检限流,转发中低延迟计量,结束时准确计费,异常时不漏账。虚拟 Key 收口安全、模型注册表统一路由和计费、日志分层。想清楚这几件事,无论自建还是用现成方案,你都能把网关这层基础设施握在自己手里。