AI 应用怎么预估单次请求成本:token 估算、预算阈值与超额降级
来源:17golang原创
时间:2026-08-25 17:58:34 162浏览 收藏
AI 功能刚上线时,账单往往看不出问题;等到长对话、检索片段和失败重试一起出现,单次请求的输入量就会悄悄翻倍。更稳妥的做法,是在真正发起模型请求前先算一遍预算,调用完成后再用服务端返回的 usage 对账,超过阈值就切换到短上下文、较小输出或人工确认路径。
要点速览
- 预估值用于拦截和路由,最终 usage 用于账单对账,两个数字不能混为一谈。
- 预算至少拆成输入 token、输出上限和重试预留三部分。
- 超额时优先减少历史消息和检索片段,不要直接截断用户问题。
- 每次请求记录模型、估算值、实际 usage、降级原因和 request_id,才能定位成本异常。

先把一次 AI 请求拆成可计算的账单
一个聊天请求的成本,不只是用户刚输入的那句话。系统提示词、历史消息、检索出来的文档、工具结果和模型输出都会进入 token 统计。不同供应商的计费单位和字段名称可能不同,所以预算器只负责统一口径,不应该把某一家模型的字段名硬编码到业务层。
可以先定义一个内部结构:
type Usage struct {
InputTokens int
OutputTokens int
}
type Price struct {
InputPerMillion float64
OutputPerMillion float64
}
func estimateCost(u Usage, p Price) float64 {
return float64(u.InputTokens)/1_000_000*p.InputPerMillion +
float64(u.OutputTokens)/1_000_000*p.OutputPerMillion
}
这里的价格只是配置,不写进代码。模型、区域、缓存输入和批量通道都可能有不同口径;如果供应商返回了缓存 token、思考 token或工具 token,应在适配层保留原始字段,再决定哪些计入业务预算。
做一个请求预算器:先估算,再决定是否发送
预算器的输入应包含完整上下文,而不是只统计最后一条用户消息。一个能落地的小项目可以只做四步:整理消息、估算输入量、预留输出空间、按照阈值选择路径。
type Budget struct {
InputLimit int
OutputLimit int
RetryReserve int
}
type Decision struct {
Allowed bool
Mode string
Reason string
}
func decide(inputEstimate int, b Budget) Decision {
if inputEstimate > b.InputLimit {
return Decision{Allowed: true, Mode: "short-context", Reason: "input-over-limit"}
}
if inputEstimate+b.OutputLimit+b.RetryReserve > b.InputLimit+b.OutputLimit*2 {
return Decision{Allowed: true, Mode: "small-output", Reason: "budget-tight"}
}
return Decision{Allowed: true, Mode: "normal", Reason: "within-budget"}
}
这个判断故意没有把超额直接变成失败。面向用户的聊天功能通常更适合先降级:减少最旧的历史轮次、把检索片段从 8 个缩到 4 个、降低输出上限,最后才提示用户缩短问题。若是批处理或高价值事务,则可以把同样的分支改成排队或人工审核。
估算器不要假装自己知道精确 token 数
字符数乘一个固定比例只能做粗略预警,中文、英文、代码、JSON 和图片的 token 化结果差别很大。能调用供应商的计数接口时,用同一份最终请求体做预估;不能调用时,用保守上限,并把估算误差记录下来。Google 的 Gemini 文档明确区分了调用前的 count_tokens 与响应中的 usage;这正好说明预估和实际对账是两个阶段。
把超额降级做成可解释的路径
降级不是简单地删字符串。删掉 JSON 的半个字段、代码块的中间行或检索证据的标题,都会让模型收到难以解释的上下文。建议给每种输入分配优先级:
- 最高:当前用户问题、系统安全约束、必须保留的业务字段。
- 中等:最近两到四轮对话、检索结果的标题和关键段落。
- 较低:更早的闲聊、重复的工具结果、已经被摘要覆盖的历史内容。
每次裁剪都产生一个新的 context_version,例如 v3-short-history。日志中同时保存裁剪前后的估算值和原因,排查“为什么这次回答变短”时才有证据。

用 usage 做事后对账,而不是只看预算器结果
真正发出请求后,把响应里的 usage 复制到统一账单事件。至少保留 model、request_id、estimated_input、actual_input、actual_output、fallback_mode 和 retry_count。估算值与实际值的比值长期偏离时,优先检查消息拼接、缓存命中和工具结果是否被重复加入。
type CostEvent struct {
RequestID string
Model string
EstimatedInput int
ActualInput int
ActualOutput int
FallbackMode string
RetryCount int
}
func estimateGap(e CostEvent) float64 {
if e.EstimatedInput == 0 {
return 0
}
return float64(e.ActualInput-e.EstimatedInput) / float64(e.EstimatedInput)
}
监控上不要只放一个总成本数字。把输入、输出、重试、降级比例和单用户日累计分开看,才能区分“某个模型单价变化”和“上下文拼接变长”这两类问题。预算事件也不应写入完整用户原文,保留长度、哈希或脱敏后的摘要即可。
验收清单:四组样本跑完再放量
一个可复现的验收集至少包含短问题、长历史、长检索片段和一次失败重试。固定模型配置与输入,分别记录估算 token、实际 token、响应长度和最终模式。检查重点有四个:
- 预算内请求走 normal,估算超额请求走 short-context 或 small-output。
- 裁剪后的上下文仍保留当前问题和必要约束,不出现半截 JSON 或孤立代码。
- 响应 usage 能和 request_id 对上,重试不会重复记成两次用户请求。
- 估算与实际偏差超过约定阈值时有告警,而不是静默放过。
先在低比例流量上观察,再扩大范围。预算器的目标不是把每次请求都压到最小,而是让成本、回答质量和降级原因都能被看见。
相关问题
只按字符数估算 token 可以上线吗?
可以作为没有计数接口时的保守预警,但不适合作为精确计费。上线后要用实际 usage 持续校准比例,并给代码、JSON 和多模态输入单独留出误差。
超过预算后应该优先减少输入还是输出?
通常先裁剪低优先级历史和重复检索片段;如果用户问题必须完整保留,再降低输出上限。两者都不能破坏安全约束和结构化结果的完整性。
缓存 token 要不要算进应用预算?
要同时保留“上下文规模”和“实际计费口径”两个指标。缓存可能降低某些输入成本,但并不代表上下文可以无限增长,容量和延迟仍然存在。
小结
AI 成本治理的最小闭环是:发送前用完整上下文做估算,超过阈值选择可解释的降级路径,响应后用 usage 对账,再用固定样本验证估算误差和回答质量。这样模型换了、提示词长了或重试增加了,系统都能给出具体的成本证据,而不是等月底账单出现异常才回头猜。
-
284 收藏
-
387 收藏
-
328 收藏
-
426 收藏
-
147 收藏
-
102 收藏
-
255 收藏
-
288 收藏
-
418 收藏
-
231 收藏
-
313 收藏
-
466 收藏
-
398 收藏
-
269 收藏
-
460 收藏
-
科技周边 · 人工智能 | 15小时前 | 人工智能 · gemini · function calling · 结构化输出 · 接口测试 · 结构化输出 JSON Schema Gemini 3 Function Calling 工具调用验收346 收藏
-
289 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习