Token 是子词片段,因此数量永远不会与单词数一致。对于普通英语,一个 token 平均约等于 4 到 5 个字符,因此 1,000 个单词大致在 1,050 到 1,350 个 token 之间,具体取决于文字的技术性有多强。代码、非英语文字和生僻词的每字符 token 消耗更高,有时甚至高出数倍。
Token 到底是什么
语言模型读取的不是字符,也不是单词,而是 token:按照从训练数据中学到的固定词表,把文本切分后得到的片段。
常见单词通常就是一个 token。生僻词则会被拆成几段。空格一般附着在下一个 token 的前面,这就是为什么同一个单词在句首和句中的计数可能不同。
用 GPT-4o 的分词器实测,unbelievable 这个词单独出现时是三个 token:un + bel + ievable。但按照它在句子里实际出现的样子,也就是带上前导空格写成 unbelievable 时,它就只是一个 token。这正是前导空格规则在起作用——模型学到的那个词表条目是带空格的形式,因为这个词在连续文本中几乎总是以这种形式出现。the 和 international 也是一样,带上空格之后各自都只有一个 token。
这就是 token 计数难以预估的原因。它的单位不是语言学意义上的,而是统计学意义上的:在训练语料中的出现频率,决定了某个内容是一个 token 还是四个。
36 个字符 · 7 个 token · 平均每个 token 约 5.1 个字符
英语经验法则:1 个 token ≈ 4 个字符 ≈ 0.75 个单词。
代码、非英语文字和生僻词每个字符会占用更多 token。
真正靠得住的经验法则
对于英语文章,用 GPT-4o 的分词器在从日常对话式写作到技术参考资料的各种文体上实测:
- 1 token ≈ 4.3–5.9 个字符
- 1 token ≈ 0.75–0.95 个单词
- 1,000 个单词 ≈ 1,050–1,350 个 token
- 一个标准页面(约 500 词)≈ 530–680 个 token
上面四条说的都是英语文章,中文的情况见下表。文体的影响比大多数经验法则承认的要大得多。轻松的对话式写作落在这个区间的下端,每千词约 1,060 个 token,因为它反复使用的是一小批常见单词,每个都正好占一个 token。密度高的技术性文字——包括本站自己的指南——则落在上端,约 1,310 个,因为专业术语会被拆成好几段。大家熟悉的"每千词 1,300 个 token"这个单一数值,是这个区间技术性的那一端,而不是中间值,所以它会把普通写作高估五分之一左右。而在规划上下文窗口时,往这个方向估错恰恰是安全的一侧。
一旦超出普通文章的范围,这些法则就会迅速失效:
| 内容类型 | 大致情况 |
|---|---|
| 英语文章 | 每个 token 约 0.75–0.95 个单词,视文体而定 |
| 代码 | 按字符算约为文章的 1.2 倍;同一个意思分别用代码和文字表达,约为 1.5 倍 |
| 键名较长的 JSON | 非常高——标点和引号都是独立 token |
| 中文、日文、韩文 | 每个字符约 0.6–0.7 个 token——不到一个 token,但在相同字符数下仍是英语开销的好几倍 |
| 西里尔文、天城文、阿拉伯文 | 同一段文本约为英语的 1.4–1.6 倍 |
| URL 和哈希值 | 极高——随机字符串的分词效果很差 |
| 连续重复的空白 | 便宜而非昂贵——字节对编码会把长串合并,四十个连续空格只算一个 token |
多语言之间的差距确实存在,但远比传闻中的小。以本站英文页面和它们的专业译文实测:日语版本约为英语的 1.7 倍,韩语约 1.5 倍,中文约 1.2 倍,印地语约 1.6 倍,阿拉伯语约 1.4 倍。在更早的 cl100k_base 分词器下,同样这几对文本分别是 2.3 倍、2.3 倍、1.7 倍、4.7 倍和 2.9 倍——"英语的两三倍"这个广为流传的说法正是由此而来。它在当时确实成立;而新一代词表已在很大程度上抹平了这个差距。
为什么不同模型的计数不一样
每个模型家族都使用自己的分词器和词表,所以同一段文本会得出不同的计数。
GPT 系列使用字节对编码的变体——GPT-4 时代的模型用 cl100k_base,更新的模型用 o200k_base。Claude 使用另一套分词器和词表。Llama、Mistral 等开源模型又各有各的方案。
词表的分歧在代码和非英语文本上最明显,所以计数的差异也在这些地方最大。
实际这意味着:
- 来自某个分词器的计数,对其他模型来说只是估算值。
- 只有服务商自己的分词器才能给出与其计费一致的精确数字。
- 做预算时要留出余量,而不是卡着上限来安排。
我们的 Token 计数器 会同时给出 GPT-4o 的计数和 Claude 的估算值。GPT-4o 那个数字是真实的分词器计数,Claude 那个则有意不是:Anthropic 没有公开可以在你浏览器里运行的分词器,所以它是按每 3.5 个字符一个 token 得出的字符数估算。在英语文章上,这个估算值比 GPT-4o 的计数高出 22–50%,普通写作大约高三分之一——所以这个差距应当理解为估算本身的误差范围,而不是两个模型家族之间实测出来的差异。即便如此,这两个数字放在一起,仍然足以判断一个提示词是距离上限还很宽裕,还是已经逼近极限;当数字必须精确时,请使用服务商自己的计数器。
为什么这个数字很重要
费用。 API 按 token 计价,输入和输出分别计费,输出通常贵好几倍。系统提示词翻倍,意味着每一次调用的这部分成本都翻倍——测试时察觉不到,上了规模就很可观。
上下文限制。 窗口装的是所有内容:系统提示词、对话历史、检索到的文档、当前消息,以及为回复预留的空间。长对话出问题,往往不是因为某一条消息太长,而是历史在不断累积。
截断。 输入超出限制时,总会有内容被丢弃——常常是静默发生的,而且被丢的往往是最早的内容。模型"忘记"了你的指令,很多时候只是指令被截断掉了。
检索时的分块。 为生成嵌入而切分文档时,按的是 token 而不是字符。按字符数定长的分块会大小不一,从句子中间切断的分块检索效果很差,因此检索流水线需要一个尊重句子和段落结构的分割工具。我们的 文本分割工具 并不是这样的工具:它切出的是最长 2,000 个字符的定长分块,在最近的空白处断开,因此不会把单词切成两半,但一个分块可能停在句子中间。请用它把长文档塞进上下文窗口或粘贴长度限制——而不是用来生成检索所需的嵌入分块。
如何在不损失含义的前提下减少 token
收效最高的缩减方法,大致按优先级排序:
- 精简对话历史。 在长对话中,它占的比例远超其他一切。把旧的对话轮次总结后再发,而不是原样重发。
- 删掉重复的指令。 同一条规则用三种说法重复,不会让遵守概率变成三倍,但一定会让这条规则的成本变成三倍。
- 清除格式残留。 不可见字符、重复空白和装饰性分隔线都会消耗 token。单看每一处,它们其实比大家想象的便宜,因为字节对编码会把长串合并:四十个连续空格只算一个 token,一行四十个连字符的分隔线只算两个,而它上面那句话是十三个。但它们仍然是纯粹的额外开销,如果一份文档每一节之间都有一条分隔线,累积起来就相当可观。删除不可见字符 可以清掉那些看不见的东西。
- 缩短结构化提示词中的 JSON 键名。
{"n": ...}与{"customer_full_name": ...}的差别,乘以上千条记录就很可观。 - 只发送相关片段。 检索出三段相关内容,胜过粘贴整篇文档,而且通常回答质量也更好、成本更低。
没有帮助的做法:删掉普通标点、删冠词,或者用电报式的极简风格写作。省下的 token 微乎其微,对输出质量的损害却不是。
常见问题
1,000 个单词是多少 token?
用 GPT-4o 的分词器实测,大约在 1,050 到 1,350 个 token 之间。对话式写作接近 1,060,因为它反复使用的是常见的单 token 单词;密度高的技术性文字则接近 1,310。代码和 JSON 会更高。中文、日文、韩文每个字符约 0.6 到 0.7 个 token:token 数比字符数少,但在相同字符数下仍是英语开销的好几倍。
为什么 GPT 和 Claude 的 token 计数不同?
每个模型家族使用自己的分词器和各自学到的词表,因此同一段文本的切分方式不同,其中代码和非英语文本的差异最大。另外要注意,我们 Token 计数器里的 Claude 数字是按每 3.5 个字符一个 token 得出的字符数估算,并非真实的分词器计数,这正是它在英语文章上比 GPT-4o 计数高出约三分之一的原因。
AI 模型中的 token 是什么?
来自模型固定词表的文本片段。常见单词通常是单个 token,生僻词会拆成几段,所以 'unbelievable' 可能变成三个 token,而 'international' 只有一个。
空格和标点算 token 吗?
算。空白通常附着在下一个 token 前面,标点也常常自成 token。长串是个例外:字节对编码会把它们合并,所以四十个连续空格只是一个 token,一行四十个连字符的分隔线只算两个。
如何减少 token 用量?
首先精简累积的对话历史——在长对话中它占绝对大头。然后删除重复的指令、清除不可见字符和重复空白、缩短 JSON 键名,并且只发送文档的相关片段,而不是整篇内容。