api-gateway · 项目介绍

api-gateway

本页由项目自动归档生成,源码与最新进展以 GitHub 仓库为准。

项目简介

一个用 Node.js 实现的本地 LLM API 网关,把 Anthropic、Moonshot、阿里云百炼(DashScope)、Ollama 等多家模型供应商聚合到同一套 OpenAI 兼容接口之下。网关提供三种路由模式(直接指定 / 自动 / 智能),并内置免费额度追踪与自动降级,适合需要在多个供应商之间灵活切换、避免供应商锁定的场景。

技术栈

维度 技术
主要语言/框架 Node.js(JavaScript / CommonJS,原生 http 模块,无 Express 等框架)
关键依赖/库 js-yaml(唯一运行时依赖,用于加载 YAML 配置)
数据存储 本地 JSON 文件 data/quota-state.json(无数据库,额度状态持久化到磁盘)
运行/部署方式 node src/index.js 或 npm start,默认监听 0.0.0.0:3000;要求 Node.js ≥ 18(依赖原生 fetch)

核心功能 / 亮点

  • 三种路由模式(src/server.js 统一分发):
    • 直接指定 — 通过 provider/model 复合键精确调用(src/router.js 同时支持复合键与纯模型名);
    • auto — 先按 auto_router.rules 规则匹配,再做能力矩阵评分(src/auto-router/index.js + feature-extractor.js);
    • smart — 调用一个小模型(默认 Moonshot)分析请求选模型(src/auto-router/llm-router.js,判断 prompt 来自 smart-router-prompt.md)。
  • 多供应商统一 OpenAI 兼容接口(src/proxy.js + src/adapters/openai.js、anthropic.js):按 protocol 分发,Ollama / 阿里云等 OpenAI 兼容供应商通过 extraBody 配置接入。
  • 免费额度管理(src/quota-tracker.js + src/usage-counter.js):从 model_capabilities 读取 quota(总量/到期时间),持久化到 data/quota-state.json,并按 urgency(剩余/剩余天数)优先消耗即将到期的额度。
  • 自动降级重试(src/server.js:MAX_RETRIES = 3 + src/router.js 的 findFallback):同供应商内按综合能力选备选模型;上游返回 429/403/400 且命中额度关键词时抛 QuotaExhaustedError 触发切换。
  • SSE 流式支持(src/proxy.js 的 handleStream):完整透传并解析流式响应中的 usage。
  • 配置与环境变量(src/config.js):YAML 配置支持 ${ENV_VAR} 环境变量替换,密钥可走环境变量而不落盘。

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
api-gateway/
├── src/
│ ├── index.js # 入口:加载配置、初始化额度追踪、启动 HTTP 服务
│ ├── server.js # HTTP 服务与路由分发(/v1/chat/completions 等)、降级重试主循环
│ ├── router.js # 模型名→provider 映射(provider/model 复合键)、备选模型查找
│ ├── proxy.js # 向上游转发、adapter 分发、SSE 流式、额度耗尽检测
│ ├── config.js # 读取 YAML 配置 + ${ENV_VAR} 替换
│ ├── quota-tracker.js # 免费额度追踪与持久化
│ ├── usage-counter.js # 从响应 usage 提取 token 并记账
│ ├── auto-router/
│ │ ├── index.js # auto 模式:规则匹配 + 能力矩阵评分
│ │ ├── feature-extractor.js # 从请求体提取特征(task/has_image/estimated_tokens…)
│ │ └── llm-router.js # smart 模式:调用小模型做路由决策
│ └── adapters/
│ ├── openai.js # OpenAI 兼容协议适配
│ └── anthropic.js # Anthropic 协议适配
├── data/
│ └── quota-state.json # 运行时额度状态(自动生成)
├── config.example.yaml # 配置样例(多供应商 / 能力矩阵 / 路由规则 / 额度)
├── config.yaml # 实际配置
├── smart-router-prompt.md # smart 模式路由 prompt
├── test-routing.js # 路由测试脚本
├── test-smart-routing.js # 智能路由测试脚本
├── package.json
├── LICENSE
└── README.md

相关链接

补充:三种路由模式背后的取舍

聚合多家模型供应商这件事,真正的难点不在「接进来」而在「选哪家」。这个网关给了三种路由模式,本质上是三档不同的成本/智能权衡:

  • provider/model 直接指定:最可控,适合你明确知道要用哪个模型的场景。复合键的设计让同一套接口能精确落到任意一个供应商的任意一个模型。
  • auto(规则匹配 + 能力矩阵评分):零额外开销。按预设规则和模型能力打分选最优解,不会为了「选模型」而多花一次调用。
  • smart(用一个 LLM 做路由决策,默认 Moonshot):多花一次小模型的钱,换来更高的路由准确率。适合请求意图复杂、规则难以覆盖的场景。

其他几个值得一提的点:

  • 统一 OpenAI 兼容接口是这个项目的价值核心:下游应用不用改一行代码就能换供应商,供应商锁定问题在网关层被消化掉了。
  • **路由 prompt 单独抽成 smart-router-prompt.md**:意味着 smart 模式的判断逻辑是可调的,而不是写死在代码里。换判断标准不用改程序。
  • 免费额度管理 + 自动降级:额度耗尽自动切下一家,这是「把各平台免费额度用到极致」这句话的实际实现路径——不是提醒你额度没了,而是自动找下一个能用的。
  • 流式支持:LLM 网关如果不支持 SSE 流式,用户体验会断崖式下降(等几十秒才看到第一个字)。这个必须在一开始就考虑,不能后补。