从 0 部署一个多模型 AI 网关:Docker、渠道、令牌与模型映射

0 阅读8分钟

从 0 部署一个多模型 AI 网关:Docker、渠道、令牌与模型映射

本文以 OpenStarry(基于 New API 的二次开发版本)为例。不同版本的界面文案可能略有差异,但核心链路一致:客户端 → 网关 → 渠道 → 上游模型。

先说结论

多模型接入真正难的不是“把 Key 填进去”,而是把下面三件事同时做对:

  1. 客户端只认一个 Base URL;
  2. 网关知道每个请求该走哪条渠道;
  3. 模型名、令牌分组和上游模型 ID 能对上。

这篇不追求一次接 20 个模型。目标只有一个:先用最小配置跑通 1 个模型,再复制这套方法批量接渠道。


一、为什么不是多填几个 Key

早期最直接的做法,是在每个项目里分别配置不同供应商的 Key:

项目 A -> OpenAI SDK -> 供应商 1
项目 B -> OpenAI SDK -> 供应商 2
项目 C -> 另一套 SDK -> 供应商 3

短期能跑,项目一多就会出现四个问题:

  • Key 散落在不同项目和环境变量里;
  • 每个项目都要单独改模型名和请求地址;
  • 无法按项目统计额度和成本;
  • 某个渠道不稳定时,只能手工改配置。

AI 网关的价值,是把这些差异收口到一层:

项目 A ─┐
项目 B ─┼─> AI 网关 ─> 渠道 1 / 2 / 3 ─> 上游模型
项目 C ─┘

02-architecture.png 客户端仍然使用 OpenAI 兼容接口,只把 Base URL 和令牌换成网关的。至于后面是 Qwen、DeepSeek、Kimi、GLM 还是 MiniMax,由网关决定。


二、部署目标与非目标

这次部署的目标:

  • 单机 Docker 可运行;
  • 支持 OpenAI 兼容请求;
  • 能配置多个上游渠道;
  • 能按项目发令牌、看额度;
  • 支持模型名映射和失败重试。

这次不追求:

  • 一上来就做高可用集群;
  • 直接对外提供生成式 AI 服务;
  • 把支付、告警、审计全部配完。

如果用于组织内部或自用场景,建议先跑通链路。对外提供生成式 AI 服务时,需要自行完成备案、内容安全、实名、日志留存、税务和上游授权等合规义务。


三、环境准备

最低建议:

项目建议
系统Linux x86_64
Docker24+
Docker Composev2
内存2 GB 起步,4 GB 更稳
磁盘20 GB 起步
端口3000

先确认环境:

docker --version
docker compose version

四、第一步:启动最小服务

第一次部署不建议直接上完整生产 Compose。仓库里的完整编排通常还会带 MySQL、Redis、告警和支付服务,变量没填全,容易卡在启动阶段。

先做一个最小启动文件 compose.first-run.yml:

services:
  new-api:
    image: openstarry/api:local
    container_name: openstarry
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      TZ: Asia/Shanghai
    volumes:
      - ./data:/data

如果你已经有镜像,直接替换 image。没有镜像就先在项目根目录构建:

git clone https://gitee.com/wlkj/openstarry.git
cd openstarry

docker build -t openstarry/api:local .

启动:

docker compose -f compose.first-run.yml up -d
docker compose -f compose.first-run.yml ps
docker compose -f compose.first-run.yml logs -f new-api

检查服务是否正常:

curl -sS http://127.0.0.1:3000/api/status

浏览器打开:

http://<服务器IP>:3000

首次访问会进入初始化页面。管理员用户名最长 12 个字符,密码至少 8 位。内部自用场景可以开启自用模式,减少不必要的注册和支付入口。

SQLite 适合第一次验证链路。正式环境建议直接用 MySQL 或 PostgreSQL,并配上 Redis,避免后期再做数据迁移。


五、第二步:配置第一个渠道

03-channels.png 进入后台后,先只加一个渠道,不要批量导入。

以 OpenAI 兼容渠道为例,重点填这几项:

配置说明
渠道类型优先选供应商对应的类型;没有就选 OpenAI 兼容
Base URL供应商的 API 地址,注意是否已经包含 /v1
Key供应商控制台创建的 API Key
模型列表客户端要调用的模型名
模型重定向把请求名映射到上游真实模型 ID
分组先保持 default
优先级 / 权重第一次部署先不配

这里最容易混的是三个“名字”:

渠道名称       -> 后台管理用的标签,不参与请求
模型列表       -> 客户端请求时传的 model
上游模型 ID    -> 供应商真正接受的 model

如果客户端传的模型名和上游完全一致,模型重定向可以留空。

如果不一致,用 JSON 做映射:

{
  "team-qwen": "qwen-plus-2025-xx"
}

含义是:

客户端请求 model=team-qwen
        ↓
网关查 model_mapping
        ↓
向上游发送 model=qwen-plus-2025-xx

左边的 team-qwen 是对外名字,右边的值必须以供应商文档为准。不要凭感觉补版本后缀。

配置完成后,先在渠道列表里点一次测试。测试不通过,不要继续创建令牌。


六、第三步:创建令牌

04-tokens.png 进入令牌管理,新建一个测试令牌。

重点看四项:

  • 分组:必须和渠道分组一致,默认都用 default;
  • 额度:先设一个小额度,避免测试时消耗过多;
  • 可用模型:如果开启限制,填对外模型名,例如 team-qwen,不要填上游 ID;
  • IP 白名单:测试阶段可以先不填,生产环境建议加上。

创建后复制一次令牌,格式通常是:

sk-xxxxxxxxxxxxxxxx

令牌只展示一次,保存到测试环境的变量里,不要提交到 Git。


七、第四步:发第一次请求

先测非流式:

export BASE_URL="http://127.0.0.1:3000"
export OPENSTARRY_KEY="sk-你的测试令牌"

curl -sS "$BASE_URL/v1/chat/completions" \
  -H "Authorization: Bearer $OPENSTARRY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "team-qwen",
    "messages": [
      {"role": "user", "content": "用一句话解释什么是 AI 网关"}
    ],
    "stream": false
  }'

正常返回会包含:

  • choices:模型输出;
  • usage:输入、输出和总 token;
  • model:本次请求使用的模型信息。

再测流式:

curl -N "$BASE_URL/v1/chat/completions" \
  -H "Authorization: Bearer $OPENSTARRY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "team-qwen",
    "messages": [
      {"role": "user", "content": "写一个 5 行的 shell 脚本"}
    ],
    "stream": true
  }'

最后去后台看三处:

  1. 请求日志里有没有这次调用;
  2. 令牌额度有没有减少;
  3. 渠道用量有没有记录。

这三处都对上,才算真正跑通。


八、常见错误怎么判断

不要只看 HTTP 状态码,先看响应体里的 error.code 和 error.message。

现象常见原因先查
401令牌错误、被禁用或没带 BearerAuthorization 头
404 model_not_found模型不在渠道列表,或映射缺失渠道模型列表、model_mapping
503 model_not_found当前分组没有可用渠道令牌分组、渠道分组、渠道状态
429限流或额度不足令牌额度、渠道限流
请求超时流式超时或上游响应慢STREAMING_TIMEOUT、上游日志

这里有一个容易误判的点:

模型不存在 -> 可能返回 404
当前分组没有可用渠道 -> 也可能带 model_not_found,但状态码是 503

所以排查顺序应该是:

先看完整响应体
再确认客户端传的 model
再对照渠道模型列表和映射
最后检查令牌分组与渠道分组

一次只改一个变量。一次改五项,即使恢复了,也不知道是哪一项修好的。


九、生产环境还要补什么

最小链路跑通后,再补这些:

1. 数据库和缓存

  • SQLite 换成 MySQL 或 PostgreSQL;
  • 配置 Redis;
  • SESSION_SECRET 和 CRYPTO_SECRET 必须长期稳定;
  • 修改 CRYPTO_SECRET 可能导致已加密配置无法解密。

2. 网络安全

  • 只暴露 3000 端口给反向代理;
  • 不要把 3306、6379 直接暴露到公网;
  • 用 Nginx 或 Caddy 做 HTTPS;
  • 管理后台限制来源 IP。

3. 镜像和升级

  • 生产不要使用 latest;
  • 固定镜像 tag;
  • 升级前备份数据库;
  • 先看发布说明,再执行迁移;
  • 不要直接 git pull && docker compose up --build。

4. 日志和成本

  • 打开请求日志;
  • 按项目、令牌、模型看用量;
  • 给令牌设置额度;
  • 定期检查异常渠道和重试次数。

5. 合规

  • 遵守上游服务条款;
  • 不把未授权的账号或额度对外转售;
  • 对外提供生成式 AI 服务时,完成相应备案和内容安全义务;
  • 注意项目 AGPLv3 许可证的使用边界。

十、最后

这套部署最重要的不是“接了多少个模型”,而是形成一条可重复的路径:

启动服务
  -> 接 1 个渠道
  -> 对齐 1 个模型名
  -> 发 1 个令牌
  -> 跑通 1 次请求
  -> 看日志和额度
  -> 再复制到第 2 个、第 3 个模型

先把一个模型跑通,比一次导入 20 个渠道更省时间。

下一篇我会写:模型映射为什么总是 404,以及三个名字到底怎么对齐。

访问地址:<OpenStarry — 注册即赠200次免费调用 | 国产大模型 API 聚合中转 · GLM · DeepSeek · Kimi>

我是小雨,记录 AI 中台、多模型接入和真实踩坑。