一、什么是 Token?为什么它比“字数”更重要?

当我们与大语言模型(LLM)交互时,无论是输入问题还是获得回答,模型处理的都不是我们人类理解的“字”或“词”,而是 Token。你可以将 Token 理解为模型的“最小意义单元”。一个英文单词可能由1-2个Token组成(例如,"Transformer" 可能被拆分为 ["Trans", "former"]),而一个中文汉字通常会被编码为1-2个Token,有时一个常用词(如“你好”)甚至可能被当作一个单独的Token。

为什么不用简单的字数统计呢?因为模型内部的“分词器”(Tokenizer)有一套自己的逻辑。它的目标是将文本高效地转换成模型能理解的数字ID序列。这个过程叫做 Tokenization。不同的模型(如GPT系列、Claude、国产的GLM等)使用不同的分词器,因此同一段文本在不同模型下产生的Token数量可能不同。这正是理解后续计费原理的基础。

关键提示:在模型看来,你输入的“请帮我写一篇500字的文章”这句话,本身就已经被拆解成了若干Token。你请求生成500字,模型在计算时,也需要将这个“字数”目标折算成大约对应的Token数量(中文大约1.5-2个Token/字)。

二、如何计算一段文本消耗了多少 Token?

手动计算Token非常麻烦且不准确,最佳实践是使用官方或社区提供的工具进行精确计算。大多数主流模型提供商都提供了开源的Token计算器库。

以OpenAI的模型为例,你可以使用 tiktoken 这个Python库。首先安装它,然后加载对应模型的分词器来查看编码结果。

# 安装: pip install tiktoken
import tiktoken

# 选择一个模型对应的编码器,例如 “cl100k_base” 用于GPT-3.5/4
enc = tiktoken.get_encoding("cl100k_base")

text = "大模型的Token与计费原理,是我们理解其运行成本的关键。"
token_integers = enc.encode(text) # 得到Token对应的整数ID列表
tokens = [enc.decode_single_token_bytes(token) for token in token_integers] # 将ID解码回字节形式,便于观察

print(f"原始文本: {text}")
print(f"Token ID列表: {token_integers}")
print(f"Token切分结果: {tokens}")
print(f"总Token数: {len(token_integers)}")

运行上述代码,你会看到文本被切分成了若干个“子词”片段。这就是模型实际“看到”的内容。掌握这个计算能力,对于预估API调用成本和优化Prompt至关重要。

三、Token 与 API 调用费用的关系

大模型服务提供商(如OpenAI、Anthropic、各大云厂商)的API计费模式,核心就是 按量计费,而这个“量”的计量单位正是 Token。通常,计费会区分输入Token和输出Token,并且价格不同。

例如,某模型的定价可能是:输入 $0.001 / 1K tokens,输出 $0.002 / 1K tokens。这意味着:

总费用 = (输入Token数 / 1000 * 输入单价) + (输出Token数 / 1000 * 输出单价)。因此,一次API调用的总Token数 = 输入Token + 输出Token。理解这个公式,你就明白了为什么节省Token就是节省真金白银。

四、节省 Token 成本的实用策略

既然Token直接与成本挂钩,那么优化Token消耗就是使用大模型时的核心技能。以下是几个关键策略:

五、多轮对话中的 Token 累积实战

在多轮对话场景中,Token的消耗模式有一个重要特点:每次API调用,你都需要将之前的对话历史作为上下文一起发送。这意味着Token数量会像滚雪球一样增长。

假设一个简单的客服对话:

import tiktoken
enc = tiktoken.get_encoding("cl100k_base")

# 模拟多轮对话历史(角色: 内容)
history = [
    {"role": "user", "content": "你好,我想查询订单状态。"},
    {"role": "assistant", "content": "您好,请提供您的订单号,我为您查询。"},
    {"role": "user", "content": "订单号是12345678。"}
]

# 构建下一次发给模型的完整提示
next_prompt = f"""
请根据以下对话历史,以客服身份给出最终回复。

历史对话:
{[msg['content'] for msg in history]}

我的最新问题:我的包裹大概什么时候能到?
"""

# 计算本次调用需要的输入Token(包含所有历史)
input_tokens = len(enc.encode(next_prompt))
print(f"本次请求的输入Token数(包含历史上下文): {input_tokens}")

# 模型回复后,新的历史会增长,下一次调用的Token会更多

从这个例子可以看出,对话历史本身是Token消耗的大头。优化策略包括定期用新总结替换旧历史,或使用支持“系统消息”来设定初始角色,避免在每轮中重复描述。

六、总结与关键提示

理解Token机制,是从“会用大模型”进阶到“用好大模型”的关键一步。它不仅是成本的标尺,也直接影响模型的理解效果——因为模型的“工作记忆”窗口(上下文长度)是以Token来计量的。

最终提示:养成使用Token计算工具预估成本的习惯。在设计应用时,将Token优化作为架构设计的一环,例如在后端记录每次API调用的Token消耗,设置预算告警。记住,在大模型应用领域,对Token的精细化管理,等同于对性能和成本的精细管理。