news 2026/10/2 20:30:19

大模型API价格目录开源:从计费建模到成本对比的工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大模型API价格目录开源:从计费建模到成本对比的工程实践

1. 从“查价查到头大”说起:这个开源目录到底解决了什么

国内大模型 API 的价格,是我最近半年被问得最多的问题之一。不是“哪个模型最强”这种主观题,而是非常具体的:“DeepSeek 现在多少钱一百万 token?”“智谱和通义哪个便宜?”“有没有那种输入输出分开计价的对照表?”问的人里有做 RAG 应用的独立开发者,有给公司选型的技术负责人,也有纯粹想拿 API 练手的学生。大家的共同痛点是:价格信息散落在各家官网、文档、公告里,口径还不统一,有的按千 token 报价,有的按百万 token,有的输入输出同价,有的分档计价,还有的搞限时折扣。你打开五个浏览器标签页,最后还是会算错。

这个开源目录项目,就是冲着这个痛点去的。它做的事情听起来很朴素——把国内主流大模型 API 的价格整理成一个结构化、可查询、可对比的目录。但真正让它有意思的,是标题里那句“连 DeepSeek 的‘梁文谷时间’都建模了”。这不是玩梗,而是一个很实际的设计决策:大模型的计费不是静态的,它有时段差异、缓存命中差异、上下文长度分档这些维度,如果只做一个静态价格表,用不了两周就过时了。所以这个目录本质上是一个带时间维度和计费规则建模的价格数据库,而不是一张 Excel 截图。

适合谁来参考这篇内容?三类人。第一类是想选型但被价格绕晕的开发者,你可以直接拿这个目录的思路去建自己的对比表;第二类是想自己做一个类似工具的人,我会把数据建模、字段设计、更新机制这些坑讲清楚;第三类是纯粹好奇“一个价格目录能有多复杂”的读者,看完你会明白为什么这件事值得开源。关键词里的大模型、API、DeepSeek、开源目录、建模,基本就是这篇文章的主线,我会围绕它们把整个项目的设计逻辑和实操细节拆开讲。

2. 价格目录不是表格:先搞清楚大模型 API 的计费维度

2.1 为什么“一张价格表”注定失败

很多人第一反应是:价格目录嘛,不就是模型名加一个单价?我一开始也这么想,直到我试着把五家厂商的价格填进同一张表,发现根本对不齐。问题出在计费维度上。国内大模型 API 的计费,至少涉及以下几个正交维度:

  • 计费单位:有的按“元/千 token”,有的按“元/百万 token”,换算时小数点容易错位。
  • 输入输出分离:DeepSeek、智谱等很多模型输入和输出价格不同,输出通常更贵,因为生成比理解更耗算力。
  • 上下文分档:同一个模型,上下文长度不同价格不同。比如某些模型 32K 以内一个价,128K 以上另一个价。
  • 缓存命中:这是最容易被忽略的。DeepSeek 的上下文缓存命中价格远低于未命中价格,如果你做的是多轮对话或 RAG,缓存命中率直接决定成本。
  • 时段差异:这就是标题里说的“梁文谷时间”的来源。DeepSeek 在某些时段有折扣计价,价格随时间段浮动。

如果你只做一个“模型名 → 单价”的映射,上面五个维度全部丢失,算出来的成本可能和实际账单差好几倍。所以这个目录的第一个设计决策就是:不把价格当成一个数字,而是当成一个带条件的计费规则。

2.2 “梁文谷时间”到底是什么:时段计费的建模思路

“梁文谷时间”这个说法,是社区里对 DeepSeek 特定优惠时段的戏称,带着点调侃,但背后是一个真实的计费机制:同一模型在不同时间段调用,单价不同。这在云服务里其实不新鲜,比如某些云厂商的闲时算力更便宜,但落到大模型 API 上,很多人没意识到。

建模这个机制,关键是要把“时间”变成一个可查询的维度。我的做法是给每条价格记录加一组字段:

字段名含义示例
model_id模型唯一标识deepseek-chat
price_type计费类型input / output / cache_hit / cache_miss
unit计价单位per_million_tokens
amount单价数值1.0
currency币种CNY
time_window生效时段00:30-08:30
context_tier上下文分档0-32K / 32K-128K
effective_from生效起始日2025-01-01
effective_to生效截止日空表示长期

这样一条记录表达的是:“deepseek-chat 的输入价格,在 00:30 到 08:30 这个时段,上下文 32K 以内,是每百万 token 1 元”。查询时先按当前时间匹配time_window,再按上下文长度匹配context_tier,最后按调用类型取对应price_type。这套建模的价值在于,它把“价格会变”这件事变成了数据结构的一部分,而不是靠人工记忆。

提示:时段计费一定要用本地时区还是厂商时区,必须在字段里明确。我踩过的坑是拿 UTC 时间去做匹配,结果优惠时段整体偏移了八小时,算出来的成本完全不对。

2.3 缓存命中为什么必须单独建模

缓存命中价格是另一个不能合并的维度。以 DeepSeek 为例,缓存命中的输入价格可以低到未命中的十分之一甚至更低。如果你做的是固定系统提示词加多轮对话的应用,命中率可能很高,实际成本远低于按未命中价格估算的结果。

建模时要注意:缓存命中只影响输入侧,输出侧价格不变。所以price_type里要区分input_cache_hit和input_cache_miss,而不是笼统的input。另外,缓存有有效期,过期后重新计算,这个有效期也应该作为一个字段记录下来,否则你无法判断“我隔了十分钟再问同样的问题,还算不算命中”。

3. 目录的数据结构设计:字段、分档与更新机制

3.1 核心字段清单与设计理由

把计费维度想清楚之后,字段设计就顺理成章了。下面是我实际用的一套字段,你可以直接抄:

{ "provider": "deepseek", "model_id": "deepseek-chat", "model_name": "DeepSeek Chat", "price_type": "input_cache_miss", "unit": "per_million_tokens", "amount": 2.0, "currency": "CNY", "context_tier": {"min": 0, "max": 32768}, "time_window": null, "cache_ttl_seconds": 3600, "effective_from": "2025-01-01", "effective_to": null, "source_url": "官方定价页链接", "updated_at": "2025-01-15T10:00:00+08:00" }

几个字段值得单独说。source_url是溯源字段,价格目录最怕的就是“这个数字哪来的”,有了它,任何人可以复核。updated_at是新鲜度字段,价格会变,读者需要知道这条记录是什么时候抓的。effective_from/to是版本字段,支持历史价格查询,也支持“某天之后涨价了”这种场景。

context_tier用对象而不是字符串,是为了方便程序做区间匹配。如果你用"0-32K"这种字符串,查询时还得解析,容易出错。用{min, max}数值区间,匹配逻辑就是一行判断。

3.2 上下文分档的边界处理

上下文分档有个很容易踩的坑:边界值归哪一档。比如 32K 这个点,是算在 0-32K 还是 32K-128K?不同厂商的文档表述可能不一样,有的写“不超过 32K”,有的写“32K 以上”。我的处理方式是:区间采用左闭右开,即[min, max),32K 归到下一档。同时在数据里显式记录厂商原文表述,避免歧义。

另一个坑是分档计价可能是阶梯式的。有的模型不是“整个请求按所在档计价”,而是“前 32K 按低价,超出部分按高价”。这两种模式成本差异很大,必须在字段里区分。我加了一个pricing_mode字段,取值flat(整档统一价)或tiered(阶梯累进)。如果是tiered,amount就要变成一个数组,记录每一档的单价。

3.3 更新机制:人工核对加自动化提醒

价格目录的生死线是时效性。我的做法是双轨制:一方面写一个简单的抓取脚本,定期去各家官方定价页抓取文本,做差异比对;另一方面保留人工核对环节,因为很多厂商的价格调整是通过公告发布的,页面不一定同步更新。

抓取脚本的逻辑不复杂:把官方页面转成纯文本,用正则提取价格数字,和数据库里的当前值比对,不一致就生成一条待确认记录。注意不要自动写入,因为页面改版、文案调整都可能造成误报。我试过全自动写入,结果某次厂商把“限时优惠”四个字去掉,脚本把优惠价当成了正式价,差点误导用户。

提示:给每条价格记录加一个confidence字段,标记“官方页面确认”“公告确认”“社区反馈待核实”。读者看到低置信度的数据会自己留个心眼,这比假装所有数据都准确要诚实得多。

4. 从零跑通这个目录:实操步骤与代码骨架

4.1 环境准备与依赖选择

这个项目对环境的依赖很轻,核心就是数据存储和查询。我推荐的技术栈是Python + SQLite + 一个轻量 Web 框架。为什么不用 MySQL 或 PostgreSQL?因为价格目录的数据量很小,几千条记录顶天了,SQLite 完全够用,而且单文件便于分发,别人 clone 下来就能跑。Web 框架用 FastAPI 或 Flask 都行,FastAPI 自带文档页面,查询接口调试起来方便。

依赖清单大致是:

pip install fastapi uvicorn sqlalchemy pydantic httpx beautifulsoup4

httpx和beautifulsoup4是给抓取脚本用的,如果你只做手动维护,这两个可以不装。sqlalchemy负责 ORM 映射,pydantic负责数据校验,这两个是核心。

4.2 建表与数据导入

建表语句的关键是把前面说的字段都落进去。下面是一个简化版:

CREATE TABLE price_records ( id INTEGER PRIMARY KEY AUTOINCREMENT, provider TEXT NOT NULL, model_id TEXT NOT NULL, model_name TEXT, price_type TEXT NOT NULL, unit TEXT NOT NULL, amount REAL NOT NULL, currency TEXT DEFAULT 'CNY', context_min INTEGER DEFAULT 0, context_max INTEGER, time_window_start TEXT, time_window_end TEXT, cache_ttl_seconds INTEGER, pricing_mode TEXT DEFAULT 'flat', effective_from TEXT, effective_to TEXT, source_url TEXT, confidence TEXT DEFAULT 'official', updated_at TEXT );

导入数据时,我建议先用一个 YAML 或 JSON 文件维护原始数据,再写脚本导入数据库。这样做的好处是数据可版本控制,每次价格调整在 Git 里都有记录,比直接改数据库可追溯得多。

4.3 查询接口的设计

查询接口要支持几个典型场景:按模型查当前价、按厂商列全部模型、按时间点查历史价、按预估用量算成本。前三个是查询,第四个是计算。计算接口的输入是模型、输入 token 数、输出 token 数、缓存命中率、调用时间,输出是预估成本。

成本计算的逻辑要按前面建模的维度逐层匹配:

def estimate_cost(model_id, input_tokens, output_tokens, cache_hit_rate, call_time): records = get_active_records(model_id, call_time) input_price = match_price(records, 'input_cache_miss', input_tokens) cache_price = match_price(records, 'input_cache_hit', input_tokens) output_price = match_price(records, 'output', input_tokens) effective_input = input_price * (1 - cache_hit_rate) + cache_price * cache_hit_rate cost = (effective_input * input_tokens + output_price * output_tokens) / 1_000_000 return cost

这段代码里match_price要处理时段匹配和上下文分档匹配。注意除数是 1_000_000,因为我们的单位是每百万 token,如果你按千 token 存,这里要改成 1000。单位换算是价格目录最容易出错的地方,我建议在代码里加断言,确保单位一致。

4.4 一个容易忽略的细节:token 数怎么估

成本计算的前提是知道 token 数。很多人直接用字符数除以某个系数,这在不同模型上误差很大。中文一个汉字大约对应 0.6 到 1 个 token,英文一个单词大约 1.3 个 token,代码和标点又不一样。我的建议是:如果只是粗略估算,用字符数除以 1.5 作为中文场景的经验值;如果要精确,就调用厂商提供的 tokenizer 或计数接口。目录本身不负责计数,但可以在文档里给出估算公式,避免用户拿着不准的 token 数来算成本,然后觉得目录算错了。

5. 实测中的坑:时区、单位与“看起来便宜”的陷阱

5.1 时区错位导致优惠时段完全失效

前面提过一次,这里展开讲。我最初做时段匹配时,用的是服务器时间,而服务器默认 UTC。DeepSeek 的优惠时段是按北京时间定义的,结果我的匹配逻辑整体偏移了八小时,本该命中优惠的调用全部按原价计算。排查过程是这样的:先打印当前时间和时段字段,发现时间对不上;再检查时区配置,发现datetime.now()返回的是 UTC;最后统一改成datetime.now(ZoneInfo("Asia/Shanghai"))才正常。

这个坑的教训是:凡是涉及时间的字段,必须显式声明时区。数据库里存的时间字符串要带偏移量,代码里做比较前先统一时区。不要依赖服务器默认时区,那是个隐藏的定时炸弹。

5.2 单位换算:千 token 和百万 token 的混用

第二个坑是单位。有的厂商文档写“0.001 元/千 token”,换算成每百万 token 就是 1 元。听起来简单,但当你有几十个模型、上百条记录时,手工换算必然出错。我的做法是:数据库统一存每百万 token 的价格,导入时做一次换算,并在导入脚本里加校验。校验逻辑是:如果原始单位是千 token,数值乘以 1000;如果是百万 token,保持不变;其他单位直接报错。

还有一个隐蔽问题:有的厂商输出价格按“元/千 token”给,输入价格按“元/百万 token”给,同一张表里两种单位混着。如果你不逐条核对,很容易把输出价格少算一千倍。我建议在数据文件里每条记录都显式写单位,不要靠上下文推断。

5.3 “看起来便宜”的模型可能更贵

这是选型时最反直觉的一点。有些模型单价很低,但它的 tokenizer 对中文不友好,同样一段中文,它消耗的 token 数比别人多。结果单价便宜,实际成本反而高。还有一种情况是输出价格极低,但模型喜欢“啰嗦”,输出 token 数远超预期。

所以看价格目录时,不能只看单价,要结合典型场景的 token 消耗一起看。我在目录里加了一个“场景估算”页面,预设几种常见任务(比如 1000 字中文摘要、多轮客服对话、代码补全),用各模型的 tokenizer 估算消耗,再乘以单价,给出实际成本对比。这个页面比单纯的价格表有用得多,因为它回答的是“我干这件事要花多少钱”,而不是“每个 token 多少钱”。

提示:如果你做的是 RAG 应用,检索到的文档会大幅增加输入 token。这时候输入价格和缓存命中率比输出价格重要得多。选型时优先看输入侧成本,别被低输出价迷惑。

6. 这个目录还能怎么扩展:从价格到选型决策

6.1 加入延迟和可用性维度

价格只是选型的一个维度。实际做应用时,延迟和可用性同样关键。一个模型再便宜,如果响应要十秒,用户体验就崩了。所以我在目录里预留了latency_p50、latency_p95、availability这几个字段,虽然目前数据还不全,但结构先留好。

延迟数据的采集可以自己跑基准测试,也可以收集社区反馈。我的做法是写一个简单的压测脚本,对每个模型发固定长度的请求,记录响应时间,跑几百次取分位数。注意压测要控制并发,并发太高会触发限流,测出来的延迟不准。

6.2 用价格数据做成本预警

目录的另一个用法是成本预警。如果你在跑一个长期应用,可以把每日 token 消耗和当前价格结合,算出每日成本,设置阈值告警。价格调整时,告警阈值自动跟着变。这个功能对预算敏感的项目很实用,尤其是那些按量付费、没有预算上限的场景。

实现上,就是定时任务拉取用量数据,乘以目录里的当前价格,和历史均值比对。如果某天成本突然翻倍,可能是价格调整,也可能是用量异常,两种情况都值得看一眼。

6.3 社区共建与数据可信度

价格目录这种项目,单靠一个人维护很难覆盖所有厂商和所有调整。开源的价值就在这里:让用的人顺手提交更新。我在项目里加了一个简单的提交模板,用户发现价格不对,可以提 issue 或 PR,附上官方链接和截图。维护者核对后合并,数据就更新了。

为了保证可信度,每条记录都有confidence和source_url,读者可以自己判断。不要追求“绝对准确”,要追求“可追溯”。一个标注了来源和更新时间的 95% 准确的数据,比一个号称 100% 准确但没有来源的数据有用得多。

6.4 我个人的使用体会

最后分享一点实际用下来的感受。这个目录我最初是给自己用的,因为我要在几个模型之间切换做实验,每次算成本都要翻文档,烦得不行。做成结构化数据之后,最大的变化不是“查得快”,而是我能做以前做不了的对比。比如我可以按“中文摘要任务的实际成本”排序,而不是按单价排序,结果经常和直觉相反。有些单价高的模型,因为 tokenizer 效率高、输出简洁,实际成本反而低。

另一个体会是:价格数据要当成会过期的数据来对待。我现在的习惯是每次做重要决策前,先看目录里对应记录的updated_at,如果超过一个月,就手动去官网复核一遍。这个习惯帮我避免过好几次“拿着旧价格做预算”的尴尬。如果你也在做类似的价格整理,我的建议是:结构设计上多花时间,把维度想全;数据维护上保持克制,宁可标注“待核实”,也不要填一个不确定的数字。目录的价值不在于数字多全,而在于你看到每个数字时,都知道它从哪来、什么时候有效、适用于什么条件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 20:29:37

RK3588双路YOLOv5s部署:线程池调度与NPU并发实战

做嵌入式AI部署的人应该都有同感:单路跑通检测只是入门,真正折磨人的是双路甚至多路视频流同时稳定运行。香橙派5这块RK3588板子,NPU算力标称6 TOPS,单路跑一个INT8量化的YOLOv5s模型,帧率轻松破百,但你要是…

作者头像 李华
网站建设 2026/10/2 20:28:40

AI新闻日报_2026-07-07:用TaoToken统一Key追踪Agent与AI Coding动态

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 20:27:12

ESP32双协议网关:WiFi与BLE融合的智能家居实战

1. 项目概述:用ESP32把WiFi和BLE捏合到一套智能家居里家里设备多起来之后,我最大的痛点不是“缺一个遥控器”,而是为了控制不同东西装了五六个App:灯的App、插座App、加湿器App、体脂秤App,界面各不相同,数…

作者头像 李华
网站建设 2026/10/2 20:26:28

全速域PMSM无感FOC控制:高频注入与滑模观测器的工程实现

1. 项目解读与全速域无感控制选型1.1 这个版本到底在解决什么问题搞电机控制的兄弟看到这个工程名应该会心一笑。B1.1版本,全速域永磁同步电机无感控制,低速段用高频注入做转子初始位置辨识,中高速段交给滑模观测器SMO,中间用权重…

作者头像 李华