New API 模型定价与倍率配置 (Model Pricing and Ratio Configuration)
目标
把 new-api 里各模型的倍率改成上游厂商官网价,并保证改完之后
(a) 其它模型不被误伤,(b) 后续还能继续改(不被脏数据卡死)。
换算基准 (QuotaPerUnit)
QuotaPerUnit = 500000(默认)时,1 倍率 = $2 / 1M tokens。于是:
ModelRatio= 官方输入价 ÷ 2CompletionRatio= 官方输出价 ÷ 官方输入价CacheRatio= 缓存读价 ÷ 输入价CreateCacheRatio= 缓存写价 ÷ 输入价
存储与入口
- 存储在
options表:key 为ModelRatio/CompletionRatio/CacheRatio/CreateCacheRatio/ModelPrice/AudioRatio/AudioCompletionRatio/ImageRatio,
value 是{"模型名": 数值}的 JSON 字符串(不是独立价格表) options表是"只存覆盖项"的稀疏表:内置默认值写在 Go 代码里(tag_setting__ratio_setting__model_ratio.go),
只有与默认不同的项才会落库。所以删掉某一行 = 恢复该键的内置默认,这比"猜一个正确的值"更安全- 后台页面:
/system-settings/billing/model-pricing;模型页的Sync model pricing是同步第三方聚合价
(basellm / models.dev),不是厂商官网价 - 新接口
PATCH /api/option/model_pricing(按模型粒度、带 expected_version 乐观锁)、POST /api/option/model_pricing/convert($ 价 → 倍率换算) - 认证:
POST /api/user/login拿到 JWTaccess_token,之后所有管理接口必须Authorization: Bearer <token>;只带 session cookie 会 401
实测踩坑
PUT /api/option/的请求体只接受单个{key, value}(controller.UpdateOption解OptionUpdateRequest)。
这不是数组、也不是{"data":[...]}。
传批量结构不会报错,接口照样回200 success:true,但完全不生效 —— 是静默失败,最容易误判成"改好了"。
批量改就自己循环单键 PUT。- 真正会"整表替换"的是单个 key 的 value:
ModelRatio的 value 是一整个 JSON 对象,
你 PUT 一个只含自己十几个模型的ModelRatio,ModelRatio里其余几百项就被清掉了,
未配置模型回落到 37.5 倍率(= $75 / 1M tokens) 的兜底。
正确姿势:GET /api/option/→ 解析出该 key 的完整 JSON → merge 自己的模型 → 再 PUT 回去。
(UpdateModelPricingOptions内部会读全表定价键再整体写回,但它读的是库里已有的值,不是请求里的值,
所以只覆盖你传的那个 key。) - 脏值毒化:只要
options里任一 pricing key 的值不是合法 JSON(实测被写成了字面量<nil>),UpdateModelPricingOptions在写入前会先反序列化所有 pricing key 的旧值,
读到<nil>直接返回invalid character '<' looking for beginning of value,
之后任何一次定价修改都会success:false。修法:直接UPDATE options SET value='<合法JSON>'
或删行恢复默认,然后重启进程。 ServerAddress为空会让面板给客户端展示的 Base URL 变成http://localhost:3000。
自建反代对外服务时一定要设成公网地址,否则用户照抄填不上。
设完passkey_rp_id之类的派生项也会自动跟随。- 未配置模型的兜底是 37.5 倍率;非自用模式(
SelfUseModeEnabled=false)下success=false,
请求直接报modelPriceNotConfiguredError。 CompletionRatio对 Claude 4 / gemini-3-pro / gpt-5.x 有硬编码兜底,Claude 系标locked=true,
会覆盖你配的值。- 推理档位后缀
-high/-low/-thinking/-medium在计费时由resolveBillingModelName
剥离后查表,所以配基名即可;为稳妥可基名与带后缀名都写。 - 不要点
Reset prices:会把整表还原成内置默认,而内置默认里没有任何gemini-3.x、
也没有claude-sonnet-4-6。 - Gemini 的缓存按
$/1M tokens·小时收存储费,没有按 token 的缓存写入费,create_cache_ratio对 Gemini 无对应口径。 ModelPrice优先于ModelRatio:如果某模型在ModelPrice中配置了按次计费(如gemini-3.5-flash-lite: 0.005),
New-API 会直接走按次扣费,完全忽略ModelRatio的 token 倍率。若希望按 token 倍率计费,必须从ModelPrice字典中删除该模型。CPA(CLI-Proxy-API)模型更新机制与二进制更新必要性:
- CPA 会自动远程拉取
models.json/codex_client_models.json,但仅靠自动拉取无法完全支持 Codex 协议大版本升级。 - 原因:OpenAI Codex 上游协议升级时伴随客户端版本校验(如 v7.3.13 将
defaultClientVersion从 0.154.0 升级到 0.155.0,以及更新 User-Agent 请求头),且不同套餐(如codex-free)支持哪些模型(如gpt-6-luna)由 CPA 二进制逻辑硬编码映射。 - 因此当 OpenAI Codex 推出新模型或更新协议时,必须下载最新 Release 替换
/opt/relay/cpa/cli-proxy-api二进制并重启服务。
- CPA 会自动远程拉取
验证方法
GET /api/option/回读,确认目标 key 的值与你写入的一致,且键数没有变少。- 对每个 pricing key 做一次
json.loads合法性检查(防<nil>之类的毒化)。 - 发一次真实请求(小 prompt 即可,不要拿上游打压测),看日志里
record consume log的model_ratio/completion_ratio/cache_ratio是否等于目标值。
实例:gpt-5.6-luna改前 0.5 → 改后 0.1,8+5 token 的请求 quota 从 19 降到 4。 - 想确认接口没被毒化,做一次空写测试:把自己刚读到的值原样 PUT 回去,应返回
success:true。
本次实例证据
- 机器与库:LA 容器
/opt/relay/na/one-api.db(/opt/relay/na/logs/为日志) - 官方价核对与逐条倍率清单:
outputs/newapi_pricing_plan_20260918.md - 改配置前后快照:
work/na_pricing_backup.json、work/na_pricing_new.json(容器内/root/na_pricing_*.json) - 数据库备份(修
<nil>之前):/root/one-api.db.bak-20260918_003514 2026-09-23 调价与升级:
- CPA 二进制升级至
v7.3.15(支持 Codex client 0.155.0 与gpt-6-luna)。 - CPA Antigravity 模型(Gemini 3.x 全系、Claude 4.x 全系及
gpt-oss-120b-medium)倍率统一调整为0.35。 - 从
ModelPrice移除了gemini-3.5-flash-lite,解除其 0.005 固定按次扣费,使 0.35 倍率生效。 - Codex 代理出的所有模型(
gpt-5.5、gpt-5.6-terra、gpt-5.6-luna、gpt-5.6-sol、gpt-6-luna、gpt-6-sol、gpt-6-astra、gpt-reserve)倍率统一调整为0.1。 - Channel 1 同步挂载
gpt-6-luna等新模型。
- CPA 二进制升级至
- 未核实模型(官网无该 model id):
gemini-pro-agent,倍率跟从 Antigravity 统一配为 0.35。
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps