
最近不少同学在群里吐槽模型效果是挺好但每天调接口像在烧钱月底一看账单直接懵了。尤其是做 AI 应用、写自动化脚本、接客服机器人的朋友对 token 的消耗速度非常敏感。很多时候我们只关心“调用一次花多少钱”却忽略了“一次调用到底吃了多少 token”“每天跑多少量级”“哪些环节在重复计费”。本文就围绕大模型 API 的 token 计费手把手拆解成本构成、计算方式、监控手段和优化策略帮你搞清楚“每天烧 token我需要花多少钱”这件事。文章适合这几类读者正在接大模型 API 做应用的开发者、写脚本批量调用模型接口的工具党、需要给团队做成本评估的技术负责人。看完之后你能自己估算业务场景下的每日 token 费用能看懂官方账单里的关键字段也能在出问题时快速定位“钱到底烧在哪了”。1. 背景与核心概念1.1 什么是 token在自然语言处理领域token 是模型处理文本的最小单元。可以简单理解为“模型认识的一个词、一个汉字、或一个子词片段”。不同模型的分词方式不同常见的经验规律是英文文本中1 个 token 大约是 0.7 到 1 个单词。中文文本中1 个汉字大约是 1 到 2 个 token。代码文本中1 行代码可能被拆成 5 到 15 个 token。标点、空格、换行、特殊符号也会占用 token。为什么用 token 计费而不是按字数计费因为模型本身并不直接处理“字”而是把输入文本切分成 token 序列再交给神经网络进行预测。也就是说无论我们传多长的文本模型实际消耗的计算资源与 token 数量强相关。按 token 计费本质上是在按“模型计算量”付费。1.2 为什么现在大家都觉得 token 贵早期模型按次计费或按时计费用户对资源消耗的感知不明显。现在主流大模型 API 普遍按“输入 token 输出 token”分别计费成本透明却也让开发者感受到真正的用量压力。日常场景中 token 消耗往往超出预期常见原因包括每次请求都要携带系统提示词system prompt这部分 token 反复计费。对话类应用把历史消息全部发给模型上下文越长单次调用越贵。流式输出过程中输出 token 数量可能成倍增加。失败重试机制导致同一请求被计算多次。模型输出超长远超业务实际需要。理解 token 计费逻辑是所有成本控制的基础。1.3 大模型 API 的常见计费维度目前主流平台虽然具体规则不同但核心计费维度可以归纳为三个计费维度说明典型场景输入 token用户传入模型的全部文本包括系统提示词、历史记录、用户问题、工具定义等对话、翻译、摘要、信息抽取输出 token模型生成的内容文案生成、代码生成、回复消息缓存 token命中缓存时输入 token 的费用会大幅降低相同前缀请求、固定系统提示词场景有些平台还会区分“标准输入”和“缓存输入”缓存命中的 token 费率往往是标准输入的十分之一甚至更低。这就解释了为什么同样调一个模型有些团队每个月能省出一大笔开销。1.4 为什么开发者需要掌握成本估算从技术角度看掌握 token 成本估算能帮助你在设计阶段就评估 AI 功能的可行性。在开发中避免无意义的上下文膨胀。在上线后快速定位异常消耗。在做技术方案对比时给出量化的成本依据。很多项目不是死在模型能力不够而是死在成本失控。提前建立“一条请求的完整成本 输入成本 输出成本 失败重试成本”这个思维模型能避免很多后期麻烦。2. 环境准备与版本说明本文的成本计算和监控方案依赖以下环境和工具。版本需要根据你的项目实际情况调整下面以常见环境为例重点演示配置思路。操作系统macOS / Linux / Windows 均可本文代码使用 Python 3。Python 版本3.8 或以上。使用的 APIOpenAI 兼容格式的 Chat Completions 接口。其他大模型厂商的接口如果风格一致也可以复用本文思路。依赖库openai、requests、python-dotenv。辅助工具飞书/钉钉/企业微信机器人用于告警、Redis用于用量计数。安装依赖的参考命令pip install openai requests python-dotenv注意不同平台的 SDK 版本和模型名称差异较大本文示例代码以“模型名通过配置传入”的方式编写方便你适配自己的环境。各模型的单价请务必以官方定价页面为准下面是常见的示例价格仅用于演示计算方法。3. 核心概念拆解如何计算一次调用的 token 费用3.1 一次请求的完整构成一次普通的 Chat Completions 请求请求体通常长这样{ model: gpt-4o-mini, messages: [ {role: system, content: 你是一个客服助手回答要简洁。}, {role: user, content: 帮我查一下订单状态}, {role: assistant, content: 好的请问您的订单号是多少}, {role: user, content: 订单号是 123456} ], max_tokens: 500 }这里面的所有 messages 数组都会计入输入 token包括 system、user、assistant 的历史消息。也就是说多轮对话中之前所有轮次的文本都会进入本次计费。3.2 输入价格与输出价格以常见模型为例假设输入 token 价格0.15 美元 / 百万 token输出 token 价格0.60 美元 / 百万 token缓存命中输入0.015 美元 / 百万 token单次调用的费用公式为费用 (输入token数 × 输入单价) (输出token数 × 输出单价) (缓存token数 × 缓存单价)举例一次调用输入 2000 token、输出 500 token单价如上费用 (2000 / 1000000 × 0.15) (500 / 1000000 × 0.60) 0.00030 0.00030 0.00060 美元约等于 0.0006 美元单看一次确实很便宜。但如果每天调用 10 万次呢每日费用 0.0006 × 100000 60 美元一个月就是 1800 美元左右折合人民币已经过万。这就是为什么“单次很便宜总量吓死人”。3.3 cached tokens 的计费区别很多平台提供了“输入缓存”能力。当请求中的前缀内容与历史请求一致时命中缓存的这部分输入不再按标准价格计费而是按缓存价格计费。例如你的系统提示词固定为 1500 token用户问题平均 300 token。每次都命中的话1500 token 走缓存价只有 300 token 走标准输入价。长期运行下来节省的成本非常可观。在代码中可以通过 response.usage 字段查看缓存命中情况{ prompt_tokens: 2000, completion_tokens: 500, total_tokens: 2500, prompt_tokens_details: { cached_tokens: 1500 } }如果发现自己请求的 cached_tokens 一直为 0说明没有正确使用缓存能力需要检查请求格式和平台文档。3.4 max_tokens 对成本的影响max_tokens 参数限制模型最大输出长度但它不是“一定会用到这么多”。模型的输出 token 由生成内容决定max_tokens 只是上限。不过如果模型开始“说废话”或重复内容输出很容易接近上限。控制输出 token 数的办法包括在 system prompt 中明确“回答不超过 50 个字”。设置合理的 max_tokens比如普通客服回复 200摘要生成 300。使用结构化输出让模型直接输出 JSON避免多余解释。4. 完整实战写一个每日 token 成本估算器下面用一个 Python 脚本模拟多用户、多轮对话场景统计每天的 token 消耗和预估成本。这个脚本可以用于上线前的压力评估也可以结合日志统计真实用量。4.1 项目结构建议按下面的目录组织代码便于后续扩展token-cost-estimator/ ├── config.py # 模型、价格、场景参数 ├── estimator.py # 核心成本计算逻辑 ├── mock_chat.py # 模拟一次调用打印 token 明细 ├── daily_report.py # 统计每日汇总并输出报告 └── requirements.txt # 依赖列表4.2 配置模块文件路径config.py# -*- coding: utf-8 -*- 价格配置 注意价格和模型名只是示例请以你实际使用的平台页面为准 MODEL_CONFIG { gpt-4o-mini: { input_price_per_million: 0.15, # 美元/百万输入token output_price_per_million: 0.60, # 美元/百万输出token cache_price_per_million: 0.015, # 美元/百万缓存命中token }, gpt-4o: { input_price_per_million: 2.50, output_price_per_million: 10.00, cache_price_per_million: 1.25, }, } # 业务场景参数 SCENARIO { daily_requests: 100000, # 每日调用次数 system_prompt_tokens: 1500, # 固定系统提示词 token history_tokens: 1000, # 多轮历史消息 token user_avg_tokens: 300, # 用户平均问题 token output_avg_tokens: 400, # 模型平均输出 token cache_hit_rate: 0.8, # 缓存命中率0~1 }这里把价格和场景参数单独放在配置文件里是为了方便对照平台账单调整也方便多人协作时统一口径。4.3 核心计算逻辑文件路径estimator.py# -*- coding: utf-8 -*- 成本估算核心逻辑 def calc_request_cost(model_config, input_tokens, output_tokens, cache_hit_rate0): 计算单次请求成本 参数: model_config: 模型价格配置 input_tokens: 标准输入 token 数不含缓存命中部分 output_tokens: 输出 token 数 cache_hit_rate: 缓存命中比例0 表示无缓存命中0.8 表示80%的输入命中缓存 返回: dict: 包含各项费用的明细 input_price model_config[input_price_per_million] / 1_000_000 output_price model_config[output_price_per_million] / 1_000_000 cache_price model_config[cache_price_per_million] / 1_000_000 cached_tokens int(input_tokens * cache_hit_rate) standard_tokens input_tokens - cached_tokens standard_input_cost standard_tokens * input_price cache_input_cost cached_tokens * cache_price output_cost output_tokens * output_price total_cost standard_input_cost cache_input_cost output_cost return { total_tokens: input_tokens output_tokens, standard_input_tokens: standard_tokens, cached_tokens: cached_tokens, output_tokens: output_tokens, standard_input_cost: round(standard_input_cost, 6), cache_input_cost: round(cache_input_cost, 6), output_cost: round(output_cost, 6), total_cost: round(total_cost, 6), } def calc_daily_cost(model_name, scenario): 根据每日调用量估算一天的总成本 参数: model_name: 模型名称 scenario: 场景配置字典 返回: dict: 每日汇总成本 model_config MODEL_CONFIG.get(model_name) if not model_config: raise ValueError(f未找到模型 {model_name} 的配置请先在 config.py 中添加) per_request_input ( scenario[system_prompt_tokens] scenario[history_tokens] scenario[user_avg_tokens] ) per_request_output scenario[output_avg_tokens] request_cost calc_request_cost( model_config, per_request_input, per_request_output, scenario[cache_hit_rate], ) daily_requests scenario[daily_requests] daily_cost request_cost[total_cost] * daily_requests return { model: model_name, per_request_detail: request_cost, daily_requests: daily_requests, daily_cost: round(daily_cost, 2), monthly_cost_estimate: round(daily_cost * 30, 2), }4.4 模拟单次调用与每日报告文件路径mock_chat.py# -*- coding: utf-8 -*- 模拟一次真实的 API 调用并展示 usage 字段 需要将 OPENAI_API_KEY 配置在环境变量中 import os from openai import OpenAI client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) response client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: 你是一个客服助手回答要简洁。}, {role: user, content: 我下单三天了还没发货能帮我查一下吗}, ], max_tokens200, ) usage response.usage print(模型回复:, response.choices[0].message.content) print( usage 明细 ) print(输入 token:, usage.prompt_tokens) print(输出 token:, usage.completion_tokens) print(总 token:, usage.total_tokens) # 缓存命中信息在不同平台可能字段不同这里做兼容读取 try: cached usage.prompt_tokens_details.cached_tokens print(缓存命中 token:, cached) except Exception: print(缓存命中 token: 当前接口未返回该字段可忽略)文件路径daily_report.py# -*- coding: utf-8 -*- 每日成本报告入口 from config import MODEL_CONFIG, SCENARIO from estimator import calc_daily_cost def main(): for model_name in MODEL_CONFIG: report calc_daily_cost(model_name, SCENARIO) print( * 50) print(f模型: {report[model]}) print(单次请求明细:) detail report[per_request_detail] print(f total_tokens: {detail[total_tokens]}) print(f 标准输入: {detail[standard_input_tokens]}) print(f 缓存命中: {detail[cached_tokens]}) print(f 输出: {detail[output_tokens]}) print(f 单次费用: ${detail[total_cost]}) print(f每日调用次数: {report[daily_requests]}) print(f每日成本(美元): ${report[daily_cost]}) print(f每月预估成本(美元): ${report[monthly_cost_estimate]}) print( * 50) if __name__ __main__: main()4.5 运行与验证运行报告脚本python daily_report.py预期输出大致如下 模型: gpt-4o-mini 单次请求明细: total_tokens: 3200 标准输入: 560 缓存命中: 2240 输出: 400 单次费用: 0.00059 每日调用次数: 100000 每日成本(美元): 59.19 每月预估成本(美元): 1775.7 这里有一个很容易看错的地方在开启缓存命中后3200 token 的总量没有变但 2240 个 token 走了缓存价所以单次费用从原本的 0.001 美元级别降到了约 0.0006 美元。省下的钱是实打实的。4.6 结果如何影响方案决策假设你的业务单次利润只有 0.01 元人民币而模型成本折算为 0.004 元人民币约 0.0006 美元那么利润空间还比较充裕。但如果一次调用吃掉 2000 输出 token成本直接翻好几倍可能瞬间把利润打没。通过这个估算器你可以在三分钟内回答几个关键问题预算是每天 100 美元最多能支撑多少次调用模型输出从 400 token 降到 200 token每月省多少钱缓存命中率从 80% 降到 50%成本上升多少这些数据能帮助你在模型选型和功能设计阶段就做出判断而不是等账单出来再后悔。5. 真实场景下的成本监控与预警估算器做的是事前评估真实项目中还需要埋点监控实际用量。下面分享一套轻量级监控方案不依赖复杂平台用日志和脚本就能跑起来。5.1 记录每次调用的 usage无论使用官方 SDK 还是 requests 直连响应体里通常会包含 usage 字段。建议在封装层统一把 usage 记录下来落到本地日志或数据库。日志字段建议最少包含时间戳模型名称业务场景编号输入 token 数输出 token 数缓存命中 token 数本次请求费用是否重试过参考日志格式2025-06-08 10:23:45|gpt-4o-mini|customer_service|input1200|output300|cache900|cost0.00039这样一条日志既能看到单次请求的明细也能为后续聚合统计提供原始数据。5.2 用脚本按天汇总成本文件路径summarize_logs.py# -*- coding: utf-8 -*- 从日志中汇总每日 token 消耗和费用 import datetime from collections import defaultdict def parse_line(line): 解析一行日志返回字段字典 parts line.strip().split(|) if len(parts) 5: return None return { time: parts[0], model: parts[1], scene: parts[2], input_tokens: int(parts[3].split()[1]), output_tokens: int(parts[4].split()[1]), } def summarize(log_path): daily defaultdict(lambda: {requests: 0, input_tokens: 0, output_tokens: 0}) with open(log_path, r, encodingutf-8) as f: for line in f: data parse_line(line) if not data: continue day data[time][:10] daily[day][requests] 1 daily[day][input_tokens] data[input_tokens] daily[day][output_tokens] data[output_tokens] for day in sorted(daily): info daily[day] print(f{day}: 请求 {info[requests]} 次, 输入 {info[input_tokens]} token, f输出 {info[output_tokens]} token) if __name__ __main__: summarize(api_usage.log)5.3 设置每日成本阈值预警在成本超过预期时第一时间通知是避免“烧穿预算”的关键。常见的实现方式定时任务每 30 分钟统计一次当日累计成本。超过阈值时通过 Webhook 发送到企业微信/钉钉/飞书。如果成本异常翻倍自动暂停非核心任务。简单告警示例# -*- coding: utf-8 -*- 每日成本阈值检查脚本 import requests DAILY_COST_LIMIT_USD 50.0 WEBHOOK_URL https://your-webhook-url def send_alert(message): payload {msgtype: text, text: {content: message}} requests.post(WEBHOOK_URL, jsonpayload, timeout5) def check_cost(cost_today): if cost_today DAILY_COST_LIMIT_USD: send_alert(f今日成本已达 ${cost_today:.2f}, 超过阈值 ${DAILY_COST_LIMIT_USD}) # 示例用法 check_cost(52.3)6. 常见问题与排查思路6.1 我的 token 消耗量为什么比预想高很多问题现象常见原因解决思路单次请求输入 token 很多messages 数组里塞入了完整历史记录只携带最近几轮对话或做摘要输出 token 远超预期system prompt 没约束长度模型自由发挥明确“50字以内”调低 max_tokenscached_tokens 一直为 0请求未满足缓存条件检查请求前缀是否严格一致查看平台缓存规则每日账单波动大并发量突增或异常重试排查线上流量增加熔断机制批量任务重复计费失败重试时重新发送了完整上下文重试前记录进度避免整段重新请求6.2 为什么上下文越长越贵在 Transformer 架构下模型需要处理整个输入序列。上下文越长每次请求的输入 token 越多计算量越大费用也越高。多轮对话如果不做历史裁剪token 消耗会随着对话轮次线性增长很容易失控。一个 10 轮对话的机器人假设每轮 500 token最后一轮请求可能就要携带 5000 token 的历史。如果在 10000 个并发会话上运行成本会非常可观。解决思路只保留最近 3 到 5 轮对话。对历史消息做摘要压缩。业务上需要的长期记忆改用向量数据库存储。6.3 为什么重试会导致费用翻倍很多开发者直接在异常后走“重新调用一次”的逻辑但并没有清除掉上一次的上下文。如果一次失败调用实际已经在服务端计算了输出比如超时但结果已生成重试相当于两次计费。更稳妥的做法使用幂等键避免同一请求重复计费。重试前确认上一次调用确实失败而不是“响应慢”。对非核心场景限制重试次数例如最多 2 次。6.4 有没有免费 token 额度可以用于测试大部分主流平台在注册时会赠送一定试用额度或者提供免费模型档。用这些额度做功能验证和成本评估是省钱的第一步。需要注意免费额度通常有有效期。免费模型与收费模型的效果可能差异较大。生产环境不要依赖免费额度。7. 成本优化最佳实践7.1 提示词压缩与固定前缀系统提示词每个请求都在计费所以要尽可能精简。下面是一个优化对比优化前你是一个专业的客服助手你的名字叫小智。你来自我们公司的人工智能团队。你的任务是回答用户关于订单、物流、商品、退换货等问题。回答时要注意礼貌同时要给出具体的信息。如果用户问的问题你不清楚可以要求用户提供订单号。请用简洁的、平易近人的语气回复。这段大概 90 个汉字可能消耗 120 到 150 token。优化后你是客服机器人。回复需简洁。不清楚时请先询问订单号。大概是原文本的 1/4每次请求省下约 90 token。按每天 10 万次请求计算每月省下的费用非常可观。优化提示词的核心原则用最短的句子表达必要条件。删除冗余的“人情味”修饰语。把高频约束如“请用JSON输出”合并成一条。测试压缩后效果是否满足业务要求。7.2 合理利用缓存命中缓存命中需要请求前缀保持稳定。如果系统提示词固定、工具定义固定、历史记录起始部分固定就可以触发缓存。实际项目中的最佳实践不要把动态内容放在 system prompt 中。动态参数如用户ID尽量放在最后一条 user 消息里。保持 tool/function 定义的顺序和内容不变。监控 usage 中 cached_tokens 的占比常态化排查命中情况。7.3 模型分级与降级策略不是所有请求都需要最强模型。成本优化的关键思路是“按需分配”。推荐分级策略请求类型推荐模型档原因简单问答、正则抽取小模型价格最低档效果够用结构化抽取、意图识别中等模型准确率与成本平衡代码生成、复杂推理旗舰模型需要强能力批量离线任务异步 低峰期避开高峰提升吞吐降级策略示例先试小模型如果一次返回质量不达标再升级到大模型。用户问答场景用快模型深度分析场景用强模型。高峰期自动切到低一档模型保证服务不中断。7.4 控制并发与流量并发高不代表成本高但并发高会放大异常情况的损失。在流量控制上建议以下几点对每个用户的请求频率做限流避免恶意请求打爆账单。批量任务使用队列削峰避免瞬时并发挤满。设置单用户单日 token 上限防止一个异常用户消耗大量额度。7.5 定期进行成本复盘建议每周或每月做一次成本复盘围绕以下问题展开哪些场景消耗 token 最多是否合理缓存命中率有没有下降为什么是否存在输出过长、内容重复的情况有没有无效请求占用额度模型档位是否还有下调空间把成本复盘变成常规流程而不是出了问题才看账单。8. 总结与建议通过本文的拆解你应该已经掌握了大模型 API token 成本的核心计算模型每次请求的费用由输入 token、输出 token、缓存命中 token 共同决定日成本等于单次费用乘以调用次数再叠加失败重试带来的额外损耗。落到实际项目中有几件事需要重点推进上线前用成本估算脚本模拟每日开销不要等到账单出来才知道超支。开发阶段统一封装 API 调用层记录 usage 日志为后续监控打好基础。运行期间配置成本阈值告警确保异常消耗能及时被发现。定期优化提示词压缩上下文提升缓存命中率。根据业务场景做模型分级不让高成本模型处理无需高智能的任务。如果你正打算做 AI 应用或者已经在为大模型 API 账单发愁强烈建议先把本文的估算脚本跑起来用真实用量替换掉示例参数。清楚每一分钱烧在哪里才能让 AI 功能在成本可控的前提下稳定跑起来。