个人记录(2026.5.14-5.15)——new-api-main 源码说明
标题
记录(2026.5.14-5.15)——new-api-main 源码说明
1. 这个项目到底是什么
new-api-main 是一个 AI API 网关平台。它把不同厂商、不同协议格式的大模型接口统一包装成一套对外 API,同时带上用户管理、令牌管理、渠道管理、计费、日志、统计和后台管理页面。
通俗理解:它像一座“模型请求中转站 + 运营后台”。
2. 它解决的是什么问题
直接对接多个上游模型时,常见问题有:
- 每家 API 格式不同
- Key 很散,难管理
- 团队内部要做权限、额度、计费
- 想让不同模型走不同上游
- 想看日志、消费、渠道健康度
new-api-main 的作用就是把这些问题集中解决。
通俗理解:它不是只帮你“转发请求”,而是帮你“把模型接入业务化”。
3. 技术栈
后端
- Go
- Gin
- GORM
- Redis + 内存缓存
- SQLite / MySQL / PostgreSQL
通俗理解:这是个标准 Go 后端平台项目。
前端
- React
- TypeScript
web/default为主前端
通俗理解:后台管理页面也在仓库里,不是另外一个系统。
4. 顶层目录作用
源码:
https://github.com/QuantumNous/new-api.git
| 目录/文件 | 作用 | 通俗理解 |
|---|---|---|
main.go |
系统启动入口 | 程序从这里启动 |
router/ |
路由装配 | 决定什么 URL 交给什么处理器 |
controller/ |
控制器层 | 真正处理 HTTP 请求的入口层 |
service/ |
业务逻辑层 | 规则、计费、渠道策略在这里 |
model/ |
数据库模型层 | 和数据库打交道的地方 |
middleware/ |
中间件层 | 鉴权、限流、日志、分发 |
relay/ |
上游转发引擎 | 真正把请求发给模型供应商 |
common/ |
公共基础能力 | 工具函数、环境变量、缓存等 |
constant/ |
常量定义 | 各种固定值和标识 |
dto/ |
请求响应结构体 | HTTP 数据格式定义 |
types/ |
通用类型 | 错误、relay 类型等 |
setting/ |
系统配置和规则 | 价格比率、操作规则等 |
oauth/ |
OAuth 相关实现 | 第三方登录和绑定 |
i18n/ |
后端国际化 | 后端返回多语言提示 |
web/ |
前端源码和构建产物 | 后台页面所在目录 |
.env.example |
环境变量示例 | 部署时先看它配什么 |
5. 启动流程怎么理解
5.1 main.go
它主要做这些事:
- 调用
InitResources() - 初始化数据库、Redis、日志、i18n
- 初始化缓存和后台任务
- 创建 Gin 服务
- 注册中间件
- 注册路由
- 启动 HTTP 服务
通俗理解:这是整个系统的“总装配入口”。
5.2 InitResources()
它负责把系统底座搭起来:
- 读
.env - 初始化环境变量
- 初始化日志
- 初始化数据库
- 初始化选项缓存
- 初始化 Redis
- 初始化 i18n
- 初始化自定义 OAuth
通俗理解:这一步像“开机自检 + 基础组件上线”。
5.3 后台任务
main.go 还会启动很多周期任务,例如:
- 渠道缓存同步
- 渠道自动检测
- 渠道上游模型更新检测
- Codex 凭证自动刷新
- 订阅额度自动重置
通俗理解:这个系统不是只“收请求”,它平时还在后台自动维护很多状态。
6. 分层怎么读
这个项目最适合按下面这条链路理解:
Router -> Middleware -> Controller -> Service -> Model / Relay
通俗理解:先决定“去哪”,再决定“能不能进”,再决定“怎么处理”,最后决定“怎么落库或怎么转发”。
6.1 router/
重点文件:
router/main.gorouter/api-router.gorouter/relay-router.go
router/main.go
作用:
- 把 API 路由、Relay 路由、Dashboard 路由、Web 路由挂到 Gin 上
通俗理解:总路由分发台。
router/api-router.go
作用:
- 用户、令牌、渠道、订阅、支付、日志、配置等后台 API 都在这里注册
通俗理解:这是“管理后台接口总表”。
router/relay-router.go
作用:
- 对外暴露模型转发接口
- 例如
/v1/chat/completions、/v1/responses、/v1/embeddings、/mj/*、/suno/*
通俗理解:这是“真正给模型客户端访问的网关入口”。
6.2 middleware/
重点文件:
middleware/auth.gomiddleware/rate-limit.gomiddleware/request-id.gomiddleware/logger.gomiddleware/distributor.go
middleware/distributor.go
这是最关键的中间件之一。
它负责:
- 从请求里提取模型名
- 检查 token 有没有权限访问这个模型
- 根据 group、模型、亲和性、优先级选出可用渠道
- 把选中的渠道信息写入上下文
通俗理解:这是“发车前的调度员”,它先决定这次请求该坐哪辆车。
6.3 controller/
重点文件:
controller/relay.go
controller/relay.go 负责:
- 解析请求
- 生成 relay 信息
- 敏感词检查
- 预估 token
- 预扣费
- 调用具体 relay 处理器
- 失败时退款、记录错误、决定是否重试和自动禁用渠道
通俗理解:这是“网关总控室”,一笔请求到了这里,才真正进入业务处理。
6.4 service/
这是规则层。
重点文件:
service/channel_select.goservice/channel.goservice/pre_consume_quota.goservice/subscription_reset_task.go
service/channel_select.go
作用:
- 根据 group、模型、重试次数和自动分组规则挑渠道
通俗理解:这是“真正做渠道选择算法”的地方。
service/channel.go
作用:
- 判断某个渠道要不要自动禁用
- 处理禁用后通知
通俗理解:这是“渠道健康规则中心”。
其它 service
| 文件/模块 | 作用 | 通俗理解 |
|---|---|---|
pre_consume_quota.go |
预扣费 | 请求发出去前先扣一部分额度 |
task*.go |
任务型平台逻辑 | Midjourney、Suno 这类任务请求处理 |
codex_credential_refresh_task.go |
Codex 凭证刷新 | 让某些凭证别过期 |
subscription_reset_task.go |
订阅额度重置 | 定时给订阅用户恢复额度 |
6.5 model/
重点文件:
model/main.gomodel/channel.gomodel/token.gomodel/user.gomodel/log.go
model/main.go
作用:
- 选数据库类型
- 建连接
- 自动迁移
- 兼容 SQLite / MySQL / PostgreSQL
- 首次初始化 root / setup
通俗理解:这是数据库“总入口和总管家”。
6.6 relay/
重点目录/文件:
relay/claude_handler.gorelay/gemini_handler.gorelay/image_handler.gorelay/embedding_handler.gorelay/audio_handler.gorelay/responses_handler.go
作用:
- 适配不同上游协议
- 构造上游请求
- 转换响应格式
- 处理流式输出和错误
通俗理解:这里就是“真正和模型供应商说话”的地方。
6.7 web/
这个目录下有两个主题:
web/defaultweb/classic
其中 web/default 是主前端。
作用:
- 提供后台管理页面
- 展示用户、渠道、日志、统计、设置等
通俗理解:你在浏览器里看到的后台页面,基本就来自这里。
7. 关键文件为什么重要
| 文件 | 为什么重要 | 通俗理解 |
|---|---|---|
main.go |
系统启动总入口 | 开机总控 |
router/main.go |
路由总装配 | 决定请求去哪 |
router/relay-router.go |
模型转发接口入口 | 客户端主要打这里 |
router/api-router.go |
管理后台接口入口 | 管理员主要走这里 |
middleware/distributor.go |
渠道选择前置逻辑 | 发请求前先决定走哪条线 |
controller/relay.go |
relay 总控制器 | 请求真正进入业务处理的地方 |
service/channel_select.go |
选渠道核心逻辑 | 挑上游的算法中心 |
service/channel.go |
渠道禁用/启用逻辑 | 渠道健康度管理 |
model/main.go |
数据库初始化与迁移 | 数据底座 |
web/default/package.json |
前端技术栈入口 | 识别前端最省时间的入口 |
8. 核心流程重新讲清楚
8.1 流程一:一次 /v1/chat/completions 请求怎么走
- 客户端请求进入 Gin。
- 命中
router/relay-router.go。 - 经过鉴权、限流、性能检查和
Distribute()。 Distribute()按模型和 group 选出一个渠道。- 进入
controller/relay.go。 - 控制器做参数检查、敏感词检查、token 估算、预扣费。
- 控制器调用
relay/中对应处理器。 - 请求被发往真实上游。
- 返回后记录日志、做结算、统计用量。
- 如果出错,可能重试,也可能自动禁用渠道。
通俗理解:一条请求不是“收到就转发”,而是“先审、先选路、再发车、再记账”。
8.2 流程二:渠道是怎么选出来的
代码主线:
- 中间件先读出模型名。
- 看 token 是否允许访问这个模型。
- 如果有亲和渠道,先尝试之前稳定成功的渠道。
- 如果没有,再走
CacheGetRandomSatisfiedChannel(...)。 - 结合 group、模型、重试次数选一个渠道。
- 把渠道的 key、base URL、类型等写进上下文。
通俗理解:它像“智能接线员”,不是随机乱发,而是按规则挑最合适的一条线。
8.3 流程三:失败后怎么处理
代码主线:
- 上游报错。
- 控制器判断是否可重试。
- 如果能重试,就换一个可用渠道。
- 如果错误符合规则,就自动禁用这个坏渠道。
- 记录错误日志。
- 如果之前做过预扣费,就退款或补偿。
通俗理解:它不是一条线挂了就直接报废,而是会尽量“换线继续打”。
8.4 流程四:管理员在后台看渠道列表怎么走
- 请求进入
/api/channel/... - 命中
router/api-router.go - 先过
AdminAuth() - 进入对应 controller
- controller 调 model/service 取数据
- 返回给前端页面
通俗理解:后台 CRUD 这条线比模型转发简单很多,主要就是权限控制加查库。
9. 为什么原流程难懂
因为这个项目其实同时在做两件大事:
- 模型 API 网关
- 平台管理后台
再叠加渠道、计费、日志、前端、任务平台适配,信息量就会很大。
通俗理解:它不是“单一接口项目”,而是“半个平台”。
10. 推荐阅读顺序
README.zh_CN.mdmain.gorouter/main.gorouter/relay-router.gomiddleware/distributor.gocontroller/relay.goservice/channel_select.goservice/channel.gomodel/main.gorouter/api-router.goweb/default/package.json
通俗理解:先把“请求主链路”读懂,再补后台和前端。
11. 一句话总结
new-api-main 本质上是一套“多上游模型统一接入、统一鉴权、统一计费、统一后台管理”的 AI 网关平台。
通俗理解:它不是只帮你“转一下 API”,而是帮你“把 API 中转站做成一个可运营的平台”。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)