构建AI模型价格追踪数据集:从数据采集到开源实践
1. 项目概述:为什么我们需要一个AI模型价格追踪数据集?
做AI应用开发或者研究的朋友,最近一年应该都有同感:大语言模型(LLM)的定价策略,简直比天气还多变。今天GPT-4 Turbo刚降价,明天Claude 3 Opus就宣布调整输入输出token的计费比例,后天某个开源模型在云服务商那里的托管价格又悄悄涨了10%。对于需要长期、稳定调用这些API的团队来说,这不仅仅是技术选型问题,更直接关系到项目的预算和可持续性。
“Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models”这个项目,就是在这种背景下诞生的。它不是一个复杂的软件系统,而是一个朴素却极其有用的公共数据集:每月自动追踪并更新22个主流AI模型的定价数据,并以结构化格式(如CSV、JSON)开源。我最初注意到这个需求,是因为自己在规划一个需要混合调用多个模型的服务时,被繁琐的价格对比和动态更新搞得焦头烂额。手动从各个厂商的文档里扒数据,不仅效率低下,还容易出错,更别提那些隐藏在角落里的“按量阶梯折扣”和“承诺使用折扣”了。
这个数据集的核心价值在于,它将原本分散、非结构化、频繁变动的商业信息,变成了一个集中、结构化、版本化的公共资源。无论是想快速进行模型成本对比的开发者,还是需要做长期趋势分析的行业研究者,亦或是教学机构里想让学生理解AI经济学的人,都能从中直接获益。它解决的不是一个“从0到1”的技术难题,而是一个“从混乱到有序”的信息工程问题,极大地降低了行业的信息摩擦成本。
2. 数据集设计与架构思路拆解
2.1 数据模型设计:如何定义“价格”?
设计这样一个数据集,第一个要回答的问题就是:什么才算是一个模型的“价格”?这听起来简单,实则充满细节。一个完整的LLM API价格至少包含以下几个维度:
- 输入Token价格:处理用户提示(Prompt)的成本,通常按每百万tokens(MTok)计价。
- 输出Token价格:生成模型回复(Completion)的成本,同样按每MTok计价。许多模型(如GPT-4、Claude系列)的输入输出价格是不同的。
- 定价单位:绝大多数按Token计费,但也有按请求次数、按时间(如每分钟)计费的模型或特殊端点,需要统一标注。
- 上下文窗口:价格往往与模型支持的最大上下文长度相关。例如,同一个模型可能有8K、32K、128K等不同上下文版本的定价。
- 区域与提供商:同一个模型在不同云服务商(如AWS Bedrock, Azure OpenAI, Google Vertex AI)或不同区域的价格可能有差异。
- 折扣与承诺计划:厂商提供的预留容量、承诺消费折扣等,这些属于衍生价格信息,可以作为附加字段。
在项目的数据模型里,每一条记录可能对应一个“模型-上下文窗口-提供商”的组合。核心字段设计如下表示例:
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
model_id | String | 模型唯一标识符 | gpt-4-turbo-preview |
provider | String | 服务提供商 | OpenAI,Anthropic,Together AI |
context_window | Integer | 最大上下文长度(tokens) | 128000 |
input_price_per_mtok | Float | 输入价格(美元/MTok) | 10.00 |
output_price_per_mtok | Float | 输出价格(美元/MTok) | 30.00 |
currency | String | 货币 | USD |
effective_date | Date | 价格生效日期 | 2024-03-01 |
pricing_page_url | String | 官方定价页面链接 | 用于溯源和验证 |
notes | String | 备注(如折扣条件) | “价格适用于承诺年消费$10K以上用户” |
注意:
input_price_per_mtok和output_price_per_mtok是核心字段。对于不按Token计费的模型,可以将其设为NULL,并通过notes字段说明其计费模式。
2.2 数据源与采集策略:自动化与可信度的平衡
数据集的准确性是生命线。22个模型,每月更新,靠人工维护是不现实的,必须自动化。但自动化爬取官方页面又面临几个挑战:页面结构变更、反爬机制、以及非结构化文本中价格的提取。
一个稳健的采集策略应该是分层级的:
- 第一优先级:官方API与状态页。部分提供商(如OpenAI)有公开的、结构化的API端点可以查询当前价格。这是最可靠的数据源。
- 第二优先级:结构化文档。有些厂商会在开发者文档中通过表格形式列出价格,相对容易解析。
- 第三优先级:定价页面HTML。这是最通用但也最脆弱的方式。需要编写针对每个页面的解析器(parser),并做好页面结构变更的监控和告警。
- 人工校验层:每月数据生成后,必须有一个快速的人工校验流程,抽查关键模型的价格是否合理。可以设置简单的阈值告警,比如某个模型价格环比波动超过50%,则触发人工复核。
在技术实现上,可以用Python编写一套爬虫集群,每个爬虫负责一个或一组提供商。使用requests或playwright库获取页面内容,用beautifulsoup或正则表达式提取价格数字和关联的模型名称。关键是要将提取逻辑与数据模型解耦,这样当某个页面改版时,只需更新对应的提取器,而不影响整体流程。
2.3 版本控制与更新机制
“Monthly”是这个项目的关键。价格数据是时间序列数据,必须保留历史记录才能进行趋势分析。因此,数据集不能简单地覆盖更新,而必须进行版本控制。
最直接的方式是利用Git。每月定时任务触发采集脚本,生成以日期命名的新数据文件(如prices-2024-03.csv),提交到Git仓库。这样,用户可以通过查看Git历史记录,轻松回溯任何日期的价格。同时,可以维护一个latest.csv的符号链接或自动更新的文件,指向最新的数据,方便大多数用户使用。
更新机制的核心是一个可靠的定时任务调度器(如GitHub Actions, Cron Job)。每月1号自动运行采集流程,如果采集成功且通过基础校验(如数据格式完整、关键模型数据存在),则自动提交并推送到主仓库。整个过程应尽可能无人值守,但必须有失败通知机制(如发送邮件或Slack消息),以便维护者及时介入。
3. 核心实现细节与实操要点
3.1 爬虫编写的避坑指南
编写价格爬虫,最怕的不是技术难点,而是厂商页面毫无征兆的改版。以下是几个从踩坑中总结出的经验:
第一,必须实现健壮的选择器。不要只依赖一个CSS选择器路径。比如,定位价格表格时,可以组合使用多个特征:table标签、包含“$”符号的文本、附近的模型名称标题等。这样即使表格的class名变了,只要大体结构还在,爬虫仍有很大概率能定位到数据。
# 一个相对健壮的价格提取思路(伪代码) def extract_price_from_page(html, model_name): soup = BeautifulSoup(html, 'html.parser') # 策略1:寻找所有包含货币符号的文本节点 price_elements = soup.find_all(text=re.compile(r'\$[\d\.]+')) # 策略2:寻找所有<table>,并检查其内容是否包含模型名和价格 tables = soup.find_all('table') for table in tables: if model_name in table.text and '$' in table.text: # 进一步解析这个table return parse_table(table) # 策略3:如果以上都失败,尝试更通用的文本扫描和正则匹配 # ... return None第二,设置请求频率限制与伪装头。即使页面没有反爬,也应遵守robots.txt并设置合理的请求间隔(如每请求一次休眠2-5秒)。务必设置真实的User-Agent头,模拟浏览器访问。
第三,实现重试与降级机制。网络请求可能失败,页面可能临时不可用。爬虫代码中必须包含重试逻辑(如使用tenacity库)。如果主要数据源失败,应尝试降级到备用数据源(如官方博客公告、第三方汇总文章)。
第四,保存原始HTML快照。每次爬取时,不仅保存解析后的结构化数据,还应将原始HTML页面保存下来(可以压缩后存储)。当后续发现某个月份的数据有疑问时,可以回溯查看原始页面进行验证,这是数据可审计性的关键。
3.2 数据清洗与验证的自动化流程
爬取到的原始数据是“脏”的,必须经过清洗和验证才能入库。这个过程也应该自动化。
- 格式标准化:价格字符串可能包含“$10.00 / MTok”、“10.00 USD per million tokens”等多种形式。需要统一清洗为纯浮点数,并明确单位。货币符号、千位分隔符(逗号)都需要处理。
- 单位换算:有些页面可能按每千tokens(KTok)报价,需要统一换算为每百万tokens(MTok)。
- 关联校验:检查提取的模型名称是否在预定义的22个模型列表中。如果出现一个未知的模型名(可能是厂商发布了新模型),应触发告警,由维护者决定是否将其加入列表。
- 逻辑校验:实施一些简单的业务规则校验。例如:
- 输出价格通常不低于输入价格(对于大多数自回归生成模型成立)。
- 上下文窗口更大的版本,其单价通常不会低于小窗口版本。
- 与上月数据相比,价格波动是否在合理范围内(例如,设置一个20%的阈值)。
- 缺失值处理:如果某个关键模型的价格本月未能爬取到,是应该沿用上月数据(标记为“估计值”),还是留空?在项目中,更严谨的做法是留空,并在
notes字段标注“数据源暂时不可用”,避免传递错误信息。
清洗和验证流程的所有操作都应该被记录,生成一份数据质量报告,随数据一起发布。
3.3 数据集的可访问性与格式选择
项目的目标是“Open Dataset”,因此易用性和可访问性至关重要。需要提供多种数据格式以满足不同用户的需求:
- CSV:最通用,几乎任何工具(Excel, Python pandas, R)都能直接打开和处理。是主推格式。
- JSON:适合Web应用和前端直接调用。可以设计一个结构清晰的JSON Schema,例如按提供商分组,下面再列模型。
- Parquet:适合大数据量场景,列式存储,读写速度快,但需要特定工具支持。
- 通过API访问:对于高级用户,可以提供一个简单的只读API,通过HTTP GET请求就能获取最新或历史数据。这可以用GitHub Pages + JSON文件简单实现,或者部署一个轻量级服务器。
无论哪种格式,都必须提供清晰的数据字典(Data Dictionary),解释每个字段的含义。此外,在项目README中,应该提供一个最简单的使用示例,比如用Python pandas加载数据并计算调用一次GPT-4 Turbo(输入1000 token,输出500 token)的成本,让用户能在30秒内上手。
4. 项目维护与社区运营的长期考量
4.1 可持续性:如何让项目活下去?
一个开源数据集的死亡,往往不是因为技术问题,而是因为维护者失去了动力。确保项目的可持续性,需要从开始就设计好。
首先,降低维护成本是关键。这就是为什么自动化采集流程如此重要。理想状态下,维护者每月只需要花几分钟时间查看自动化报告,处理极少数异常情况。如果每次更新都需要手动查找和录入数据,项目很难坚持超过三个月。
其次,建立社区贡献机制。在GitHub仓库中,明确写出贡献指南。当用户发现某个模型价格已更新而数据集还未更新时,可以提交Issue,甚至直接提交Pull Request来修正数据。对于贡献者,可以通过在README中列出感谢名单等方式给予认可。对于22个模型以外的模型,也可以由社区提议和投票决定是否加入。
第三,寻求轻量级的合作。可以与一些关注AI成本的开发者社区、技术媒体或研究机构建立联系。他们可能是数据的使用者,也可以帮助宣传和校验数据。但切记保持项目的独立性和中立性,避免与任何特定的云厂商绑定过深,以维持公信力。
4.2 数据解读与衍生分析:超越原始数据
仅仅提供原始价格数字,价值是基础的。项目可以进一步提供一些简单的衍生分析和可视化,帮助用户更好地理解数据。
- 成本计算器示例:提供一个在线的或可下载的简单脚本,让用户输入预期的月度使用量(输入/输出token数),自动计算出使用各个模型的大概成本,并生成对比图表。
- 价格变化趋势图:每月自动生成主要模型的价格随时间变化的折线图。一张图就能直观展示出“模型价格战”的激烈程度,例如可以看到GPT-4 Turbo的价格曲线是如何一路向下的。
- 性价比分析:结合第三方发布的模型性能基准(如MMLU、HumanEval),计算每个模型的“每美元性能得分”。这能帮助用户在预算有限的情况下做出更优选择。当然,这需要谨慎处理,因为性能基准本身也存在争议。
这些衍生内容可以作为项目的“高级教程”或“分析报告”单独发布,吸引不同层次的用户。
4.3 可能遇到的挑战与应对策略
在运营这样一个项目一段时间后,我预见到可能会遇到以下几个挑战:
挑战一:厂商的“不友好”行为。有些厂商可能不希望价格被如此透明地追踪和比较,可能会采取技术手段阻止爬虫,甚至发送法律函件。应对策略是:1) 确保爬虫行为礼貌(低频率、遵守robots.txt);2) 所有数据均来自厂商自己公开的定价页面,不存在窃取未公开信息的行为;3) 在项目首页明确声明数据来源,并强调项目出于公益和教育目的。
挑战二:定价模型日益复杂。未来的定价可能不仅仅是输入输出Token费,可能会捆绑推理时间、每秒token生成速度(吞吐量)、专用实例租赁等。数据集的数据模型需要保持扩展性,可能需要引入新的字段来描述这些复杂维度。
挑战三:数据滞后性。月度更新对于快速变化的市场来说,可能有时显得滞后。可以探索“事件驱动”的更新机制,例如监控厂商博客的RSS订阅或特定Twitter账号,一旦检测到“pricing”、“cost”等关键词,立即触发一次临时数据采集。但这会大大增加系统的复杂性。
挑战四:准确性争议。价格理解可能有歧义,比如“承诺折扣”是否应计入标准价格?在项目中,坚持一个原则:记录最基础的、公开标注的、无附加条件的标准价格。所有折扣、促销信息在notes字段中说明。这样保证了基准的可比性,同时提供了更丰富的信息。
这个项目的初衷,是成为AI开发者工具箱里一个默默无闻但不可或缺的“螺丝刀”。它不炫酷,但足够实用。在技术飞速迭代的今天,除了关注模型的“能力上限”,我们同样需要关注其“成本下限”。一个透明、可靠的价格信息市场,对于整个生态的健康发展和创新普惠,有着细微但重要的价值。
