logo

大模型调用单价上涨后,如何判断真实成本

作者:da吃一鲸8862026.11.10 15:51浏览量:1

简介:模型单价上涨不等于总账单同步上涨。多轮任务中的上下文累积、缓存命中、输出长度和成功率,同样决定最终花费。本文拆解单价、用量与任务轮次之间的关系,给出可复用的成本估算公式和代码示例,并说明如何通过上下文管理控制开销,帮助团队在选型和预算前做出可验证的判断。

一、单价与总成本是两个问题

大模型服务通常按输入 token、命中缓存的输入 token、输出 token 分别计价。单价是每百万 token 的价格,它是一个固定参数。总成本则是各类 token 用量乘以对应单价,再把所有轮次的结果加总。两者经常被混为一谈。某个模型的单价翻倍,同一任务的账单未必翻倍。反过来,单价下降也可能因为模型需要更多轮次才能完成任务,让总花费不降反升。

判断成本时,需要同时回答三个问题:完成一次任务需要多少次请求,每次请求消耗多少各类 token,各类 token 的单价是多少。只看单价,只能得到一个局部结论。

二、用切披萨理解单位价格

同一张披萨切成 8 块,每块 2 美元,总价 16 美元。切成 16 块,每块 1.25 美元,总价 20 美元。第二种切法的单价更低,但人吃下的披萨量没有变化,所以总支出更高。

这个类比对应到模型调用中,可以这样理解。单价相当于每块披萨的价格。有效工作量相当于真正吃下去的那部分,也就是完成任务所需的有效 token 和有效步骤。如果一个模型能用更少的 token 和更少的步骤解决问题,即使单价偏高,总成本也可能更低。如果一个模型单价低,却需要反复试错,总用量就会被放大。

因此,比较模型时应当比较“完成同一任务的总成本”,而不是比较“每百万 token 多少钱”。

三、多轮交互中的成本放大机制

在对话式或代理式的工作流中,每一轮请求通常会带上完整历史,包括之前的提问、模型回复、工具返回结果等。这意味着输入 token 会随轮次持续增长。

假设初始上下文为 2000 token,每轮新增约 1500 token(包括工具返回和模型输出),共运行 10 轮。第 k 轮的输入量约为 2000 + 1500 × (k − 1)。10 轮累计输入约为 87,500 token,累计输出按每轮 500 token 计算为 5,000 token。输入量的增长近似于轮次的平方关系,轮次越多,后期每一轮的输入成本越高。

这类场景有两个特点。第一,任务目标不够清晰,模型需要“做一步、看一步”,轮次难以预先确定。第二,每一步都依赖上一步的反馈,无法批量合并请求。在这种情况下,输入单价和缓存单价对总成本的影响,比单次问答时更明显。

输出 token 的价格通常高于输入 token。长篇回复、冗长的推理过程或不必要的解释,会在输出侧快速累积费用。控制输出长度与控制输入长度同样重要。

四、上下文管理策略对成本的影响

上下文管理方式直接决定每轮的输入规模。常见策略有四种,各自的成本特征不同。

1. 完整保留历史。 实现最简单,信息无损失。但输入随轮次增长,适合轮次少、单轮信息量小的任务。

2. 摘要压缩。 定期把历史对话压缩为摘要,只保留摘要和最近几轮。输入规模可控,但生成摘要本身需要消耗 token,而且摘要可能遗漏关键细节,导致后续返工。返工的成本需要计入总账。

3. 分段会话加外部记录。 把长任务拆分为多个会话,每个会话开始时只带入必要的状态。状态信息写入外部存储,例如任务清单、决策日志、关键参数表。每次只读取当前步骤需要的内容。这种方式能有效控制单轮输入,代价是增加了状态设计和恢复的工程复杂度。

4. 检索式引入上下文。 将历史内容切分后存入索引,每轮只检索与当前问题相关的片段。适合知识量大、但每步只需局部信息的场景。检索质量不稳定时,模型可能缺少关键依据,需要额外的校验步骤。

部分计费方案会按上下文长度分档,超过某个阈值后单价发生变化。评估时需要核对计费规则中是否存在此类分档,并把分档边界纳入成本模型。

缓存是另一项关键因素。如果多轮请求的前缀内容保持稳定,缓存命中率会明显提高,输入成本随之下降。为了提高命中率,应当把不变的指令、角色设定和参考资料放在请求的前部,把每轮变化的内容放在后部。

五、配额与计费维度的区分

同一个模型的使用入口可能有多种,例如交互式对话、开发工具内嵌调用、直接接口调用。不同入口的配额和计费方式可能相互独立。

配额规则需要关注以下几点:

  • 计量单位是按会话条数、按 token 数,还是按时间窗口计算。
  • 不同入口之间是否共享额度,是否存在单独的每日或每周上限。
  • 额度耗尽后,系统是中断服务、降级到其他模型,还是按超额单价计费。
  • 降级策略是否会改变输出质量,进而影响任务的成功率和返工次数。

这些规则决定了实际可用额度,也决定了团队应当把哪些任务放在哪个入口运行。

六、评估框架:从单任务成本到单位成功成本

一套可靠的评估方法通常包含以下步骤。

  1. 建立标准任务集。选择 20 到 50 个代表真实业务的任务,覆盖简单、中等和复杂三个层次。
  2. 记录每次运行的轮次、输入 token、缓存命中 token、输出 token。
  3. 按计费规则计算每个任务的成本。
  4. 判断每个任务是否成功,统计成功率。
  5. 计算单位成功成本,即总成本除以成功任务数。

单位成功成本是最关键的指标。一个单价较低的方案如果成功率偏低,需要更多重试,单位成功成本可能高于单价较高但一次完成率高的方案。

下面的代码给出成本计算的基础实现。其中的价格参数为示意值,不对应任何具体服务。

  1. from dataclasses import dataclass
  2. from typing import List, Tuple
  3. @dataclass
  4. class Pricing:
  5. input_per_m: float # 每百万未命中缓存的输入 token 单价
  6. cached_per_m: float # 每百万命中缓存的输入 token 单价
  7. output_per_m: float # 每百万输出 token 单价
  8. @dataclass
  9. class RoundUsage:
  10. input_tokens: int # 本轮输入 token 总数(含缓存部分)
  11. cached_tokens: int # 本轮命中缓存的输入 token 数
  12. output_tokens: int # 本轮输出 token 数
  13. def task_cost(rounds: List[RoundUsage], p: Pricing) -> float:
  14. """计算单个任务在所有轮次中的总成本。"""
  15. total = 0.0
  16. for r in rounds:
  17. fresh = r.input_tokens - r.cached_tokens
  18. total += fresh * p.input_per_m / 1_000_000
  19. total += r.cached_tokens * p.cached_per_m / 1_000_000
  20. total += r.output_tokens * p.output_per_m / 1_000_000
  21. return total
  22. def cost_per_success(
  23. results: List[Tuple[List[RoundUsage], bool]],
  24. p: Pricing,
  25. ) -> float:
  26. """计算单位成功成本:总成本除以成功任务数。"""
  27. total = sum(task_cost(rounds, p) for rounds, _ in results)
  28. successes = sum(1 for _, ok in results if ok)
  29. if successes == 0:
  30. return float("inf")
  31. return total / successes
  32. if __name__ == "__main__":
  33. # 示意价格,单位为任意货币单位
  34. pricing = Pricing(input_per_m=2.0, cached_per_m=0.2, output_per_m=10.0)
  35. # 模拟 10 轮任务:输入从 2000 逐轮增加 1500,输出每轮 500,无缓存
  36. rounds = []
  37. for k in range(10):
  38. rounds.append(RoundUsage(
  39. input_tokens=2000 + 1500 * k,
  40. cached_tokens=0,
  41. output_tokens=500,
  42. ))
  43. print(f"单任务成本: {task_cost(rounds, pricing):.4f}")

运行上述示例,10 轮无缓存任务的输入成本约为 0.175,输出成本约为 0.05,合计约 0.225。若把前缀内容改为缓存命中,输入成本会明显下降。评估时应当分别统计两种情况,以确定缓存策略的实际收益。

七、落地建议

  • 选型前先定义标准任务集,用同一套任务比较不同方案,避免凭单价做判断。
  • 同时记录成本、耗时和成功率,计算单位成功成本,作为主要决策指标。
  • 把不变的指令和参考资料放在请求前部,提高缓存命中率。
  • 对长任务采用分段会话和外部状态记录,控制单轮输入规模。
  • 限制输出长度,要求模型只返回结构化结果或必要信息,减少输出 token 的浪费。
  • 核对计费规则中的配额、分档边界和超额策略,把这些条件写入成本模型。
  • 定期用真实流量回放评估结果,因为任务分布变化会改变各项成本的权重。

发表评论

活动