我写了一个轻量 AI 网关库,多模型路由 + 自动降级 + 预算控制,一个包全搞定

路由、降级、限流、成本控制------调多个 LLM 必须解决的四个问题,一个零依赖 TypeScript 库搞定。
背景:调 AI 接口为什么越来越像运维
你的项目一开始只用 OpenAI,一个 fetch 搞定。后来产品说"Claude 写文案更好",加一个 Provider。再后来"GPT-4 太贵了,简单任务用 mini",加路由逻辑。然后有天 OpenAI 429 了------整个服务挂了。
于是你的代码变成了这样:
typescript
async function callAI(messages, taskType) {
if (taskType === 'copywriting') {
try {
return await callAnthropic(messages);
} catch (e) {
return await callOpenAI(messages); // 降级
}
} else if (taskType === 'chat' && user.tier === 'free') {
return await callOpenAI(messages, 'gpt-4o-mini'); // 省钱
} else {
return await callOpenAI(messages, 'gpt-4o');
}
// 还要加预算检查、重试、日志、超时......
}
这段代码有几个问题:
- 路由逻辑硬编码------加个 Provider 要改代码、重新部署
- 降级是 try-catch 嵌套------三层降级链写出来想吐
- 没有预算控制------凌晨跑了个 bug 循环,早上起来账单 $200
- 没有统一日志------出了问题翻三个 Provider 的日志找原因
这些不是"高级需求",是每个调多模型的项目必须解决的基础设施。
所以我做了 ai-gateway-lite------一个轻量级 AI 网关库,用 JSON 配置替代硬编码,一个包解决路由、降级、预算、日志四个问题。
bash
npm install ai-gateway-lite
它能做什么
多模型路由
用 JSON 配置路由规则,按 taskType、feature、userTier 灵活分发请求:
json
{
"rules": [
{
"name": "premium-complex",
"priority": 100,
"match": { "taskType": "complex", "userTier": "premium" },
"target": { "provider": "anthropic-main", "model": "claude-sonnet-4-20250514" }
},
{
"name": "default-chat",
"priority": 10,
"match": {},
"target": { "provider": "openai-main", "model": "gpt-4o-mini" }
}
]
}
优先级匹配------VIP 用户走 Claude,普通用户走 Mini,一行代码不用改。
自动降级
Provider 挂了?自动切换到下一个:
json
{
"name": "complex-fallback",
"steps": [
{ "provider": "anthropic-main" },
{ "provider": "openai-main", "model": "gpt-4o", "when": ["timeout", "provider_error"] },
{ "provider": "openrouter-fallback", "when": ["timeout", "rate_limit", "provider_error"] }
]
}
降级触发条件可以精确控制------只有 timeout 和 provider_error 才降级,budget_exceeded 不降级(钱不够就别换个更贵的)。
预算控制
怕跑飞?设个每日上限:
json
{
"name": "global-daily",
"scope": { "type": "global" },
"window": "day",
"limits": { "maxTotalTokens": 1000000, "maxCostUsd": 10.0, "warnAt": 0.8 },
"enforcement": "hard"
}
hard模式:超了直接拒绝soft模式:超了告警,但还是放行warnAt: 0.8:用到 80% 时就开始告警
流式输出
SSE 流式响应,所有 Provider 统一接口:
typescript
const stream = await gateway.chatStream({
messages: [{ role: "user", content: "写一首关于 TypeScript 的诗" }],
});
for await (const chunk of stream.stream) {
process.stdout.write(chunk.delta);
}
const summary = await stream.getUsageSummary();
console.log(`Tokens: ${summary.totalTokens}, Cost: $${summary.estimatedCostUsd.toFixed(4)}`);
成本估算
每次请求自动计算费用,内置 OpenAI / Anthropic 主流模型定价表:
typescript
const res = await gateway.chat({
messages: [{ role: "user", content: "Hello!" }],
});
console.log(res.estimatedCostUsd); // 0.0001
自定义模型?注册一下就行:
typescript
import { registerModelPricing } from "ai-gateway-lite";
registerModelPricing("my-model", {
inputPer1kTokens: 0.001,
outputPer1kTokens: 0.002,
});
30 秒上手
bash
# 1. 安装
npm install ai-gateway-lite
# 2. 配 Key
export OPENAI_API_KEY=sk-xxx
typescript
import { Gateway, loadConfigFromObjects } from "ai-gateway-lite";
const config = loadConfigFromObjects({
providers: [
{
name: "openai",
provider: "openai",
models: ["gpt-4o-mini"],
auth: { type: "apiKey", envVar: "OPENAI_API_KEY" },
},
],
routes: {
rules: [{ name: "default", priority: 0, match: {}, target: { provider: "openai" } }],
},
budgets: [],
});
const gateway = new Gateway({ config });
const res = await gateway.chat({
messages: [{ role: "user", content: "Hello!" }],
});
console.log(res.content);
console.log(`Cost: $${res.estimatedCostUsd.toFixed(4)}`);
不想写代码先试试?clone 下来跑 demo:
bash
git clone https://github.com/hyxnj666-creator/ai-gateway-lite.git
cd ai-gateway-lite && npm install
cp .env.example .env # 填上你的 API Key
npm run demo
访问 http://localhost:3170,三个接口直接能用:
| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/v1/chat |
非流式对话 |
POST |
/v1/chat/stream |
SSE 流式对话 |
GET |
/health |
健康检查 + Provider 列表 |
核心设计决策
为什么用 JSON 配置而不是代码
路由规则、降级链、预算策略------这些应该是运维配置,不是代码逻辑。
用 JSON 配置意味着:
- 不改代码就能调整路由------"Claude 涨价了,简单任务切到 Mini",改 JSON 重启就行
- 配置可以版本管理------谁改了什么一目了然
- 可以动态加载------未来支持从远程配置中心读取
当然,如果你嫌建配置文件麻烦,loadConfigFromObjects() 直接传对象也行。
为什么零运行时依赖
Node.js 18+ 自带 fetch、ReadableStream、TextDecoder------调 HTTP API 需要的东西全有了。
不依赖 openai、@anthropic-ai/sdk 等官方 SDK 意味着:
- 体积小------整个包 47KB(minified)
- 不会被 SDK 更新 break------直接对接 REST API,接口稳定
- 支持任何 OpenAI 兼容的 Provider------DeepSeek、Groq、Together 都能通过 OpenRouter 或自定义 Provider 接入
为什么只重试特定状态码
重试逻辑只对 429(限流)、502、503、504(后端故障)和网络超时进行重试,其他错误直接报错。
原因是:
- 400(参数错误)------重试也没用
- 401/403(鉴权失败)------重试也没用
- 500(内部错误)------可能重试有用,但 500 通常意味着逻辑 bug,盲目重试可能加重问题
指数退避 + 可配置重试次数:
json
{
"retry": { "maxAttempts": 3, "backoffMs": 1000 }
}
首次等 1s,第二次 2s,第三次 4s。避免雪崩。
架构一览
bash
请求进来
│
├── 路由匹配(taskType / feature / userTier → 最高优先级规则)
│
├── 预算检查(超限?hard → 拒绝 / soft → 告警放行)
│
├── 执行请求
│ ├── 成功 → 返回
│ └── 失败 → 分类错误(timeout / rate_limit / provider_error)
│ └── 触发降级链 → 下一个 Provider
│
├── 记录用量(token / 费用 / 延迟)
│
└── 返回 GatewayResponse(含 estimatedCostUsd)
内置 Provider
| Provider | 流式 | 认证方式 |
|---|---|---|
| OpenAI | ✅ | Bearer token(OPENAI_API_KEY) |
| Anthropic | ✅ | x-api-key(ANTHROPIC_API_KEY) |
| OpenRouter | ✅ | Bearer token(OPENROUTER_API_KEY) |
需要接其他 Provider?实现 Provider 接口即可:
typescript
class MyProvider implements Provider {
readonly name = "my-provider";
readonly family = "custom";
async chat(options: ProviderRequestOptions): Promise<ProviderResult> {
// 你的实现
}
}
const gateway = new Gateway({
config,
customProviders: {
custom: (config) => new MyProvider(),
},
});
错误处理
所有错误统一为 GatewayError,带结构化字段:
typescript
import { GatewayError } from "ai-gateway-lite";
try {
await gateway.chat(request);
} catch (err) {
if (err instanceof GatewayError) {
console.log(err.kind); // "provider_timeout" | "provider_rate_limit" | "budget_exceeded" | ...
console.log(err.httpStatus); // 504, 429, etc.
console.log(err.retryable); // true / false
}
}
HTTP 状态码自动分类:
| 状态码 | 分类 | 可重试 |
|---|---|---|
| 401/403 | provider_auth |
❌ |
| 429 | provider_rate_limit |
✅ |
| 408/504 | provider_timeout |
✅ |
| 500 | provider_error |
❌ |
| 400 | provider_response |
❌ |
和同类方案的对比
| 维度 | ai-gateway-lite | LiteLLM | Portkey |
|---|---|---|---|
| 形态 | npm 包,嵌入应用 | Python 服务 | SaaS + SDK |
| 语言 | TypeScript | Python | 多语言 |
| 运行时依赖 | 0 | 大量 | SDK 依赖 |
| 路由配置 | JSON 声明式 | 代码/YAML | Dashboard |
| 降级链 | ✅ 多步骤 + 条件触发 | ✅ | ✅ |
| 预算控制 | ✅ 内置 | 有限 | ✅ |
| 流式 | ✅ SSE | ✅ | ✅ |
| 成本追踪 | ✅ 内置定价表 | ✅ | ✅ |
| 部署 | 无需部署,库引用 | 需部署服务 | 第三方 SaaS |
| 开源 | MIT | MIT | 部分开源 |
| 包大小 | 47KB | - | - |
核心差异 :ai-gateway-lite 是嵌入式的------不需要额外部署一个网关服务,npm install 进项目直接用。适合中小团队或个人项目,不想多维护一个服务的场景。
适用场景
- SaaS 产品------按用户等级分配不同模型,VIP 走 GPT-4,免费用户走 Mini
- AI 应用后端 ------统一网关层,不管接几个 Provider 都是一个
gateway.chat() - 成本敏感项目------设好每日预算,再也不怕凌晨跑飞
- 高可用场景------主 Provider 挂了自动切备用,用户无感知
开源地址
- npm : ai-gateway-lite
- GitHub : hyxnj666-creator/ai-gateway-lite
- License: MIT
bash
npm install ai-gateway-lite
84 个测试,TypeScript strict 模式,Node.js 18/20/22 全版本 CI 通过。
如果对你有帮助,给个 ⭐ 或者掘金点个赞,是我继续迭代的动力。
有问题或建议欢迎提 issue 或评论区交流。