Tokenizer:理解 token 才能真正控成本
token 是 LLM 的计费单位和上下文货币,但很多人对它只有模糊概念——中文一个字几个 token?代码占多少?为什么切词影响成本和效果?本文讲清 tokenizer 原理(BPE)、不同语言的 token 效率、用 tiktoken 实测、以及控成本的实操(缩 prompt/选高效语言/缓存)。
本文要点
- 主题聚焦:大模型、TypeScript
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
调 LLM 的开发者,十个有九个说不清自己上一条 prompt 到底烧了多少 token。大家知道"按 token 计费",但对 token 的理解常常停留在"大概就是字符吧"——于是估算成本靠拍脑袋、截断上下文按字数、prompt 塞满了还觉得"没多少"。结果是账单失控、上下文爆窗、中文应用天然比英文贵一截却不知为何。
token 不是字符,也不是词。不理解这个最小单位,成本优化和上下文工程都是空中楼阁。这篇文章把 tokenizer 讲到能落地:原理、语言效率差异、用 tiktoken 实测、以及真正省钱的实操。
一、token 不是字符,也不是词,是子词单元
人类看文本按"词"或"字",模型只认数字。中间这座桥就是 tokenizer:把文本切成一个个离散片段,每片查表映射成一个整数 ID,模型再处理这些 ID。这个片段就是 token。
关键在于 token 的颗粒度介于字符和词之间,叫子词(subword):
- 高频整词是 1 个 token:
"hello"、"world"、"the"。 - 低频或组合词会被拆开:
"unbelievable"→"un"+"believ"+"able","tiktoken"→"tik"+"token"(它太新,训练语料里没整词)。 - 罕见字符、emoji 往往要多个 token 才能拼出一个字。
一个朴素但被忽视的事实:LLM 按 token 计费、按 token 算上下文窗口。输入多少 token 收多少钱、占多少额度,输出同理(通常更贵)。所以 token 是 LLM 时代的"货币单位"——你写的每一行 prompt,都是在花钱。
二、Tokenizer 原理:BPE 是怎么切词的
主流 LLM 用的是 BPE(Byte Pair Encoding,字节对编码)。它不是按规则切,而是从数据里学出来的:
- 初始词表是 256 个字节,文本先拆成字节序列。
- 统计语料里最常相邻的字节对,合并成一个新 token,加入词表。
- 重复上一步,直到词表达到设定大小(几万到几十万)。
结果就是:越常见的片段,越可能成为一个独立 token。"the"、"tion"、"http" 这种高频串被合成单 token,而罕见组合继续以小片段存在。这也是为什么英文常用词只占 1 token、生僻词却要几个。
但——每个模型的 tokenizer 不一样,token 不能跨模型换算:
| 模型 | 典型编码 |
|---|---|
| GPT-3 / GPT-3.5 | p50k_base |
| GPT-4 / GPT-3.5-turbo | cl100k_base |
| GPT-4o / GPT-4o-mini | o200k_base |
| Claude 系列 | Anthropic 自家 tokenizer |
| Llama / Mistral | 多为 SentencePiece |
同一段中文,在 cl100k_base 里可能是 100 token,换 o200k_base 就可能只有 70。"我这条 prompt 多少 token" 没有唯一答案,必须绑定具体模型。
三、语言效率差异:中文为什么天然更贵
BPE 是按语料频率学合并的,而主流模型的训练语料英文占绝对大头。这就造成一个对中文应用很不友好的事实:同样的意思,中文花的 token 比英文多。
经验数字(cl100k_base 量级):
- 英文:常见词大多 1 token,整体约 1 个词 ≈ 1.3 token(即 1000 个英文词 ≈ 1300 token)。
- 中文:一个汉字常常 1~2 token,高频字(你、好、的、是)多 1 token,但很多中文字要 2 个甚至更多 token。等价的中文表达,token 数往往是英文的 1.5~2 倍。
- 代码:空白和缩进都在烧 token。每一级缩进、每个换行、每个括号都算。一段格式工整的代码,结构符号和缩进能占掉可观比例。
这不是模型"歧视"中文,而是 BPE 的语料分布决定的:英文词组合并得充分,中文字组合并不充分。做中文 AI 产品,等于同样预算上下文窗口更短、同样长度 prompt 更贵——这是产品定价和设计时必须认账的前提。
一个值得记住的演进:o200k_base(GPT-4o)专门优化了多语言,中文效率比 cl100k_base 提升明显(同段中文 token 数降 30% 左右)。选模型不只是选能力,也在选 token 效率。
四、实测:用 tiktoken 算一算
别靠感觉,拿工具量。OpenAI 开源的 tiktoken 能离线精确数 token(纯本地计算,不调 API、不花钱)。TS 生态有同名的 WASM 移植包:
import { encoding_for_model } from "tiktoken";
const enc = encoding_for_model("gpt-4o"); // 对应 o200k_base
const count = (text: string) => enc.encode(text).length;
// 顺带看看它怎么切的
const ids = enc.encode("tiktoken is great");
console.log(ids); // [82, 427, 2301, 374, 2294] —— "tik" "token" " is" " great" 之类
console.log(ids.length); // 5
enc.free(); // 用完释放 WASM 内存,长生命周期进程务必记得调
跑一组实测(o200k_base):
| 文本 | 字符数 | token 数 | 说明 |
|---|---|---|---|
"Hello, world!" | 13 | 4 | 英文标点合并,极省 |
"The quick brown fox jumps over the lazy dog." | 44 | 10 | 约一词一 token |
"你好,世界!" | 6 | 5 | 中文一字≈一 token,标点也算 |
"快速的棕色狐狸跳过了那只懒狗。" | 14 | 13 | 等价英文 pangram,token 略多 |
| 一段 7 行格式化 JS 函数 | ~90 | ~45 | 缩进/括号/换行占近一半 |
两张表里最该盯着看的是:代码那行,字符数和 token 数接近 2:1。你以为是"几行小函数",tokenizer 看到的是满屏缩进和符号。给模型喂整份源码做上下文时,这个比例会直接吃掉你的窗口预算。
五、为什么这直接影响成本和效果
token 数不只是钱的事,还连着三件事:
- 输入长 = 贵。输入按 token 收费,长 prompt 直接放大每次调用成本。
- 输入长 = 慢。首 token 延迟(TTFT)和输入长度正相关,prompt 越长用户等越久。
- 输出更贵。输出 token 单价通常是输入的 3~5 倍,模型"唠叨"比"读题"贵得多。
对中文应用,这三条会被效率劣势放大:同样的功能,中文 prompt 天然比英文版贵一截、慢一截。这也是为什么"压 prompt"在中文场景 ROI 尤其高——压缩的是被 BPE 放大的那部分成本。
六、控成本实操:五个能立刻见效的杠杆
理解了 token,优化才有方向:
- 精简 prompt,砍废话。把"你是一个乐于助人的、知识渊博的、擅长……"这种水词删掉,只留可执行规则。system prompt 是每次调用都付钱的固定税基,值得反复榨。
- few-shot 控量。3 个精选示例往往够,别堆 20 个。每个示例都是输入 token,且会稀释模型注意力。
- 选高效表达。内部数据处理、日志分析这类不需要"人味"的场景,用英文写 prompt 更省;结构化数据用 JSON / 表格,别用自然语言描述。
- 开 prompt cache。稳定的 system prompt + 长文档前缀命中缓存,输入成本可降到 1/10(Anthropic)或对折(OpenAI)。法则是稳定的放前面,易变的放后面。
- tokenizer 感知的截断。裁上下文要按 token,不是按字符——否则中文截在 token 中间会产生乱码片段,既浪费又可能触发模型异常输出。
七、工程注意:别按字符估算 token
最后这条是工程上的硬纪律:任何涉及 token 上限的逻辑,都必须用 tokenizer 精确算,不能按字符数估。
- "我按 8000 字符截断" 是错的。同样 8000 字符,英文可能 2000 token、中文可能 6000+,差出两三倍,要么提前浪费窗口、要么直接超限报错。
- 字符截断还会切在 token 中间,产生不完整片段。正确做法是用 tokenizer 数到预算内,并解码还原到合法 token 边界。
- tiktoken 是纯本地、毫秒级、零成本的。在写入上下文、投递 prompt 前先
encode一遍数清楚,既防超限又能精准计费。
把"按字符"的直觉换成"按 token",是 LLM 工程化最基本也最值得的一次心智升级。
小结
- token 是子词单元,不是字符也不是词,它既是计费单位也是上下文货币。
- BPE 按频率学切词,语料以英文为主,导致中文 token 效率天然偏低(等价内容贵 1.5~2 倍)。
- 各模型 tokenizer 不同,token 数不能跨模型换算,优化要绑定具体编码。
- 代码 token 近乎字符数的一半是结构符号和缩进,喂源码做上下文时务必警惕。
- 凡是 token 上限,一律用 tokenizer 精确算,按字符估算就是裸奔。
金句:按字符估 token,等于用尺子称重量——单位都错了,再精细的优化都是徒劳。真正控住成本的人,从搞懂一个 token 有多大开始。
Related