简介:OneAPI计费系统开源版1.2.0是一套多功能的接口管理与计费解决方案,适合需要为API服务接入付费能力的开发者、独立站长及技术团队使用。该系统支持免费、资源包、混合计费三种模式,涵盖卡密兑换、余额充值、实名及手机号校验、多种通知方式,并提供API文档与代码的在线编辑功能,整体上既能直接部署用于生产,也为二次开发留出了清晰结构。本次更新修复了若干已知Bug,优化特定值扣费逻辑,并增强邮箱/短信验证码防刷机制,同时支持注册赠送余额,实用性进一步提升。压缩包共2000个文件,主要由PHP业务代码、Markdown说明文档、JSON配置与前端资源组成,另含数据库SQL及部署相关文件,整体仅8.34MB,便于快速下载与部署。目前已有95人学习下载,适合想低成本搭建API计费闭环的开发者参考。
1. OneAPI计费系统开源版 1.2.0 是什么:解决多模型接入与计费混乱的最后一公里
做 AI 应用落地的人,十有八九碰过这种场景:项目里同时接了 GPT、Claude、文心、通义,每家的 API 格式不一样、鉴权方式不一样、价格单位不一样,开发的时候一套套适配,上线之后账单更是一笔糊涂账。OneAPI 计费系统开源版 1.2.0 这个项目,就是把“多模型统一接入”和“按量计费”这两件事打包解决掉——它提供一个统一的 API 网关,你用一套 OpenAI 风格的接口去调各家模型,系统在后面对接真实上游,同时把每次请求的 token 消耗、费用折算、用户扣费全部自动记账。1.2.0 这个版本相比早期版,主要完善了渠道管理的粒度和额度统计的准确性,做生产接入会比旧版省心不少。
这套系统适合谁?三类人:一是做 SaaS 应用的开发者,要给自己的终端用户分配 API Key 并限流限费;二是企业内部做 AI 中台,需要统一管控各业务线的模型调用成本;三是做模型聚合转售的团队,靠额度充值和倍率差价跑通商业模式。接下来我会从系统设计逻辑、部署步骤、计费配置、踩坑记录到验收方法,完整过一遍这套体系怎么落地。
2. 计费系统的核心设计:先看懂令牌桶、额度账本和渠道映射,再动手部署
2.1 为什么需要统一网关:上游接口差异是第一个黑匣子
各家模型厂商的接口风格差异很大。OpenAI 系是/v1/chat/completions,Anthropic 是/v1/messages,百度的ERNIE-Bot用access_token动态鉴权,阿里的DashScope又是独立的Authorization头格式。如果你的业务代码直接对接每一家,每次上游调整参数或新增模型,你都要改业务代码再重新发版,这中间的沟通和排障成本非常高。
OneAPI 的做法是让所有调用方只认一套 OpenAI 兼容协议,把差异消化在网关内部。你在业务侧设置base_url指向 OneAPI 的地址,模型名写成 OneAPI 里配置好的“映射名”,网关拿到请求后,根据映射关系找到真实渠道,再转换为对应厂商的协议格式发出去,响应再统一转回 OpenAI 结构返回给你。这个过程对调用方完全透明。
从计费角度看,统一网关还有一层意义:如果不做代理,每个调用方的用量散落在各家厂商的控制台里,按项目、按功能聚合成账单非常麻烦。有了网关,一次调用从进入系统到响应返回,令牌消耗 → 费用折算 → 用户扣费 → 渠道记录这条链路全部有据可查,月底对账只看数据库即可。
2.2 额度账本的三层模型:用户、令牌和渠道配额
OneAPI 的计费体系不是单层扣费,而是三层联动。最上层是“用户”,用户表记录了余额、额度、状态等字段,这是你给终端使用者的计费账户。中间层是“令牌”,一个用户可以创建多个令牌,令牌是真正发给客户去调用 API 的凭证,令牌本身没有余额概念,它只是指向用户账户的一把钥匙。最底层是“渠道”,渠道代表真实的上游供应商配置,渠道里定义了模型的倍率、密钥、代理地址,以及这个渠道最多能承受多少并发请求。
一个请求进来后,系统先校验令牌是否有效、对应用户是否被禁用,然后从令牌指向的用户余额里预扣一笔预估费用,等真实响应返回后计算实际 token 数,再做多退少补。这个“预扣 → 结算”的机制和运营商话费计费是同一套逻辑,好处是防止用户在一个大请求执行到一半时余额耗尽,导致上游费用倒挂。
渠道配额是另一个很容易被忽略的账本维度。每个渠道可以设置最大并发和权重,当一个模型绑定多个渠道时,系统会按权重做负载均衡。比如你有公司内部 GPU 自建的 vLLM 服务、有阿里云百炼的付费渠道、有开源的免费渠道,分别在 OneAPI 里配成三个渠道,设置不同权重,调用就会按比例分发。一些团队在这个场景下会刻意把一个渠道的权重设得比较高,这样既能优先消化内部的算力,又保留付费渠道作为兜底。
2.3 为什么要用 1.2.0 而不是旧版:渠道测试与日志定位的体验差异
1.2.0 在渠道管理上有一个很实用的改进:支持对单个渠道单独发起测试,而且测试结果会直接显示“鉴权参数是否通过、模型是否可用、返回耗时多久”。旧版如果渠道配置有问题,往往要等真实业务请求打到这条渠道上才发现,排障链路长不说,还会污染你的生产计费数据。1.2.0 的渠道级测试和更清晰的日志筛选条件,就是让你在新渠道接入时,先在测试环境把问题暴露出来,再切生产流量。
对做转售的团队来说,日志查询的粒度也很关键。1.2.0 在日志列表里可以直接按模型、按渠道、按用户维度筛出消耗明细,这样你就可以针对“某个用户为什么一夜之间烧掉了 80% 的额度”“某条渠道为什么连续失败还产生了费用”这类具体问题,直接定位到某几行的请求日志上,而不是导出一张几万行的表格去慢慢筛。
3. 用 Docker Compose 跑通最小部署:从环境准备到初始化管理员
3.1 部署前的准备:服务器、数据库和时区三件事
OneAPI 的部署方式常见有两种:一种是用 Docker 单容器直接跑,内置 SQLite 数据库,适合试用和 100 以内的用户规模;另一种是 Docker Compose 搭配 MySQL 或 PostgreSQL,适合正式生产。我一般建议直接从 Compose 方案起步,因为计费数据是后悔药——一旦跑起来再迁移数据库,虽然官方有迁移工具,但中间要停服、备份、校验,折腾成本足够你重新部署一遍。
服务器配置不用太焦虑,OneAPI 本身只做转发和计费,不承载模型推理,2 核 4G 的机器跑几千个用户足够。但你一定要确认服务器时间是不是 UTC 时区,因为计费日志的时间戳直接依赖系统时间。如果你忽略了这一步,后面对账会发现计费时段永远偏了 8 个小时,排查过程会让人非常郁闷。
准备一个干净的目录结构,建议这样划分:
mkdir -p /opt/oneapi/data cd /opt/oneapi/data3.2 编写 docker-compose.yml 并启动
我们先定义一个最小可用的 Compose 编排,数据库采用 SQLite 起步,方便你把精力放在熟悉系统上:
version: '3.4' services: one-api: image: justsong/one-api:1.2.0 container_name: one-api restart: always ports: - "3000:3000" environment: - TZ=Asia/Shanghai - SQL_DSN=one-api.db - SESSION_SECRET=please_change_me_to_a_long_random_string volumes: - ./data:/data启动命令就一句话:
docker compose up -d启动完成后,打开http://服务器IP:3000就能看到登录页。首次部署时系统会自动初始化一个管理员账号,用户名是root,初始密码是123456,登录后系统会强制要求修改密码。
这里的SQL_DSN参数需要解释一下:它指定了数据库文件的路径,one-api.db是相对路径,最终文件会落在容器内的/data/one-api.db,再通过 volume 映射到宿主机./data目录。SESSION_SECRET是会话加密密钥,生产环境务必换成长随机串,否则别人可以伪造会话。TZ=Asia/Shanghai保证日志和计费时间跟你的业务时区对齐。
3.3 用 MySQL 替换 SQLite 的配置模板
如果你的用户量预计会超过几百,或者你希望计费数据能方便地做备份和聚合分析,那在一开始就换成 MySQL 更稳妥。Compose 文件扩展如下:
version: '3.4' services: mysql: image: mysql:8.0 container_name: one-api-mysql restart: always environment: - MYSQL_ROOT_PASSWORD=your_root_password - MYSQL_DATABASE=oneapi - TZ=Asia/Shanghai command: --default-authentication-plugin=caching_sha2_password volumes: - ./mysql-data:/var/lib/mysql one-api: image: justsong/one-api:1.2.0 container_name: one-api restart: always depends_on: - mysql ports: - "3000:3000" environment: - TZ=Asia/Shanghai - SQL_DSN=root:your_root_password@tcp(mysql:3306)/oneapi?charset=utf8mb4&parseTime=True&loc=Local - SESSION_SECRET=please_change_me_to_a_long_random_string volumes: - ./data:/dataSQL_DSN的格式是标准 GORM 连接串,注意parseTime=True这个参数必须带上,否则日期字段会被驱动解析成字节数组,后续对账单按时间筛选会直接报错。charset=utf8mb4是为了支持存储表情符号——模型返回的日志里如果包含 emoji,用默认的utf8会直接写入失败,这个坑我在生产环境里遇到过。
数据库启动需要十几秒,depends_on只保证容器启动顺序,不保证 MySQL 已经准备好接受连接。如果 OneAPI 容器启动时 MySQL 还没就绪,OneAPI 会尝试连接失败然后自动退出,依靠restart: always自动拉起,通常重试两三次后就能正常启动。
3.4 初始化验证:确认版本、登录取和管理员密码
部署完成后不要急着配置渠道,先做三个验证动作:
- 查看容器状态和日志,确认没有报错。
- 浏览器打开管理页面,用初始管理员登录。
- 修改默认密码,然后到“系统设置”里把
服务器地址改成你的真实公网地址。
docker ps docker logs one-api --tail 50看到类似Starting GIN server in 0.0.0.0:3000的日志就说明服务已经起来了。如果日志里出现Failed to connect to database,优先检查SQL_DSN里的用户名密码、MySQL 容器是否健康、网络是否互通。
4. 配置你的第一条渠道:从模型映射到负载均衡的完整流程
4.1 渠道基础配置:类型、密钥和代理地址怎么填
进入管理后台的“渠道”页面,点击“添加渠道”。这里有一个值得注意的设计:渠道类型实际上是模板,系统预设了 OpenAI、Anthropic、百度千帆、阿里云百炼、智谱、讯飞等常见的厂商类型,你选了类型之后,表单里会自动带出该厂商需要的字段。
以接入 OpenAI 官方渠道为例,最核心的字段是:
名称:给这条渠道起个自己能看懂的名字,比如openai-official-prod类型:选OpenAI密钥:填你的 OpenAI API Key,支持多行填多个 Key,系统会随机取用代理地址:如果你通过网络代理访问 OpenAI,这里填代理地址;如果服务器能直连,留空就好
填完之后不要急着保存,1.2.0 的渠道表单旁边有“测试”按钮,这个按钮非常值得好好利用。点测试时,系统会用你填的密钥实际调用一次该渠道的模型列表接口,并返回连通性结果。如果测试失败,把返回的错误信息直接复制,去搜索或者对照厂商的错误码排查,通常能定位到八成的问题。
4.2 模型映射:为什么用户填的模型名可以跟上游不同
这是 OneAPI 最巧妙的设计之一。渠道绑定的“模型”并不是写死的固定值,而是一组映射关系。你在渠道里填模型名gpt-4o,同时可以设置“自定义模型名”为my-gpt4。这样,你发给用户的文档里只需要写my-gpt4,系统转发给 OpenAI 时再翻译回gpt-4o。
这个能力解决了两个实际问题。一是你想换上游供应商时,不需要通知所有调用方改代码,只需要在渠道层面改映射目标即可;二是你可以将多个渠道的同一模型聚合到一个模型名下,由系统做负载均衡,实现“多个供应商 / 一个逻辑模型名 / 自动切换”。
模型映射界面长这样:在添加渠道的页面上,找到“模型映射”区域,左边输入上游真实模型名,右边输入你要暴露给用户的模型名,一行一对,保存后立刻生效。
4.3 权重的意义:多渠道下流量怎么分配
你可能会问:一个逻辑模型挂了三家渠道,请求到底发给谁?答案就在渠道的“权重”字段里。系统的分配逻辑是,按所有可用渠道的权重占比做随机选择,权重越高的渠道被选中的概率越大。
这个机制配合渠道的最大并发数,可以做到很细的流量调度。举个例子:你有两个渠道,一个是公司内部自建的 vLLM 服务,成本几乎为零但并发有限;另一个是云厂商的按量付费服务,价格高但扩容快。你可以在内网渠道设置权重5、最大并发10,在云厂商渠道设置权重1、最大并发50。平时 80% 以上的流量会走内网,当内网并发打满时,系统会把溢出的请求转发给云厂商。这个配置在真实业务里非常实用。
4.4 必做的连通性验证:用 curl 模拟一次真实调用
在配置完渠道和映射后,不要急着接入业务代码,先用 curl 做一次端到端验证。OneAPI 兼容 OpenAI 协议,所以调用方式和你调 OpenAI 接口一模一样:
curl http://localhost:3000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-your-token" \ -d '{ "model": "my-gpt4", "messages": [ {"role": "user", "content": "你好,请用一句话介绍你自己"} ] }'注意这里的Authorization里的sk-your-token不是你的渠道密钥,而是在“令牌”页面里创建的 OneAPI 令牌。如果你还没有创建令牌,先去令牌页面生成一个,权限范围选“所有模型”即可。
请求返回的 JSON 结构应该和 OpenAI 官方一致,里面有一个usage字段,记录了prompt_tokens、completion_tokens、total_tokens。这个字段是整个计费系统的数据来源——如果渠道返回的响应里没有usage,系统就无法计算费用。大部分情况下,模型厂商都会返回这个字段,但也存在少数兼容层不返回的情况,遇到时你应该第一时间去渠道日志里确认。
4.5 用真实场景检验配置:一个渠道对应多个模型
给渠道配置完模型映射后,可以在渠道详情里看到当前渠道可用的模型列表。如果你创建的令牌在“模型范围”里勾选了“仅限以下模型”,那用户调用时指定的模型就不能超出这个范围,否则会直接收到404 model not found的错误。
这里我建议你按业务线来做模型分组:比如把gpt-4o、gpt-4o-mini绑到一个渠道组里,把claude-3-5-sonnet绑到另一个渠道组里,把embedding模型单独放到一个渠道组里。分组的好处是后续在令牌一级做权限控制时很直观,给哪个用户开哪些模型的权限直接勾选即可。
5. 把计费参数调到合理:倍率逻辑、价格配置和用户额度管理
5.1 计费的基本单位:token 消耗、倍率和价格设置的换算关系
OneAPI 的计费不是直接填“多少钱一个 token”,而是通过“倍率”字段做换算。为了方便理解,可以把倍率想成一个抽象的价格系数。系统内部有一个基准点:假设倍率1对应的价格是$0.002 / 1K tokens,这个基准价格可以通过后台“价格”页面修改。
换算公式为:请求费用 = 实际消耗 token 数 × 该模型倍率 × 基准单价。举个例子,某个模型倍率设置为2,一次请求消耗了 1500 个 token,基准单价按$0.002 / 1K计算,那么费用就是 1500 / 1000 × 2 × 0.002 = $0.006。
这种倍率制的好处是当你接入新的模型时,只需要查一下该模型在官方价格页面上的单价,用单价除以基准单价得出倍率填进去,后续的所有计费都会自动按此折算。你不需要为每个模型写死一段价格计算逻辑。
5.2 模型倍率设置:官方价格与真实成本之间的一个缓冲垫
在 OneAPI 后台“模型”页面配置模型倍率时,我建议不要把倍率设成和官方价格完全一致的比例。原因很现实:上游价格会调整,你的渠道可能存在代理成本、失败重试成本、币种汇兑成本,如果倍率卡得死,上游一涨价你就亏。
常见做法是在官方成本上加一个系数,比如官方单价换算倍率是1,你设置成1.3或1.5——这样你的计费收入能覆盖掉潜在损耗,终端用户支付的单价还在合理范围内。做转售的团队通常会把热门的gpt-4o倍率调到官方的1.5到2倍,把冷门的embedding模型调成平价甚至微亏,用冷门低价引流、热门走量赚钱的组合打法。
需要注意一点:修改模型倍率只影响后续新请求的计费,历史日志里的费用不会重新计算。如果要追溯调整,只能通过修改日志记录的方式处理,这是所有计费系统的通用逻辑。
5.3 用户充值、退款与额度到期:后台怎么操作
用户管理页面支持对单个用户“充值”和“退款”。充值时输入金额,系统会生成一条额度变更记录,这条记录在用户侧的流水列表里可见。额度可以是永久有效,也可以设置“过期时间”,在用户编辑弹窗里直接填时间即可,到期后该用户余额归零,如果余额为负,也会被禁用。
退款操作要更谨慎,因为退款不会自动回滚已经生成的请求日志,你需要先确认要退款的用户近期消费了哪些费用,再手动计算退回金额。更常见的操作方式时直接把用户余额调整到某个值,而不要频繁做“扣减”。系统里“调整额度”这个操作不会生成账单流水,适合做一次性修正。
5.4 令牌级别的流控:限制并发、限制模型、限制额度
令牌不只是凭证,还是精细化的控制面。每个令牌可以设置“额度上限”,用户总余额没变,但这个令牌最多只允许消费这么多,适合做不同等级客户的分层售卖。令牌还可以限制允许访问的模型列表,甚至设置“模型倍率”单独覆盖全局设置的倍率——这个功能适合给大客户单独谈价格。
令牌的额度上限到量后,再发起请求会收到insufficient_quota错误,业务侧可以根据这个错误码自动引导用户去充值页面,这是常见且成熟的运营套路。
5.5 用表格快速确认你的初始计费参数
| 配置项 | 推荐初始值 | 说明 |
|---|---|---|
| 基准单价 | $0.002 / 1K tokens | 作为倍率的锚点,可按业务调整 |
| gpt-4o 倍率 | 1.5 ~ 2 | 覆盖官方价和潜在成本 |
| gpt-4o-mini 倍率 | 1.2 ~ 1.5 | 大众走量模型,倍率压低一些 |
| embedding 倍率 | 1.0 | 通常保本引流 |
| 用户默认额度 | 根据套餐定 | 免费用户给少量体验额度,付费用户按订单充入 |
6. 生产环境避坑指南:五个高频故障的排查与修复
6.1 日志里出现 401 鉴权失败,但密钥确认没问题
现象:渠道测试能通过,但真实调用时频繁出现401 Invalid API key。
原因:令牌的“模型范围”没有包含请求里指定的模型。你在令牌里限制了只能调用gpt-4o,但业务代码实际请求的是gpt-4o-mini,系统在鉴权阶段就把请求拦下了。渠道测试使用的是渠道自己的密钥,所以不会暴露这个问题。
解决:进入令牌编辑页,把模型范围改成“所有模型”进行快速验证。确认问题出在模型范围后,再按业务实际需求精确勾选。这条排查路径至少能节省半个小时的无头绪折腾,算是常见但让人头疼的坑。
6.2 渠道列表显示可用,但请求超时无响应
现象:渠道测试返回“可用”,但生产请求大量超时,日志里没有任何报错,只有等待超时。
原因:渠道测试只验证了“能连上、能鉴权、能返回模型列表”,并没有真实发起一次对话补全请求。很多渠道对列表接口放得比较松,但对推理接口会有额外的限制,比如按并发数限流、按账号余额限制,或者推理服务本身负载已经很高。
解决:在渠道设置页面点“测试”的同时,选一个具体的模型发起真实请求。如果真实请求超时,检查上游控制台的并发限制,并降低 OneAPI 渠道配置里的“最大并发”数值。另外在“系统设置”里把请求超时时间稍微调大,一般设为 120 秒比较合理,可以覆盖大多数推理服务的响应时间。
6.3 SQLite 数据库锁定错误,Drop 请求成功后系统卡住
现象:用户量不大但日志写入频繁,后台页面偶尔出现database is locked错误。
原因:SQLite 适合轻量场景,但在高频写入下容易出现锁冲突。OneAPI 的日志写入和额度更新都在同一时间点发生,SQLite 的写锁机制会导致并发写入互相阻塞。
解决:短期方案是降低日志保留天数,在系统设置里把日志保留周期调短,比如 7 天,减少总数据量。长期方案是尽早切换到 MySQL 或 PostgreSQL——这也是我建议在生产环境直接上 MySQL 的原因。
6.4 用户额度显示扣多了,实际消费和账单对不上
现象:用户反馈“我就发了几条消息,额度少了一半”,后台看请求日志的total_tokens也不大。
原因:计费是按prompt_tokens和completion_tokens分开算的,系统在请求开始时按用户配置的“输入倍率”和“输出倍率”预扣费用。如果某条渠道返回的usage字段里 token 数与用户实际感知差距很大,多半是上游返回的 token 统计口径和实际不符,常见于流式输出场景,部分兼容层可能把上下文重复计入。另外,如果模型倍率里“输入倍率”和“输出倍率”都填了较大值,预扣费用会明显高于用户心理预期。
解决:到“日志”页面筛选该用户的请求,展开一条详情,查看“计费详情”里的预估费用、实际费用和倍率。一比就能看出是倍率设置问题还是上游 count token 的问题。如果是倍率问题,调整对应模型的输入/输出倍率即可;如果是上游统计问题,需要评估换渠道或用支持的 token 计数工具重新统计。
6.5 升级 1.2.0 后页面打不开,日志报数据库版本不兼容
现象:沿用旧版的数据目录直接换镜像,启动后页面 502,日志里提示数据库结构版本低。
原因:OneAPI 从旧版升级时,程序会自动执行数据库迁移。但如果你的数据目录权限不对,或者当时用的镜像版本跨度过大,自动迁移可能失败。
解决:升级之前先备份数据目录,然后查看官方文档确认从你的旧版本到 1.2.0 的迁移路径。如果中途版本跳跃过大,需要按版本逐级升级,不要一步跨到目标版本。另外,容器内进程需要能写数据目录,如果chmod权限不正确,迁移脚本会静默失败。
7. 部署后的验证与进阶用法:用一条加固命令和一套压测流程确认系统可用
走到这一步,你的 OneAPI 系统已经有渠道、有模型映射、有用户额度,也踩过几个常见的坑。最后这个章节,我给你一套部署后的“验收清单”,以及两个进阶用法,用来确认这套系统能不能扛住真实流量。
第一步是给管理端加一层 IP 白名单,这是成本最低但非常有效的加固手段。在系统设置里找到“允许的 IP 段”,填上你办公网的 IP,这样公共互联网的请求就无法访问管理后台,能过滤掉大量扫描攻击:
# 在 nginx 层面再挡一层更稳 location /admin { allow 192.168.1.0/24; deny all; proxy_pass http://127.0.0.1:3000; }第二步是做一次并发压测,验证计费系统在高并发下不会漏单、不会超扣。用ab或者wrk工具,向 OneAPI 的 chat/completions 接口并发打请求,每个请求使用同一个令牌,压测结束后到后台日志页面确认请求数和费用总额是否匹配:
wrk -t4 -c50 -d30s -s post.lua http://localhost:3000/v1/chat/completions压测的post.lua里要带上Authorization: Bearer sk-your-token和固定的model参数,因为计费是按模型倍率计算的,模型名变化会导致费用结构复杂化,不利于校验。压测结束后,观察“日志”页面是否所有请求都有成功和失败记录,用户额度扣减总额是否约等于请求数 × 单次费用。
进阶用法方面,我建议把日志同步到外部存储做长期审计。OneAPI 自带日志保留策略,但计费系统作为业务核心,历史数据最好保留一年以上。常见做法是通过定时任务把数据库里的logs表导出到 BI 系统或者归档存储,这比任何“相信日志不会丢”都靠谱。
最后说一个我的习惯:每次改完渠道配置或倍率之后,都会用一个专门的测试令牌打一个固定 prompt,确认响应正常、费用符合预期,再让业务方切换流量。这个动作看起来简单,但它能挡住九成的“改完配置忘了验证”的翻车事故。OneAPI 计费系统开源版 1.2.0 是我在多套 AI 应用里验证过的方案,从统一接入到按量扣费再到问题排查,它都能在当前生态里给你一个牢靠的基座。生产环境的计费无小事,希望这套部署和避坑经验帮到你。
本文还有配套的精品资源,点击获取