token 的成本:模型定价是怎么运作的
"模型账单以 token 计量,而非单词或请求。弄清 token 是什么、以及你为哪些 token 付费,是让成本保持可预测的方式。"
当你通过 API 使用模型时,你不是按请求或按单词被计费的。你是按 token 被计费的。token 是模型实际读和写的单位,而模型账单上几乎每一个意外,都来自没弄清它们是什么、以及你为哪些 token 付费。好消息是,这个定价模型一旦你看清它的形状就很简单,而少数几个习惯能让成本保持可预测。坏消息是,驱动你账单的那些部分,在你屏幕上看到的文本里往往是隐形的。
本文解释 token 是什么、为什么输入和输出定价不同、隐藏的 token 藏在哪里,以及如何估算和控制你将花的钱——全都是无论你用哪个提供方或模型都保持成立的原则。
token 究竟是什么
一个 token 是一块文本——大致是一个词,但不完全是。模型不读字母或整个单词;它们把文本拆成介于两者之间的片段。一个常见的短词可能是单个 token,而一个更长或更生僻的词可能拆成两三个。空格、标点和格式也都算。人们用的粗略经验法则是,一个 token 平均比一个词稍短一点,但唯一能确切知道的办法,是让模型的分词器去数。
重要的后果是,token 数并不整齐地映射到你对长度的直觉。密集的、技术性的或非英语的文本,每词用的 token 可能比朴素的英文散文更多。代码,带着它的标点和符号,可能很费 token。所以"我的文本有多长"是错误的问题;"我的文本是多少 token"才是你账单在意的那个,而两者的分歧可能比你预期的更大。
输入 token 和输出 token 定价不同
每一次与模型的交互都有两条 token 流,而它们几乎总是花不同的钱。输入 token 是你发进去的一切——提示词、指令,以及你包含的任何文档或示例。输出 token 是模型生成回来的一切。提供方把这两者分开定价,而输出 token 通常是两者中更贵的。
原因根植于生成是如何运作的。读输入是单次通过;模型把它全部纳入并处理。产出输出则一次一个 token 地发生,每一步都是一次崭新的运算,依赖于到目前为止生成的一切。那种一步一步的产出是昂贵的部分,这就是为什么生成的输出通常比它所回应的输入带着更高的价格。知道这点会改变你的优化方式:一份长输出,往往比一份长输入更能撬动你的账单。
驱动你账单的隐藏 token
最常见的账单意外,来自你从未明确敲下的 token。三个来源尤为突出。
第一,**你重新发送的系统指令和上下文。**在一段对话里,模型在各轮之间没有记忆——所以为了保持连贯,应用会随每一个请求重新发送先前的对话和任何常设指令。那段历史的成本在每一轮都被再付一次。一段长对话每条消息变得越来越贵,因为每条新消息都拖着整份记录作为输入一起来。
第二,**检索或附加的内容。**当你给模型文档据以工作时,那些 token 中的每一个都是你付费的输入。一个把大文档塞进提示词的功能,每次调用可能悄悄花掉远比用户那个短问题所暗示的更多的钱。
第三,**模型自己的中间工作。**有些模型在给出最终答案之前会产出内部推理,而那段中间文本是你通常要为之付费的生成输出,即便它没有展示给用户。一个简短的可见答案,可能坐在一大堆已付费的生成之上。
为什么上下文窗口对成本要紧
每个模型都有它一次能考虑的最大文本量——它的上下文窗口。把一个大的上下文窗口当成可以免费往里倒一切的空间,是很有诱惑力的,但窗口是一个容量,不是一个预算。你仍然为放进去的每一个 token 付费。把一个大窗口填到满溢,意味着每次调用都为一份大输入付钱。
窗口确实施加了一个硬上限:输入加输出不能超过它。但实际的纪律,是用得远低于这个最大值。你为完成任务发送的 token 越少,每次调用就越便宜,而且往往返回得越快。一个大窗口是给偶尔的大活准备的便利,不是在例行小活上挥霍的许可证。
估算和控制开销
你在还没上线之前就能预测成本。算术很直接:估算每次调用典型的输入 token 和输出 token,各自乘以对应的价格,再乘以你预期的调用次数。在构建之前在信封背面做这件事,能在昂贵的设计还便宜可改时就把它们抓出来。
要在运行之后控制开销,几个习惯做了大部分工作。修剪你发送的东西——丢掉你不需要的对话历史,概括长上下文而非逐字重发,并只包含要紧的文档。在任务允许时给输出长度设上限,因为输出是更贵的那条流。为例行工作去抓一个更小、更便宜的模型,把昂贵的那个留给确实需要它的调用。并测量真实用量而非信任估算,因为真实流量上的实际 token 数,才是付账单的那些数字。
一个快速的直觉演练
设想一个客服助手。一个用户敲下一行问题——输入很小。但你的系统还发送了一页常设指令、对话的最近几轮,以及三篇检索到的帮助文章。用户可见的文字是一个舍入误差;真正的输入是那些指令、历史和文章,在每一轮都重复。如果助手接着写了一份周到的多段回复,那份输出可能比所有输入加起来还贵。这样看一次调用——大部分成本都在用户从不见到的地方——就是全部的洞见。优化那个可见的问题什么也省不下;修剪那不可见的上下文和输出长度,才是钱所在的地方。
总结
你付费的是 token,而非单词或请求——而驱动你账单的 token,通常是你看不见的那些:重发的对话历史、附加的文档、常设指令,以及模型自己的中间生成。输入和输出分开定价,输出通常更贵。一个大的上下文窗口是你付费去填的容量,不是免费空间。在构建之前用简单的算术估算,修剪你发送的、给你生成的设上限,并测量真实用量。token 定价奖励那些确切知道自己在发送什么的人,惩罚那些不知道的人。
