LLM API Gateway — 聚合多提供商的统一网关

背景

日常开发中需要切换使用多个 LLM 提供商(Anthropic Claude、Moonshot Kimi、阿里云通义千问、本地 Ollama),每个提供商的 API 格式和认证方式不同。这个网关将所有提供商聚合到一个 OpenAI 兼容接口下,并提供智能路由能力。

架构

1
2
3
4
5
6
7
8
客户端(OpenAI SDK / curl)
↓ POST /v1/chat/completions
LLM API Gateway (Node.js, 端口 3000)
↓ 路由决策
├── Anthropic API (Claude Opus/Sonnet/Haiku)
├── Moonshot API (Kimi)
├── DashScope API (Qwen 系列)
└── 本地 Ollama (llama, gemma, mistral...)

三种路由模式

Direct 模式

客户端直接指定 provider:model:

1
2
3
4
{
"model": "anthropic:claude-sonnet-4-6",
"messages": [...]
}

网关只做协议转换,将 OpenAI 格式转为对应提供商的 API 格式。

Auto 模式

不指定 provider 时,自动匹配:

  1. 先查规则表(auto-router.rules),按精确/前缀匹配模型名
  2. 未命中则用能力矩阵评分:对每个能处理多轮对话 + 支持中文的模型,按优先级排序
  3. 返回最佳匹配
1
2
3
4
5
6
7
8
9
# config.yaml 能力矩阵示例
auto-router:
capability_matrix:
- models: ["claude-sonnet-4-6"]
capabilities: ["multi-turn", "chinese", "reasoning", "long-context"]
priority: 10
- models: ["kimi-latest"]
capabilities: ["multi-turn", "chinese", "long-context"]
priority: 7

Smart 模式

由路由模型(router model)分析用户 prompt 的复杂度,决定用哪个模型:

1
2
3
4
5
6
7
smart-router:
model: "claude-haiku-4-5"
routes:
- match: "simple translation or Q&A"
model: "ollama:qwen2.5:7b"
- match: "complex reasoning or code generation"
model: "anthropic:claude-sonnet-4-6"

配额追踪

每个提供商可能有免费配额(如 Moonshot 每月免费 100 万 token)。网关自动追踪用量:

  • 请求时检查配额,耗尽后从路由表中移除该模型
  • 配额按自然月重置
  • 状态持久化到 data/quota-state.json
1
2
3
4
5
6
7
8
// quota-tracker.js 核心逻辑
check(model) → ENTRY
if expired → reset
if exhausted → return false (排除)
return true (可用)

record(model, tokens) → ENTRY
累计用量并持久化

技术选择

  • 原生 http 模块:不依赖 Express/Koa,减少依赖和启动时间
  • YAML 配置js-yaml 加载,可读性比 JSON/JS 好
  • 环境变量注入 API Key:避免敏感信息写入配置文件

运行

1
2
3
4
5
cd NodejsProj/api-gateway
npm install
cp config.example.yaml config.yaml
# 编辑 config.yaml,通过 ${ENV_VAR} 引用 API key
npm start # 端口 3000
🤖 AI 博客助手
你好!我是博客 AI 助手,可以回答关于博客文章内容的问题。试试问我吧~