
1. 先算一笔账几千万token到底花在哪儿了一个月跑掉几千万token这个量级听起来吓人但拆开看其实很普通。我手上这个项目是一个面向内容团队的辅助写作工具日活不高大概三四百人但每个用户平均每天要触发十几次生成请求每次请求的上下文又比较长——系统提示词、历史对话、参考资料全都要塞进去。单次请求输入轻松破万token输出几百到一两千不等。这么一乘一个月下来输入侧就吃掉三千多万token输出侧也有大几百万。很多人第一次看到账单会懵是因为只盯着输出看觉得生成的字数不多应该花不了几个钱。实际上在主流API的计价体系里输入token和输出token是分开计价的而且输入往往是大头。尤其是带长上下文、带知识库检索、带多轮对话的场景输入token的占比经常能到八成以上。你如果只优化输出等于在漏水的桶上拧小出水口进水量一点没变。我拿自己某个月的原始账单举个例子方便你建立量级感项目数量单价参考小计输入token3200万按中档模型约 $3/百万约 $96输出token680万按中档模型约 $15/百万约 $102合计3880万—约 $198注意这只是单模型、单账号的粗算。如果你用的是更高阶的模型或者开了多个环境开发、测试、生产各一套key账单翻两三倍很正常。所以几千万token这个数字本身不稀奇稀奇的是同样的业务量有人花两百刀有人花两千刀。差距不在业务在于调用方式和架构设计。这一篇我想聊的就是后者怎么在不砍功能、不降体验的前提下把这几千万token的账单压下来。下面所有内容都来自我自己的实测不是理论推演涉及的数字都是真实跑出来的。2. 计价模型里最容易被忽略的三个变量在动手省钱之前得先把计价规则吃透。大部分人只知道输入便宜、输出贵但真正影响账单的变量远不止这两个。2.1 缓存命中与未命中的价差现在主流平台都提供了**提示词缓存prompt caching**机制。简单说如果你的请求前缀比如系统提示词、固定的few-shot示例和上一次请求高度重复平台会把这部分缓存起来命中缓存的部分按更低的单价计费通常是原价的十分之一甚至更低。这个机制对什么场景最有用就是那种系统提示词很长、但每次用户问题很短的应用。我实测过一个客服问答机器人系统提示词加知识库片段有八千多token用户问题平均只有五十token。没开缓存的时候每次请求都要为那八千token付全价开了缓存之后重复部分按缓存价走单次成本直接掉到原来的两成左右。但缓存有个坑它通常有生命周期几分钟到几十分钟不等而且要求前缀完全一致。你如果在系统提示词里塞了动态内容比如当前时间、用户昵称缓存就永远命中不了。我见过有人为了让回答更个性化在系统提示词开头加了句现在是{当前时间}结果缓存全废一个月多花了好几百刀。这种细节文档里不会重点提醒你但账单会。2.2 上下文长度对单价的影响有些平台对超长上下文是分段计价的。比如前128K token按标准价超过128K的部分单价上浮。这意味着你无脑把整篇文档塞进去可能触发高价档。我的做法是先做检索再做生成。不要把所有资料一股脑丢给模型而是先用轻量检索关键词匹配或向量检索筛出最相关的两三段再拼进上下文。这样既省token回答质量往往还更好因为模型不会被无关信息干扰。2.3 不同模型的单价梯度同一个平台往往有多个档位的模型价格能差十几倍。高阶模型适合复杂推理但很多任务其实用中低档模型就够了。我做过一个对比测试把同一批把这段文字改得更通顺的请求分别发给三个档位的模型人工盲评结果差异很小但成本差了近十倍。这里的关键不是无脑用便宜模型而是按任务分级路由。简单任务走便宜模型复杂任务才走高阶模型。这个路由逻辑后面会详细讲。3. 实测对比四种调用姿势的成本差异光说原理没意思我直接上实测数据。同一批业务请求约一万次调用输入总量约两千万token输出约四百万token我用四种不同的调用姿势各跑了一遍结果如下方案输入成本输出成本总成本相对基准A. 裸调用无缓存全用高阶模型$60$60$120100%B. 开启缓存仍全用高阶模型$18$60$7865%C. 缓存 任务分级路由$18$22$4033%D. 缓存 路由 上下文精简$11$20$3126%几个观察值得展开说。缓存带来的收益主要在输入侧从$60降到$18降幅七成。这符合预期因为输入token里重复的系统提示词占比很高。任务分级路由的收益主要在输出侧从$60降到$22。原因是很多任务的输出其实不需要高阶模型中档模型完全够用而输出单价中档模型只有高阶的三分之一左右。上下文精简是最后一块拼图把输入从$18进一步压到$11。做法就是前面说的检索前置把每次请求的输入从平均两千token压到一千二左右。四个方案叠加下来总成本从$120降到$31省了将近四分之三。而且我特意做了质量抽检方案D和方案A的回答在人工评分上差距在可接受范围内用户侧基本无感知。提示这里的单价是参考值不同平台、不同时期会有浮动但比例关系大体成立。你要做的是在自己的账号上跑一遍类似的对照实验拿到属于你的真实数字。4. 把成本压下来的五个具体动作上面是结果这一节讲怎么落地。每个动作我都会说清楚为什么这么做和具体怎么改。4.1 系统提示词做静态化改造这是投入产出比最高的一步改起来也最简单。核心原则凡是每次请求都一样的部分全部前置且保持字节级一致。具体操作把系统提示词、角色设定、输出格式要求、few-shot示例全部放在消息数组的最前面顺序固定。移除所有动态内容。时间、用户名、会话ID这类信息要么放到用户消息里要么放到系统提示词之后的位置。检查有没有隐藏的动态因素比如某些SDK会自动在开头插入时间戳或者你的模板引擎会做变量替换导致空格数量变化。我踩过的一个坑系统提示词里有个列表我用了模板循环生成结果每次生成的换行符数量因为数据源不同而略有差异缓存命中率一直上不去。后来改成硬编码的固定字符串命中率立刻从三成跳到九成以上。4.2 按任务复杂度做模型路由不是所有请求都值得用最贵的模型。我的路由规则大致是这样分类、抽取、格式转换、简单改写走最低档模型。这类任务有明确答案便宜模型足够。常规问答、摘要、中等长度生成走中档模型。这是主力档位覆盖大部分业务。复杂推理、多步规划、代码生成走高阶模型。只在必要时调用。实现上可以在请求入口加一个轻量分类器。最简单的做法是用关键词和请求长度做规则判断复杂一点可以用一个小模型做意图分类。我用的是规则加长度阈值准确率够用而且零额外成本。有个细节要注意路由判断本身不要调用大模型否则省下的钱又花回去了。规则引擎或者本地小模型是更好的选择。4.3 上下文检索前置别把整本书塞进去很多团队图省事把用户可能用到的所有资料都拼进上下文指望模型自己挑。这在token便宜的时候还行量一大就扛不住。正确做法是两段式先用检索把候选资料缩小到最相关的几段再拼进上下文。检索可以用关键词匹配BM25之类也可以用向量检索甚至简单的字符串包含判断在很多场景下就够用。我实测过一个知识库问答场景原来每次请求平均塞一万五千token的全文改成检索前置后平均只塞两千token回答准确率反而略有提升。原因是模型不再被大量无关段落干扰注意力更集中。4.4 输出长度做硬约束输出token单价高控制输出长度直接省钱。但要注意方式方法不能简单粗暴地截断那样会破坏回答质量。我的做法是在系统提示词里明确输出格式和长度预期比如用不超过三句话回答只输出JSON不要解释。同时在API参数里设置max_tokens上限防止模型跑飞。实测下来加了明确的长度约束后平均输出从八百token降到四百token左右成本减半而用户满意度没有下降。因为大部分场景下用户要的就是简洁答案冗长的解释反而是负担。4.5 批量请求合并如果你的业务里有大量小请求可以考虑合并成批量请求。比如十个用户各问一个短问题与其发十次请求不如合并成一次请求让模型分别回答。这样做的好处是摊薄了系统提示词的开销。十次请求要付十次系统提示词的钱合并成一次只付一次。当然合并也有代价延迟变高而且一个请求失败会影响一批。所以适合对实时性要求不高的场景比如离线批处理、定时任务。5. 那些让我多花冤枉钱的坑省钱的反面是踩坑。这一节记录几个我真实踩过、并且代价不小的坑希望你能绕开。5.1 重试机制没有做幂等和退避早期我的代码里有个简单的重试逻辑请求失败就立刻重发最多重试三次。结果遇到平台限流的时候大量请求失败后立刻重发又立刻失败三次重试全部打水漂token照扣钱照花但一个有效结果都没拿到。后来改成指数退避加重试上限并且对限流错误单独处理等待更长时间再试。更重要的是加了请求去重同一个请求在短时间内不重复发送。这一改无效token消耗直接降了一个数量级。5.2 流式输出中断导致的重复计费用流式输出的时候如果客户端提前断开连接服务端可能已经把整个回答生成完了token照扣。我遇到过用户频繁刷新页面导致大量流式请求被中断但账单上这些请求都是全额计费的。解决办法是在客户端做防抖避免用户操作触发重复请求同时在服务端记录请求状态对已中断的请求做标记避免重复发起。5.3 开发环境用了生产key这个坑很蠢但很常见。开发调试的时候图方便直接用了生产环境的key结果测试脚本跑了几轮把当月预算吃掉一大块。正确做法是环境隔离开发、测试、生产各用独立的key并且给开发key设置严格的额度上限。很多平台支持在key级别设置预算用满就停这个功能一定要开。5.4 日志里记录了完整请求体为了排查问题我在日志里记录了完整的请求和响应。这本身没问题但日志存储和检索也花钱而且如果日志里包含大量token内容存储成本会很高。后来改成只记录元数据请求ID、token数量、耗时、状态码需要详细内容时再按需开启。既省了存储也避免了敏感信息泄露的风险。6. 监控与告警让账单不再失控省钱不是一次性的动作而是持续的过程。业务在变调用模式在变上个月有效的策略这个月可能就失效了。所以必须建立监控。我现在的做法是每天跑一次成本统计按维度拆开看按模型哪个模型花得最多是不是该调整路由规则。按接口哪个功能最费token是不是该优化上下文。按用户有没有异常高频的调用是不是被滥用。按缓存命中率命中率掉了要立刻查原因。告警阈值我设了两档日成本超过预算的1.5倍发提醒超过2倍直接限流。限流不是目的是为了给自己争取排查时间避免月底看到账单才傻眼。另外我会定期做成本回归测试拿一批固定的测试请求跑一遍看成本有没有异常上涨。如果涨了说明某处改动引入了额外开销能第一时间发现。7. 关于API聚合与base_url的一些实践最后聊一个和成本间接相关但很重要的点接入方式的选择。现在很多人会用聚合平台来统一管理多个模型供应商通过改base_url就能切换后端。这样做的好处是灵活坏处是中间多了一层可能带来额外的延迟和不确定性而且计费口径可能和官方不一致。我的建议是核心业务尽量直连官方聚合层只用于非关键路径或做备份。原因是直连的计费透明缓存机制、限流规则都是官方原生的优化手段能直接生效。走聚合层的话你精心设计的缓存策略可能因为中间层做了请求改写而失效。如果确实需要用聚合层务必确认它是否透传了缓存相关的字段是否保持了请求前缀的一致性。我见过有人换了base_url之后成本翻倍查了半天才发现是中间层给每个请求加了动态头信息把缓存全打掉了。至于密钥管理原则很简单一个用途一个key权限最小化额度设上限。不要把生产key贴到任何公开的地方也不要在多个项目间共用同一个key。一旦某个key泄露或滥用你能快速定位并停用不至于影响全局。8. 我现在的成本结构长什么样经过上面这一轮优化我当前的成本结构大致是这样输入侧因为缓存和检索前置占比从原来的五成降到三成左右输出侧因为路由和长度约束占比从五成降到四成剩下的是各种零散开销。总体成本相比优化前降了约七成而业务量还在增长。需要说明的是这个结果不是一蹴而就的是分了好几轮迭代。第一轮只做缓存降了三成第二轮加路由又降了两成第三轮做上下文精简和输出约束再降两成。每一轮都有实测数据支撑不是拍脑袋。如果你现在正被账单困扰我的建议是先从缓存和路由这两个动作入手它们改动小、见效快、风险低。等这两块跑顺了再去做上下文精简和监控体系。不要一上来就追求完美架构那样容易半途而废。最后分享一个我自己的习惯每个月月底我会把当月的token消耗和成本拉出来和上个月做对比找出变化最大的三个点逐个分析原因。这个习惯帮我发现了好几个隐藏的成本漏洞也让我对业务的实际消耗有了更清晰的感知。毕竟省钱的前提是知道钱花在哪儿了。