LLM Gateway:把多家模型供应商收进一个 OpenAI 兼容端点
Route, manage, and analyze your LLM requests across multiple providers with a unified API interface.
秒懂
- 它是什么?
- 它用 TypeScript 写了一个中间层,把 OpenAI、Anthropic、Google Vertex AI 等供应商的调用、密钥、用量与费用统一到一套接口和一套账目里。判断它的关键不在功能列表,而在自托管时的部署约束和 ee/ 目录那道许可分界线。
- 适合谁用?
- 如果你的团队已经在两个以上模型供应商之间来回切换,并且需要一份跨供应商的 token 与费用账目,同时能接受 AGPLv3 对自托管衍生代码的约束,LLM Gateway 值得先在测试环境跑通一次统一镜像。反过来,只调用单一供应商、或者把数据驻留和审计要求写进合同里的团队,先别急着上:ee/ 目录之外的功能边界、30 天数据保留上限、以及 multi-organization administration 需要 white-label 授权这几条,都应该在动手之前对着 LICENSE 与 ee/LICENSE 逐条确认。
- 能商用吗?
- 请先确认。这个仓库使用的许可证不在我们自动归类的范围内,商用前请阅读仓库里的 LICENSE 文件。
- 还在维护吗?
- 在维护。仓库在最近一天内有新的提交。
- 用什么语言写的?
- 主要是 TypeScript(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决的是密钥和账目散落的问题
一个应用同时调用 OpenAI 和 Anthropic,最先失控的通常不是代码,而是运维面。每个供应商一套 API key,每个 key 一套配额和计费口径,日志分散在各自的 dashboard 里。想知道这个月哪条产品线烧了多少钱、哪个模型的响应时间在退化,得手工把几份账单拼起来。
LLM Gateway 的定位就是插在应用和供应商之间的中间层。README 把它描述为 middleware,并列出四件事:把请求路由到多个供应商、集中管理各家的 API key、跟踪 token 用量与成本、分析性能指标。目标读者是那些已经把多供应商当成常态、而不是偶尔做一次模型对比的团队。
它提供的接口与 OpenAI API 格式兼容,README 用 seamless migration 形容这一点。对已经在用 OpenAI SDK 的代码库来说,迁移成本主要是改 base URL 和 key,而不是重写调用层。这是它最实际的卖点,也是它必须背上的包袱:兼容意味着要长期跟随上游格式变化。
请求从网关到供应商的路径
从仓库结构能看出它的分层意图。apps/gateway 是负责路由 LLM 请求的网关,apps/api 是 Hono 写的后端,两者分开,说明转发路径和管理面(账号、密钥、计费)不是同一个进程。packages/models 存放模型与供应商的定义,这是路由决策的数据来源;packages/db 用 Drizzle ORM 管理 schema 和迁移。
请求的形态可以直接从 README 的示例读出:向 /v1/chat/completions 发一个 POST,带 Authorization: Bearer 的网关 key,body 里指定 model 和 messages。也就是说,客户端只认网关这一层,具体落到哪家供应商由网关根据 model 字段和 packages/models 里的定义决定。
这里有一个对自托管用户很关键的推论:模型与供应商的映射关系是代码里的数据,不是运行时配置。新增一个供应商或模型,走的是改 packages/models 再部署的路径,而不是在界面上填个表单。对希望快速试新模型的团队,这个节奏偏慢;对希望变更经过代码评审的团队,这反而是优点。README 没有说明路由是否支持按成本或延迟自动选择,只说可以 compare different models' performance and cost-effectiveness,所以自动选路这件事不应被假定存在。
两条上手路径:托管与自托管
README 给了两种用法。托管版是去 llmgateway.io 注册账号拿 API key,适合先验证接口是否合口味。自托管版面向需要控制数据和配置的团队,官方推荐用统一镜像。
自托管的第一步是生成两个密钥。README 的脚本用 openssl rand -base64 32 生成 LLM_GATEWAY_SECRET 和 GATEWAY_API_KEY_HASH_SECRET,前者对应容器里的 AUTH_SECRET,后者用于网关 API key 的哈希。之后执行 ./scripts/run-unified-container.sh 即可。
如果不想用脚本,README 也给了一次性 docker run 的写法,镜像地址是 ghcr.io/theopenco/llmgateway-unified:latest,映射了 3002、3003、3005、3006、3007、4001、4002 七个端口,说明这个统一镜像里同时跑着 UI、API、网关等多个进程。
这里有一条 README 特意强调的约束:不要用宿主机目录 bind-mount 到 /var/lib/postgresql/data。原因是容器内的 PostgreSQL 初始化需要对该目录设置权限,在部分宿主文件系统与属主组合下会失败。正确做法是使用 Docker 管理的命名卷,例如先 docker volume create llmgateway_postgres 与 llmgateway_redis,再挂载。这条约束很容易被忽略,因为大多数自托管教程默认你会 bind-mount 一个数据目录。
开发模式则是另一套:pnpm i && pnpm run setup 会装依赖、起 Docker 服务、同步数据库 schema 并灌入初始数据,然后 pnpm dev 启动开发服务器,pnpm build 做生产构建。README 单独提示 WSL2 用户要确保 Docker Desktop 开启了 WSL 集成。
仓库里不止一个应用
文件夹结构透露的信息比功能列表多。apps/ui 是 Next.js 仪表盘,apps/api 是 Hono 后端,apps/gateway 是 LLM 请求网关,这三者是核心。此外还有 apps/playground(一个叫 Lounge 的消费级聊天应用)、apps/code(面向编码工具的落地页与仪表盘)、apps/airside(一个叫 Airside 的供应商自助门户)、apps/docs 以及 ee/admin 内部管理后台。
对评估者来说,这意味着两件事。第一,仓库的体量比一个纯网关大得多,构建和依赖管理的成本相应更高;如果你只想拿网关那一块,需要自己判断哪些 app 可以裁掉,README 没有提供裁剪指南。第二,apps/airside 的存在暗示这个项目同时在做供应商侧的自助接入,也就是它不只是一个自用工具,还有平台化的意图。
packages/shared 存放共享类型与工具,跨 app 复用。这个布局在 TypeScript 单体仓库里很常见,代价是任何一次 schema 变更都可能牵动多个 app。
许可分界线在 ee/ 目录
README 明确写了双许可。核心功能是 AGPLv3,ee/ 目录下的商业功能需要 Enterprise 授权,并且 multi-organization administration 需要 white-label 授权。
这条线画得很直接:以目录为界。判断某个功能是否属于开源部分,看它在不在 ee/ 下面即可。但 README 对 ee/ 功能的列举用了 and more to be defined 这样的措辞,也就是说企业功能的清单还在变动。对打算长期依赖某个具体能力(比如自定义供应商密钥配置)的团队,这是一个需要留意的信号:今天是企业功能,明天是否还在同一侧,README 没有承诺。
AGPLv3 的实际含义需要结合部署方式看。自托管一个 AGPLv3 的网关,涉及的是向网络用户提供服务的场景,衍生代码的开放义务是否触发,取决于你改了什么、怎么部署。这里不给出法律判断,只提醒一句:如果计划在网关上做私有改动再对外提供服务,应该先让法务看 LICENSE 和 ee/LICENSE 两份文件,而不是照搬「自托管就等于随便用」的经验。
README 没有说明托管版与自托管版在功能上是否完全一致,也没有说明自托管版是否包含 ee/ 下的能力。这是评估时必须直接向项目方确认的一条。
数据保留与功能边界是最大的未知数
README 在企业功能里写了一条对比:extended data retention (unlimited vs 30 days)。按字面理解,非企业部署的数据保留期是 30 天。对用量分析来说,这个上限决定了你能回溯多久的成本趋势,也决定了年度预算复盘能不能在网关里直接做完。如果你的团队需要跨季度对比模型成本,30 天是不够的,这一点在选型早期就该确认清楚,而不是等数据被清掉之后才发现。
第二个限制来自托管版的形态。托管版是把请求经过项目方的服务器转发给供应商,密钥和数据都过第三方。README 没有提供托管版的合规材料、数据驻留选项或子处理者列表。对金融、医疗这类有明确数据出境或驻留要求的场景,托管版基本可以直接排除,只能走自托管。
第三,README 提到的 guardrails 和 rate-limiting 只出现在仓库的 topics 里,正文的功能列表没有展开。topics 是仓库标签,不是功能文档。在确认这两个能力的具体行为和配置方式之前,不应该把它们计入选型理由。
还有一点需要直说:这份材料里没有任何性能数据。网关作为中间层会引入额外一跳,具体增加多少延迟,README 没有给出,也不该由外部推测。
和 LiteLLM 这类方案比,差别在部署形态
同类需求最常见的参照是 LiteLLM。两者都提供 OpenAI 兼容的统一接口,都做多供应商路由和用量统计,差别不在功能清单,而在交付形态。
LiteLLM 以 Python 库加代理服务的形式分发,很多团队直接把它作为 SDK 嵌进 Python 应用,代理是可选的一层。LLM Gateway 是 TypeScript 写的完整应用,README 给出的路径是 Docker 统一镜像或 pnpm 开发环境,没有提到以库的形式嵌入。
这个差别会直接影响选型。如果你的后端是 Python,且希望路由逻辑和应用在同一进程里,LiteLLM 的形态更贴合;如果你的技术栈是 TypeScript,或者希望网关是一个独立部署、独立升级、带自带仪表盘的服务,LLM Gateway 的形态更自然。反过来说,只想在 Node 应用里加几十行转发逻辑的团队,引入一个包含七个端口、多个 Next.js app 的镜像,代价明显偏高。
另一个差别在许可。AGPLv3 加 ee/ 目录的商业授权,与 LiteLLM 的许可条款不同,对打算修改后对外提供服务的团队,这两者的义务不一样。选型时应该把许可和部署形态放在一起看,而不是先选功能再补法务。
版本节奏与升级成本
从发布记录看,v1.14.0、v1.15.0、v1.16.0 分别在 8 月 24 日、8 月 31 日、9 月 7 日发布,间隔一周。这是一个相当紧凑的节奏。
对自托管用户,周更意味着两件事。第一,升级是常态而不是例外,需要有一套可回滚的部署流程,尤其是数据库 schema 由 packages/db 的 Drizzle 迁移管理,跨版本升级时迁移是否可逆,README 没有说明。第二,跟上最新版和停留在稳定版之间的取舍会更频繁地出现。
README 没有给出 LTS 版本、弃用策略或兼容性承诺。对于把网关放在关键路径上的团队,这是需要在内部先定规则的地方:跟到哪个版本、多久升一次、回滚靠什么。
许可层面还有一条实际影响:ee/ 下的功能需要单独的商业授权,这意味着如果团队后来用到了组织管理或延长保留期,成本结构会从「自托管的服务器开销」变成「服务器开销加授权费」。这个转换点应该在架构评审时就标出来。
编辑结论
如果你的团队已经在两个以上模型供应商之间来回切换,并且需要一份跨供应商的 token 与费用账目,同时能接受 AGPLv3 对自托管衍生代码的约束,LLM Gateway 值得先在测试环境跑通一次统一镜像。反过来,只调用单一供应商、或者把数据驻留和审计要求写进合同里的团队,先别急着上:ee/ 目录之外的功能边界、30 天数据保留上限、以及 multi-organization administration 需要 white-label 授权这几条,都应该在动手之前对着 LICENSE 与 ee/LICENSE 逐条确认。
社区笔记