AI应用Token成本控制:计费拆解与优化策略

发布时间:2026/10/20 7:34:36
AI应用Token成本控制:计费拆解与优化策略
做 AI 应用的人早晚都会被一张账单教育一次。我见过不少团队上线前反复对比模型效果、逐字打磨提示词结果上线后第一周就被 Token 费用吓到。原因很简单模型输出质量是你肉眼可见的体验但 Token 消耗藏在每一次请求的返回字段里等到月账单出来才看清。Token 经济学不是什么高深理论它要回答的问题非常具体如何用更少的 Token 达成同样的效果以及当 Token 不可避免地要花出去时怎么把预算花在最有价值的地方。这篇文章写给独立开发者、AI 应用落地工程师和所有需要为模型调用付费的团队从一次真实请求的计费拆解开始讲到 Prompt 压缩、上下文管理、缓存命中、模型分级路由和预算告警。文中的费用推演都可以拿自己的真实数据重算一遍。1. 先算清楚账Token 到底在计费里扮演什么角色1.1 一次请求从发出到扣费钱花在哪几个环节很多团队对 Token 计费的理解停留在“按字数花钱”这是最危险的误差来源。实际上当你把一段请求发给模型接口服务商并不是按“条数”计费而是把文本切分成 Token 后逐一计费。一次模型调用的费用可以简化成输入 Token 数乘以输入单价加上输出 Token 数乘以输出单价。如果有缓存命中输入部分还会按缓存价格另算。这个公式本身不复杂但绝大多数成本失控都藏在“输入 Token 里究竟装了什么”和“输出到底生成了多少”这两个问题上。输入部分最容易被人忽略。一次请求的输入不只是用户在输入框里打的那句话还包括系统提示词、历史对话消息、外部检索结果、工具定义、函数调用 Schema、示例样本甚至格式化用的 Markdown 符号和换行。这些都是要花钱的。举例来说很多客服机器人的 Prompt 模板并不大但每次请求都会把之前十几轮对话原封不动地重新塞进去输入量被迅速放大。到了第 20 轮对话模型处理的输入已经是第一轮的几十倍。输出部分同样不省心。模型生成的正文、JSON 字段、列表格式、结尾礼貌用语全都会被计入输出 Token。更关键的是输出单价通常是输入单价的数倍。我见过有人花了大量精力压缩系统提示词把输入从 1500 Token 压到 800 Token结果输出一次回答还是稳定在 800 Token账单没有任何惊喜。因为真正吃掉成本的大头往往在模型生成那一段。还有一类成本容易被漏掉那就是工具调用带来的“隐藏 Token”。现在的应用经常让模型决定是否调用外部工具工具名、参数描述、返回值约束都会被编码成 Token。有些模型每多定义一个工具就可能增加几十到几百 Token 的固定开销而且这部分在开发阶段根本感觉不到因为测试请求量小。只有上了生产环境调用量一上来它才变成账单上肉眼可见的缺口。1.2 Token 不是字数中文场景的计费误差从哪来Token 可以粗略理解为模型能识别的最小文本碎片。对英文来说一个单词通常对应一到一点几个 Token对中文来说一个汉字可能对应一个 Token也可能被切得更细。标点、空格、换行、Emoji 这些看似不重要的东西也会被编码成 Token。如果你按“字数”去估算请求成本偏差很容易达到 20% 到 50%而且往往是低估。举个很常见的场景。一段 30 字的用户问题按字数算好像很便宜但经过分词后可能变成 38 个 Token。一段包含 JSON 示例、表格、函数定义的系统提示词Token 数量甚至可能比字符数还高。因为模型服务商使用的分词算法并不完全一致同一个 Prompt 在不同模型下的 Token 统计也可能不同。所以最稳妥的做法不是拍脑袋而是把 Prompt 模板纳入版本管理在提交变更前用对应模型的分词工具或服务商提供的计数器跑一遍把 Token 数写进改动说明里。多模态和工具调用场景更是如此。如果请求里带图片图片会被切分成固定尺寸的视觉 Token一张看起来很小的缩略图也可能消耗不少 Token。如果开启函数调用每次请求都要把函数定义重新编码一遍。这些成本不会显示在代码里但会显示在账单里。上线之前至少要把这些隐藏项都摸一遍否则后面做成本预估很容易失真。1.3 定价模型读收费、写更贵、缓存另外算为了后面做费用推演这里先给一套典型的参考定价。不同模型和厂商的价格差异很大但结构上通常都有这几档普通输入、缓存输入、普通输出、批量输入、批量输出。计费项参考单价USD/千 Token简单解释普通输入0.003每次需要真实处理的新鲜输入缓存输入0.0003命中缓存且前缀一致的输入便宜一个数量级普通输出0.015模型逐 Token 生成价格最高批量输入0.0015非实时任务走批量接口约五折批量输出0.0075非实时任务走批量接口约五折这套价格只用于后面的演算不代表任何真实厂商报价。但它反映了一个重要规律输出比输入贵得多缓存输入比普通输入便宜得多。原因也不难理解。输入阶段服务商可以进行大量并行预计算成本摊得比较薄输出阶段是模型一个一个词地往外生成占用推理资源的时间更长自然更贵。而缓存输入是复用之前算过的结果只需要做一次读取和匹配所以价格能压得很低。理解了这个定价结构你就能明白为什么“所有请求都走同一个旗舰模型”是很多项目成本失控的根源。旗舰模型的输出单价可能是经济型模型的七到十倍而业务里大量简单任务根本用不上那么强的推理能力。这不是模型选型问题而是预算分配问题。2. 成本控制的三条主线入口压缩、中间分离、出口收敛2.1 入口压缩别让 Prompt 里每一个字都变成账单上的数字入口压缩的目标很直接在保证输出质量不下降的前提下减少每次请求的输入 Token。最容易见效的地方就是系统提示词。很多团队写的系统提示词像一篇命题作文有背景介绍、有角色设定、有行为准则、有禁忌事项、还有一堆示例。这些内容确实有一定用处但里面的信息密度极低大量重复表述完全可以在不伤效果的前提下删掉。我在实际项目中常用的方法是把提示词当成代码来重构。先看哪些字段是动态的哪些是静态的把静态指令放到最前面把动态内容放到后面再逐个检查每一条指令问自己“删掉这句话模型表现真的会变差吗”多数时候答案是不会。少用形容词少写“你是一个伟大的人工智能助手”这类装饰性句子把动作说得越明确越好。Few-shot 示例也要控制数量。很多应用给模型塞了一堆示例希望它能“学会”某种输出格式但实际上两三个边界案例就够用了示例和示例之间如果高度相似后面的都是重复计费。检索增强场景更要注意不要把知识库的所有分块全部塞进提示词而是先检索、筛出最相关的两到三个片段再拼接进输入。每多塞一屏无关内容模型既容易被干扰也在为无关内容买单。入口压缩有个容易踩的坑为了省 Token 把关键上下文删了结果模型答非所问用户只能多问一次反而多花一轮输出钱。压缩必须以质量回归为前提。每次压缩提示词后至少跑一批真实请求对比效果确认没有明显劣化再上线。2.2 中间分离让上下文管理从“全量重发”变成“按需拼装”如果说入口压缩是省“首轮费用”上下文管理省的就是“长会话费用”。很多应用采用的是无状态接口调用把所有的历史消息数组每次原样发给模型。这样做开发最简单但成本最失控。原因在于对话轮数越多每次请求的输入就越长而且每一轮新请求都会把前面所有历史重新计一次费。假设每轮对话平均产生 200 Token 输入聊到第 20 轮时第 20 次请求本身就要携带 4000 Token 的历史前 20 次请求累计发送的 Token 接近四万多。其中真正的新增信息只有最后一轮用户说的话。这就像每次开会都让全部参会人员重新读一遍之前的会议纪要而且纪要是按字数收费的。更好的做法是把上下文拆成几个层次按需拼装。第一层长期记忆摘要用一个小模型定期把旧对话压缩成“已解决问题、未完成任务、用户偏好”三类信息每次请求只带摘要不携带全部历史。第二层短期窗口只保留最近两到三轮的完整对话保证模型对当前话题有足够上下文。第三层外部知识由检索器决定当前问题需要哪些背景资料只把命中的片段放进去。我做过一个客服助手改造原来每次请求输入是系统提示词 500 Token 加完整历史 2000 Token 加知识库片段 1000 Token总共 3500 Token。改造后变成系统提示词 200 Token 加摘要 300 Token 加最近两轮 400 Token 加检索命中 600 Token总共 1500 Token。效果没有明显变化但平均输入量直接降了一半以上。这个收益在日请求量大的时候会直接变成六位数的预算差异。2.3 出口收敛用结构化和 max_tokens 卡住输出成本输出比输入贵所以输出侧的优化往往比 Prompt 压缩更值钱。最基础的操作是设置 max_tokens。很多开发者在调用接口时不设这个参数或者设成模型支持的最大值模型就会按照自己的节奏自由发挥。回答越长费用越高用户还不一定需要那么多铺垫。正确做法是先看历史数据。从日志里统计每次任务实际需要的输出长度分布然后取一个合适的百分位作为 max_tokens。比如有 90% 的请求在 200 Token 以内就能完成那就别把上限设成 1024。这不会限制真正需要长输出的请求但能卡掉模型没必要的废话。结构化输出也是一个很好的收敛手段。如果业务只需要几个字段明确要求“只输出 JSON不要解释不要 Markdown”输出长度通常会短很多。反过来如果任由模型自由发挥它很容易在回答里加一段礼貌客套、一段背景说明、再列一堆不相关建议。可以用停止词或自定义结束标记让模型在完成任务后立刻停住而不是继续生成“如果有其他问题请随时问我”这类话。还有一点需要提醒temperature、top_p 这类采样参数对 Token 计费没有直接影响不要指望调低温度能省钱。它们真正影响的是回答质量和重试概率。如果温度设置不合理模型频繁答错用户反复重试那额外产生的 Token 才是真金白银的浪费。3. 计费优化实战一个真实场景的压测与费用推演3.1 场景设定与基线费用计算为了把前面讲的策略串起来我用一个模拟项目 X 来做费用推演。场景是一个智能客服助手日活跃用户约一万每天产生五万次模型调用。当前实现里每次请求平均输入 1200 Token其中包括 800 Token 系统提示词、200 Token 用户问题、200 Token 检索内容平均输出 300 Token。调用的是某商用旗舰模型采用前面表格里的参考价普通输入 0.003 美元/千 Token普通输出 0.015 美元/千 Token。先看基线费用。计算可以写成一段很简单的逻辑calls 50000 avg_input 1200 avg_output 300 input_price 0.003 output_price 0.015 input_cost calls * avg_input / 1000 * input_price output_cost calls * avg_output / 1000 * output_price daily_cost input_cost output_cost print(input_cost, output_cost, daily_cost)结果是每天输入成本 180 美元输出成本 225 美元合计 405 美元。一个月按 30 天算就是 12150 美元单次请求成本约 0.0081 美元。这个数字对很多创业团队来说已经是不可忽视的负担而且它还没有计算重试、多轮叠加和流量尖峰。也就是说这个基线费用是一个偏保守的估计。3.2 优化动作的叠加效果与费用推演接下来我把前面说的优化手段按顺序叠加看每一步到底能省多少钱。第一步做入口压缩和上下文管理。系统提示词从 800 Token 压到 400 Token检索内容控制在 100 Token 以内平均输入从 1200 降到 600 Token。输出暂时不变还是 300 Token。输入成本变成每天 90 美元输出成本每天 225 美元合计 315 美元月成本降到 9450 美元相比基线节省约 22%。第二步启用缓存。假设系统提示词这部分公共前缀可以被缓存命中命中的比例是输入 Token 的 40%。未命中的 60% 输入 Token 按普通输入价 0.003 算命中的 40% 按缓存输入价 0.0003 算。每天输入成本变成 54 加 3.6也就是 57.6 美元输出还是 225 美元合计 282.6 美元月成本 8478 美元相比基线节省约 30%。第三步做输出收敛。把 max_tokens 从默认 1024 调整到按历史分布取 p90 的 180 Token同时要求模型先给结论不要长篇大论。输出平均从 300 降到 180 Token。输出成本变成每天 135 美元。此时输入成本仍是 57.6 美元日合计 192.6 美元月成本 5778 美元相比基线节省约 52%。优化阶段平均输入 Token平均输出 Token日成本月成本相比基线基线120030040512150-入口压缩 上下文管理6003003159450-22.2%启用缓存600300282.68478-30.2%输出收敛600180192.65778-52.4%到这里仍然没有改变模型选型。但成本已经砍了一半。很多团队做到这一步就满足了其实还有更激进的优化空间模型分级路由。3.3 模型分级路由与批处理怎么进一步省钱并不是每一次请求都需要旗舰模型。客服场景里大量问题是“发货时间”“退换货流程”“订单查询”这些属于简单意图识别用经济型模型完全够用。只有涉及多轮推理、数学计算、长文档综合理解的任务才需要旗舰模型的能力。假设通过规则和简单分类器判断30% 的请求属于复杂任务继续用旗舰模型70% 的请求属于简单任务切到经济型模型。经济型模型参考价设为普通输入 0.0005 美元/千 Token输出 0.002 美元/千 Token。优化后的输入输出量保持不变平均输入 600 Token平均输出 180 Token。旗舰模型这边每天处理 15000 次请求输入成本是 27 美元输出成本是 40.5 美元合计 67.5 美元。经济型模型每天处理 35000 次请求输入成本 10.5 美元输出成本 12.6 美元合计 23.1 美元。两边加在一起日成本 90.6 美元月成本 2718 美元相比最初的 12150 美元节省约 77.6%。这个推演当然偏理想因为路由判断本身可能产生调用成本模型效果差异也可能导致更高的重试率。但即便打个五折它仍然有非常可观的收益。我的经验是先用小流量对比一下两种模型在简单任务上的表现确认经济型模型不会大幅拉低用户满意度再逐步扩大流量比例。不要把切换做成一次性的大爆炸而是做成带开关的灰度发布。批处理是另一块容易被忽略的钱。如果业务里有非实时任务比如日报生成、历史工单分类、知识库索引更新它们并不需要几百毫秒内返回结果。把这类请求放到批量接口中很多服务商能给出接近五折的价格。参考前面表格里的批量输出价 0.0075 美元/千 Token每天哪怕只有 2000 千个输出 Token 走批量也能省下 15 美元一个月就是 450 美元。这部分优化几乎对用户体验没有影响属于白捡的收益。3.4 预算控制与告警设置成本控制不能只靠事后看账单必须在系统里设置预算边界。我通常会做三件事。第一在请求层设置硬上限。每次调用都明确 max_tokens并对输入长度做预检查。如果某个用户发来的消息太长系统先做截断或提醒而不是把所有内容一股脑丢给模型。对单用户或单密钥设置每日调用配额防止异常流量把预算打穿。第二把用量数据变成可观测指标。每次模型调用返回后把 prompt_tokens、completion_tokens、total_tokens 原样写进结构化日志并按业务功能打标签。这样就能回答“哪个功能最烧钱”“哪个用户调用量异常高”这类问题而不是面对一张总额账单发呆。第三设置三道告警。日费用超过当日预算的 50% 时提醒一次单个用户单日调用量比正常基线高三倍时告警平均单次请求的 Token 消耗比上一周高出 30% 时告警。告警阈值不要设得太满因为服务商控制台的估算金额和最终账单往往存在百分之几到百分之十几的偏差留出缓冲区间才不会被误报淹没。4. 常见问题与排查技巧实录4.1 明明对话很短账单却很高重发历史的数学这是我在很多项目里见过的头号问题。表面上看每次请求只生成了短短一段回答但账单却高得离谱。翻日志后会发现请求体里带着完整的历史消息而且每一轮请求都会把前面的历史再算一遍输入费用。假设每轮输入新增 200 Token到第 20 轮时前 20 次请求累计发送的输入 Token 接近四万。单看一次请求四万 Token 的成本并不算高但如果一万个用户每天都聊 20 轮这部分费用会被放大得非常可观。处理方式就是前面说的摘要加滑动窗口。保留最近两三轮的完整对话更早的内容压缩成摘要再配合“关键事实”和“待办事项”这类结构化字段。这样既不会丢失长期信息也不会让账单随对话轮数线性增长。4.2 用了缓存费用却没什么变化缓存命中的前提很多开发者启用缓存后发现命中率很低费用几乎没降。最常见的原因是前缀不固定。缓存通常要求提示词的公共前缀完全一致不是语义相似。如果系统提示词里带时间戳、用户名、随机 ID或者把用户消息直接拼在最前面缓存就无法命中。解决办法是把请求拼装顺序做一次调整。静态的指令、示例、工具定义放到最前面动态的用户输入、检索结果放到后面。这样公共前缀尽可能长缓存才有机会命中。还要注意如果某种缓存机制只针对一定长度的公共前缀那过短的提示词可能反而不划算。开启缓存后要定期看命中率如果命中率长期低于三成就要排查前缀是否被某个动态字段破坏了。4.3 输出被截断反而更贵max_tokens 的取舍有同学为了省钱把 max_tokens 设得很小结果模型回答到一半被截断。用户看到半截内容只能再发一句“继续”系统又生成第二轮。第一轮花钱买了半截内容第二轮还要重新携带上下文再花一遍输入费用。一来一回原本一次 400 Token 的输出变成了两次 200 Token 的输出外加额外的输入总成本不降反升。max_tokens 的真正作用是控制单次请求的上限而不是强求所有回答都短。正确思路是统计线上的输出长度分布取 90 分位作为上限。这样做既能覆盖绝大多数正常回答又能防止模型偶尔抽风写一篇小作文。对长回答场景还要在业务层设计“先给结论、再给详情”的格式让最关键的答案永远出现在第一个输出片段里。4.4 Token 估算和账单对不上隐藏的 Token 去哪了如果发现自己手工估算的 Token 数和账单总是差一大截先别急着怀疑服务商。多半是漏算了这几类内容工具定义的 Schema、JSON 输出格式中的字段名、多模态图片的视觉 Token、特殊控制符和格式化符号。尤其是函数调用场景工具越多固定开销越大。同样结构的请求加一个工具前后输入 Token 可能差几十到几百。我的习惯是每条响应日志里保存 usage 字段并定期对比“日志累加总额”和“账单总额”。如果两者长期对不上就说明有请求没有记日志或者有重试请求被吞掉了。把用量日志当成财务凭证来对待是整个成本控制体系里最基础也最重要的一环。4.5 流量尖峰一来成本曲线突然起飞日常流量平稳时成本预测还算准确。一旦有活动推广、热点事件或外部脚本刷接口请求量会在短时间内暴涨费用也跟着起飞。这类问题往往不是模型提示词能解决的而是要在入口层做限制。第一对所有接口加鉴权和频控防止匿名流量消耗预算。第二给非关键请求设计降级策略复杂任务在高峰期切到经济型模型或者直接返回缓存结果。第三重试逻辑必须带退避和上限不能一失败就立刻重试三次否则一次故障就能造成几倍的成本。最后如果业务有明显的流量波峰可以在波峰前主动降低 max_tokens 和输入长度阈值宁可让单次回答稍微简单一点也别让预算在半小时内被打穿。5. 把 Token 成本控制变成一种工程习惯5.1 构建费用可观测性从每请求 Token 到全链路分摊成本控制不能靠月底看账单那样太晚了。我见过最有效的做法是建立一个“用量数据中心”把每次模型调用的 usage 字段采集进来按业务功能、用户维度、模型维度做聚合。这样每天的日报会非常清楚哪个功能消耗了多少输入 Token多少输出 Token缓存命中率是多少平均单次请求成本是多少。有了这些数据才能回答“这个新功能到底值不值得上”的问题。如果一个功能每天烧掉 100 美元但只给业务带来 50 美元的转化那就应该砍掉或降级。如果另一个功能虽然调用量很大但大量请求都被缓存命中单位成本很低反而可以放心加大投入。费用可观测性不是财务部门的事而是每个 AI 应用开发者都应该建立的基础设施。5.2 上线前先做 Token 体检一份可执行的检查清单每次新功能上线前别只测效果和延迟还要做一次 Token 体检。我把常用检查项列成了清单照着跑一遍基本不会漏。每个 Prompt 模板是否有 Token 基准线变更后增量是多少单请求的最大输入长度是否受限超长内容是否会被截断或拒绝上下文是否会无限增长是否配置了滑动窗口或摘要机制是否开启了缓存缓存命中率目标是多少是否设置了单用户频控、单请求 max_tokens 和预算告警是否需要为不同请求选择不同模型路由失败时是否有兜底方案是否保存完整 usage 日志能否还原某个用户的成本路径这套体检做一次只需要小半天但它避免的问题往往能省下几个月的盲目优化。尤其对新项目来说上线第一周的数据最宝贵如果一开始就埋好了用量日志后面所有成本分析都会轻松很多。5.3 团队协作建立成本审查机制成本控制不该只靠一个人盯着要把“Token 消耗”变成代码评审里的一项常规指标。我建议团队在做 Prompt 改动时像改代码一样写改动说明这次改动预计让单次请求增加还是减少多少 Token对用户可感知质量的影响是什么如果只写了“优化提示词”却没有任何 Token 数据支撑那这个改动本质上是不合格的。同时可以设定一个成本 owner每周看一次用量报表关注“单次任务成本”或“单会话成本”这类归一化指标。不要只盯总账单因为总账单会随用户量自然增长很难判断是正常还是异常。相比之下单次会话平均成本如果连续几天明显上升一定说明最近某个改动或流量模式发生了变化。最后分享一个我自己的土办法在开发环境里给每次模型调用打印完整 usage不急着优化先让数据裸奔一段时间。踩过几次坑之后你会发现Token 经济学本质上不是抠门而是让每次请求都明码标价逼自己想清楚这个 Token 真的非花不可吗如果答案是肯定的那就放心花如果答案开始犹豫说明该优化了。