Token 这玩意儿你可以粗暴理解成 “模型眼里的字”,但不是咱们平时说的字。模型底层是 BPE(Byte Pair Encoding)那一套,把文本切成一堆子词片段,每个片段对应一个 token id。所以同样一段话,不同模型切出来的 token 数可能不一样,甚至差挺多。
中英文和代码的差异,经验值大概是这样:
- 英文:1 个 token ≈ 4 个字符 ≈ 0.75 个单词。也就是说 100 个英文单词大概 130 多个 token。
- 中文:1 个汉字通常 1~2 个 token,常见字很多是 1 个,生僻字或者跟标点混在一起可能变 2 个甚至更多。粗算的话中文 1 个字 ≈ 1.5 token 比较稳。
- 代码:代码 token 密度很高,因为符号、缩进、括号、下划线这些都是独立 token。一段 100 行的 Python 可能轻松上千 token。缩进如果是 4 个空格,可能每个空格都算或者合并算,反正很费。
- 数字和特殊符号:也经常被切得很碎,比如一串 UUID 或者 base64 字符串,token 数可能比字符数还多。
输入和输出是分开算的,这个坑很多人一开始没注意。你发过去的 prompt(包括 system prompt、历史对话、few-shot 示例)全算输入 token,模型吐出来的内容算输出 token。输出通常比输入贵 2~4 倍,所以别把一堆没用的上下文塞进去,历史对话该截断就截断。
自己算的话,最准的办法是用对应模型的 tokenizer:
- OpenAI 系:
tiktoken库,Python 里pip install tiktoken,然后encoding_for_model("gpt-4o")直接 encode 数长度。 - Claude:官方有
anthropicSDK,也可以装anthropic-tokenizer或者用transformers加载对应 tokenizer。 - DeepSeek、Qwen 这些国产的:基本都是基于 BPE 的,HuggingFace 上找对应模型的 tokenizer 就行,
AutoTokenizer.from_pretrained然后len(tokenizer.encode(text))。 - Gemini:官方有
count_tokens接口,直接调。
不想写代码的,OpenAI 官方的 tokenizer 页面(platform.openai.com/tokenizer)可以直接粘贴看,不过只支持 OpenAI 自己的模型。通用一点的可以用 tiktoken 自己跑个脚本,或者网上有些在线的 token 计数器,但注意它们不一定跟你用的模型完全一致。
实际开发里我的建议是:别追求精确到个位数,按字符数估个大概就行,比如中文按 1.5 倍字符数、英文按 0.25 倍字符数粗算,留 20% buffer。真要卡预算,就在关键路径上用 tiktoken 或对应 tokenizer 精确算一下,其他地方估算够了。上下文管理比精确计数重要得多,很多人 token 爆了不是因为算不准,是因为历史对话没裁剪、system prompt 写太长。