refactor(billing): 长上下文阶梯计价改为价格目录数据驱动 - #6353
Open
feeeei wants to merge 3 commits into
Open
Conversation
删除 GPT/Gemini 系列写死的阶梯规则,阶梯一律由目录数据驱动: - 解析层折算 LiteLLM 的 *_above_XXXk_tokens 绝对价字段为阈值+倍率 (阈值取自字段名,倍率 = above/基础价,cache 侧跟随输入倍率, xAI 按 provider 用达到即进高档语义);显式 long_context_* 字段 按"字段存在"优先,显式 threshold=0 或 multiplier=1 可关闭阶梯 - 删除 OpenAI 272K 常量与 applyModelSpecificPricingPolicy 的长上下文 强补分支、fallbackPrices/静态兜底条目的 LongContext 字段、Gemini 旧 边际规则全链路(CalculateCostWithLongContext / RecordUsageWithLongContext / 阶梯表 marginal 基准);保留 fastRatio 与 GPT-5.6 cache_write 1.25x 防御分支、grok 静态兜底阶梯 - 渠道配置定价区间时完全以渠道区间为准,不再叠加目录阶梯 - 长上下文倍率 ≤0 在应用点按 1 计,防止显式字段残缺把分项乘 0 免费 - 目录重载时对比新旧数据,原有阶梯丢失打 WARN 哨兵告警 行为变化:Gemini 由边际 2x(仅 /v1beta、全模型)改为整单换档(数据 驱动、仅带 above_200k 的 pro 系),渠道平价之上叠加目录阶梯;Claude sonnet-4/4.5 随目录数据获得 200K 整单阶梯(与官方定价一致);模型广场 官方参考价列与实付列同源展示目录阶梯。
新增 pricing.override_file 配置(默认关闭):稀疏补丁文件按 JSON 字段 浅合并覆盖目录/回退数据,作为最高优先级数据源,用于本地自定义官方 目录条目(如显式 long_context_input_token_threshold=0 关闭某模型阶梯) 而无需自建价格镜像: - applyPricingOverrides 挂在 parsePricingData 解析入口,只修补已存在 条目(补丁字段覆盖同名字段,值为 null 删除字段);目录、回退与灾备 路径都经该入口,覆盖语义三处一致 - mergeOverrideOnlyModels 在回退合并后把目录/回退都没有的模型作为 独立条目并入(复用主解析路径,须自带价格字段通过有效性过滤); 不在主解析时抢先建条目,避免纯补丁挡住回退完整条目、其余分项价 静默变 0 - 最终未生效的条目(模型名拼错、纯补丁落在不存在的模型上)打 WARN 哨兵;override 文件缺失/损坏仅跳过合并,不影响目录加载 - 生效时机为重启或下次目录下载,与 fallback_file 一致;fallback_file 只补缺失模型的语义不变
阶梯计价数据驱动后,目录条目的字段缺失或版本拼接会直接变成计费偏差, 解析层补两道数据契约哨兵,并修正出厂快照中 Gemini pro 系的缓存写入价: - orphanCacheTierFields / warnOrphanCacheTierFields:条目带 cache 侧 above 档(含 _priority/_flex 变体与 above_1hr 形态)却没有基础价时打 WARN——cache 侧 above 档不参与计费取值,按"基础价 × 输入倍率"计,基础价 缺失即该分项按 0 计;变体缺自身基础价时沿 变体→1h→标准 回落链任一存在 即不算孤儿,与计费回落一致 - isLopsidedLongContextLadder / warnLopsidedLongContextLadders:above 档 折算出只有一侧带附加费的阶梯时打 WARN(基础价与 above 档来自不同价格 版本的形态),显式 long_context_* 字段不告警 - deriveLongContextFromAboveTierFields 注释改为陈述契约:cache above 档 须恰为基础价 × 输入倍率 - 出厂快照 6 个 Gemini pro 条目补 cache_creation_input_token_cost(= 标准 输入价,Google 对缓存写入不另收费)、above_200k 改为输入 above 价、带 priority 输入价的 4 条补 priority 孪生,与 model-price-repo 数据修正同值 测试: - 解析层:孤儿字段 WARN(含 priority/1h 孤儿正例、1h 回落 5m 反例)、单侧 阶梯 WARN、出厂快照契约(全条目无孤儿字段、无单侧阶梯、Gemini pro 缓存 写入价 = 输入价) - 用量契约:extractGeminiUsage 与 Antigravity 非流式/流式转换均不产生 cache_creation token(Gemini usageMetadata 无该类别) - 计费:gemini-2.5-pro 阶梯对 cache_read / cache_creation 分项生效,阈值 计入缓存写入 token;阶梯表场景与夹具同步为现行目录值
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
请先合并 Wei-Shaw/model-price-repo#20 再合并本 PR。
本 PR 删除了代码侧的全部长上下文阶梯兜底,阶梯完全依赖价格目录数据(
*_above_XXXk_tokens字段)。#19 是配套的目录数据修正;若本 PR 先合并,依赖那批修正条目的部署会在间隙期按基础价计费(少收)。之前错了什么
1. 阶梯规则写死在代码里,与数据源长期脱节
input/output_cost_per_token_above_272k_tokens等绝对价字段,但代码从未解析过它们(全仓rg above_272k零命中)long_context_input_token_threshold/*_cost_multiplier三字段——这套约定在远程目录数据里出现 0 次,唯一载体是 resources fallback 文件里 gpt-5.6 三个条目(运行时被同步数据遮蔽,等于死配置)applyModelSpecificPricingPolicy对 GPT 系强补 272K,目录数据无法关闭它2. Gemini 旧规则与 Google 官方定价存在三处偏差
3. Grok 阶梯从未生效:目录条目(无阶梯字段)优先遮蔽了带阶梯的 Go 兜底价卡——数据侧已在 #19 修复,本 PR 合并后自然生效,无需再改代码。
改成了什么
deriveLongContextFromAboveTierFields把目录的above_XXXk绝对价折算成阈值+倍率——阈值取自字段名,倍率 = above 价 ÷ 基础价,cache 侧跟随输入倍率;_flex/_priority变体与above_1hr(缓存时长)不参与。语义与 LiteLLM 官方 cost calculator 同构:整单换档、严格>、唯 xAI 用≥long_context_*字段按"字段存在"优先:写threshold: 0或multiplier: 1即可在数据层显式关闭某模型的阶梯usesOpenAILegacyLongContextPricing、六个 fallback 价卡的 LongContext 字段、Gemini 旧边际链路(CalculateCostWithLongContext/RecordUsageWithLongContext/ 阶梯表 marginal 基准)。保留 fastRatio 与 GPT-5.6 cache_write 1.25x 两个分支——它们防御的目录数据缺陷(LiteLLM 把 5.5 priority 错标 2x、5.6 缺 cache_write 价)至今存在新增:
pricing.override_file本地覆盖补丁阶梯改由数据驱动后,"显式
threshold: 0关某个模型的阶梯"、"修正个别条目价格"这类操作只剩改目录数据一条路——但自托管部署不控制 model-price-repo:fallback_file只补目录缺失的模型(无法覆盖已有条目),直接改data/model_pricing.json又会被哈希同步覆盖。数据驱动缺了一个部署方自控的持久覆盖入口,本 PR 一并补上:pricing.override_file(默认空 = 关闭,零行为变化):稀疏补丁 JSON,条目按字段浅合并覆盖目录/回退数据,最高优先级;字段值null删除该字段;目录、回退、灾备三条解析路径同语义fallback_file一致fallback_file分工明确、语义互不影响:fallback 补缺失(灾备快照 + 自定义新模型),override 覆盖已有(最高优先级稀疏补丁)示例——某部署想让 gpt-5.5 按 272K 标准价、不启用阶梯:
{ "gpt-5.5": { "long_context_input_token_threshold": 0 }, "gpt-5.5-2026-04-23": { "long_context_input_token_threshold": 0 } }影响了什么
marginal计价基准不再产生,前端枚举保留兼容测试
make test-unit54 个包全绿Related: #6440