Skip to content

成本速算:这个功能每次调用多少钱 ​

1. 本节产出 ​

掌握一套估算公式和一张可复用的测算表,能对任意 AI 功能在写代码之前给出单次调用成本和月度账单量级,并知道五个最常见的账单失控点。

2. 前置依赖 ​

3. 为什么要在动手前先算钱 ​

AI 项目和普通后端项目最大的区别:每一次业务调用都在烧真金白银,而且费用随流量线性增长。

三个真实翻车场景:

场景发生了什么损失
内部问答上线第一天没做缓存,同一批员工问了同样的三个问题几百次首月账单远超预算
Agent 加了重试失败自动重试 3 次,错误期间每次调用都在计费高峰期账单翻了数倍
上下文越塞越多把整个历史对话都带上,单次请求 tokens 线性膨胀单价不变但总量暴涨,且延迟同步变差

算钱这件事,早算一天省一个月。

4. 核心原理:成本由四个因子相乘 ​

单次成本 = 输入 tokens × 输入单价
         + 输出 tokens × 输出单价
         + (如有)Embedding tokens × Embedding 单价
         + (如有)Rerank 调用次数 × Rerank 单价

月度账单 = 单次成本 × 日均调用次数 × 30

要算准,关键是估准 token 数。这是 Java 工程师最容易估错的一步,因为直觉是按「字数」算。

Token 与字数的换算 ​

文本类型换算经验值
英文1 token ≈ 4 个字符 ≈ 0.75 个单词
中文1 个汉字 ≈ 0.6~1.5 token(取决于模型分词器,涉及生僻字、代码片段会更高)
代码比自然语言贵,缩进与符号都会占 token

提示:永远不要靠估算签约。上线前用真实数据跑一遍,读响应里的 usage 字段核对——这是唯一的准确数。

四个因子怎么估 ​

以「企业文档问答」为例,典型的 token 构成:

部分token 估算说明
System Prompt100-500指令、约束、格式要求
检索到的上下文Top-K 段数 × 每段 token决定性因素,K=5、每段 400 token 就是 2000
历史对话保留轮数 × 每轮多轮会话下会不断累积
用户当前问题20-200通常可以忽略
输出回答100-1000可以设置上限控制

可以看到:上下文是多轮 Agent 场景下最大的成本项。这也解释了为什么后面所有优化(切分粒度、Top-K、缓存、上下文压缩)最终都指向同一件事——少传 token。

5. 操作步骤 ​

步骤 1:建一张自己的价格表 ​

价格会变,不要抄网上过期数字。做法是在那一刻去厂商官网的定价页抄下来,填进这张表:

模型用途厂商/模型输入单价 (元/千 token)输出单价 (元/千 token)抄录日期
主力对话
廉价任务(分类/摘要)
Embedding
Rerank

提示:输出单价通常显著高于输入(常见是数倍)。这意味着「让模型少说废话」直接省钱,把 max_tokens 设置合理既是性能优化也是成本优化。

步骤 2:用真实请求取 token 数 ​

Spring AI 的响应里带用量信息:

java
ChatResponse response = chatModel.call(prompt);
Usage usage = response.getMetadata().getUsage();
System.out.printf("prompt=%d, completion=%d, total=%d%n",
    usage.getPromptTokens(), usage.getCompletionTokens(), usage.getTotalTokens());

跑十次代表性请求取平均,比估算准得多。

步骤 3:套公式算月度 ​

代入:

日均调用 = DAU × 人均调用次数
月度成本 = 单次成本 × 日均调用 × 30

步骤 4:给一个决策样例 ​

假设一个内部文档问答:单次输入 2500 token(含检索上下文),单次输出 400 token,日调用 500 次。设输入单价为 a 元/千 token,输出为 b 元/千 token:

单次 = 2.5a + 0.4b
月度 = (2.5a + 0.4b) × 500 × 30 = 37500a + 6000b

把 a、b 换成你表格里的真实数字,就得到月账单。写方案时把中间过程留下,业务方问「为什么这么贵」时,你能当场拆给他们看。

6. 验证清单 ​

  • [ ] 建立了自己的价格表,并标注抄录日期
  • [ ] 用 usage 字段核对过至少一种典型请求的真实 token 数
  • [ ] 算出的月度成本,先乘 1.3 作为含重试和意外的预算值
  • [ ] 确认已设置 max_tokens,避免输出失控
  • [ ] 明确了高峰期的调用量上限(不设限的系统在异常时会把预算烧穿)

7. 生产避坑 ​

  1. 调试期的打印就是双倍计费。每打印一次完整响应你就多花一次看不见的钱。开发环境建议把 temperature 调低、输出长度调小,并且不要在生产日志里记录完整 prompt/response(同时也合规)。
  2. 重试是隐形成本放大器。失败重试在账单上同样计费,尤其是模型超时这种场景——请求其实可能已经到达服务端。做法:重试只对幂等、且明确是连接类错误的场景开,同时给重试总量设熔断。
  3. Embedding 的钱别忽略。入库时看着是一次性成本,但文档更新频率一高就是持续支出。增量更新(只重算变更文档)和幂等设计在这里直接等价于省钱。
  4. 长上下文不是免费的灵丹妙药。很多团队发现「模型支持超长上下文」就干脆全塞进去,结果是延迟和成本同步恶化,而检索质量未必更好。
  5. 缓存命中率要单独度量。精确缓存(完全相同请求)和语义缓存(相似请求)能省下的比例差异巨大,别在方案里拍脑袋写「预计节省 50%」——这会被业务方当成承诺。

8. 延伸与锚点 ​

  • 思考题:你的场景里,输入和输出哪个占比更高?如果输入占大头 → 攻上下文压缩与缓存;如果输出占大头 → 攻约束格式和 max_tokens。
  • 代码锚点:ch00-04-cost-calculation
  • 下一章:00-05 术语表
  • 后续深化:02-18 成本治理与降级(待编写)、04-07 成本治理与预算告警(待编写)