前端接入 LLM 必学:彻底搞懂 Token 是什么
很多人第一次接触大模型时,都会听到一句高频术语:
这个模型支持 128K token 上下文或者:
这段提示词太长,超出 token 限制了于是很多人会自然地把 token 理解成:
一个词
一个字
一个字符
这三种理解都不准确。
如果只用一句话先给结论,我会这样说:
Token 不是“人类自然语言里的词”,而是模型为了计算而使用的最小离散文本单元。
它是大模型理解文本、记忆上下文、计算成本、生成答案的基础砖块。
如果不理解 token,你就很难真正理解这些问题:
为什么同样一句话,中英文 token 数差很多
为什么代码和自然语言的 token 成本差异明显
为什么提示词一长,性能和费用都会出问题
为什么模型不是“按句子思考”,而是“按 token 预测”
这篇文章会从第一性原理出发,循序渐进讲清楚:
token 到底是什么
为什么 LLM 必须把文本切成 token
tokenizer 是怎么工作的
token 如何进入 Transformer
模型为什么是“一个 token 一个 token”生成答案
token 与上下文窗口、成本、延迟之间是什么关系
一、先从第一性原理问起:模型为什么不能直接看文字
人类看一段文字时,会直接把它理解成语义。
例如看到:
北京今天天气不错我们会立刻理解:
“北京”是地点
“今天”是时间
“天气不错”是在表达状态
但对计算机来说,原始文本首先只是符号序列。
如果再往底层看,它甚至只是:
Unicode 字符
或者字节序列
而神经网络能处理的,不是“文字本身”,而是数值。
所以,从第一性原理看,大模型必须先完成三步:
把文本切分成稳定的离散单位
给每个离散单位分配一个整数 ID
再把整数 ID 映射成向量,送入神经网络
这里的“稳定离散单位”,就是 token。
换句话说:
Token 的本质,是“文本进入神经网络之前的离散化接口”。
二、Token 到底是什么
最通俗地说,token 可以理解为:
模型词表里的一个条目。
这个条目可能是:
一个完整单词
一个单词片段
一个汉字
一段标点
一个空格加单词前缀
一个代码符号
甚至是半个不常见词
这也是为什么 token 既不等于“词”,也不等于“字符”。
例如同样是英语:
apple有些 tokenizer 可能直接把它切成一个 token。
但如果是一个很罕见的词:
unbelievability它可能会被切成多个子词片段,例如类似:
un + believ + ability再比如中文:
人工智能它有可能被切成:
一个整体 token
两个 token
四个单字 token
这取决于具体 tokenizer 的词表和训练策略。
所以更精确的定义应该是:
Token 是 tokenizer 按照既定词表和切分规则,把原始文本映射出来的离散片段。
三、为什么不直接按字符切,或者直接按单词切
这是理解 token 的关键一步。
1. 只按字符切,序列会太长
如果完全按字符切分,问题是序列会变得非常长。
例如一句英文:
Large language models are useful.按字符切,会得到几十个单位。
序列越长,Transformer 计算成本越高,因为注意力机制的复杂度会随序列长度快速增长。
2. 只按单词切,词表会爆炸
如果完全按单词切,又会遇到另一个问题:
词形变化太多
新词太多
拼写错误太多
代码、URL、文件路径、变量名变化无限多
你不可能把所有可能出现的“词”都提前放进词表。
3. 子词切分是折中方案
所以业界最后走向了一个非常工程化、也非常优雅的折中:
用“子词”而不是“字符”或“完整单词”作为主要单位。
这样做有几个明显好处:
常见词可以保留为单个 token,提高效率
生僻词可以拆成多个片段,避免 OOV 问题
词表规模可控
适配自然语言、代码、标点、路径、数字等混合文本
这正是现代 tokenizer 的核心思想。
四、Tokenizer 是做什么的
tokenizer可以理解为一个“文本切分与编码器”。
它做两件核心事情:
把文本切成 token
把 token 映射成整数 ID
例如:
"Hello, world!"经过 tokenizer 后,可能变成:
["Hello", ",", " world", "!"]再进一步变成:
[15496, 11, 995, 0]这里的数字就是 token ID。
模型真正看到的,不是原始字符串,而是这一串 ID。
整个过程可以抽象成这样:
flowchart LR A[原始文本] --> B[Tokenizer 切分] B --> C[Token 序列] C --> D[Token ID 序列] D --> E[Embedding 向量] E --> F[Transformer]五、Tokenizer 通常怎么切分
不同模型使用的 tokenizer 不完全一样,但主流思路大体相近,常见算法包括:
BPE
WordPiece
Unigram
byte-level BPE
对大多数工程实践来说,不必死记算法细节,但要理解它们共同遵循的核心原则:
从大量语料中学习“哪些片段最常出现”,把高频片段保留为更大的 token,把低频内容拆成更小片段。
1. 一个直观例子
假设训练语料里经常出现这些片段:
theingtionhttp.comdefreturn
那么 tokenizer 往往会优先把这些高频片段收进词表。
结果就是:
高频模式可以被压成更少 token
低频模式仍然可以通过更小片段拼出来
2. 为什么空格经常也算 token 结构的一部分
很多 tokenizer 不是简单“按空格分词”,而是会把空格也编码进 token 里。
例如它不一定存:
world
而可能存:
world
这样做有一个好处:
模型可以更自然地区分“词首出现”和“词中出现”的模式。
这也是为什么同一个单词在句首和句中,token 切分可能不同。
六、为什么同一句话,不同模型的 token 数不一样
这是一个常见误区。
很多人以为 token 数是文本的客观属性,其实不是。
更准确地说:
Token 数是“文本 + tokenizer”的共同产物。
不同模型使用不同 tokenizer,所以同一段文字在不同模型里,token 数可能不同。
影响 token 数的因素包括:
tokenizer 词表大小
是否采用 byte-level 切分
是否更偏向英文语料
是否针对代码优化
是否对中文常见片段做了更好的合并
所以不要把这些说法理解得太死:
1 token ≈ 4 个字符 1 个汉字 = 1 个 token 1 个英文单词 = 1 个 token它们只能算非常粗糙的经验值,不能当精确规则。
七、中文、英文、代码,为什么 token 表现差异这么大
这背后其实是“可压缩性”的差异。
1. 英文
英文里高频词、前后缀、空格模式很稳定,所以 tokenizer 比较容易学到高频片段。
很多常见英文词会直接变成一个 token,或者少数几个 token。
2. 中文
中文没有天然空格分词,而且词边界本身就比英文更模糊。
所以 tokenizer 在中文上常常更依赖:
单字
双字词
常见短语
这导致中文 token 分布往往和英文很不一样。
3. 代码
代码是 token 世界里非常特殊的一类文本:
标识符很长
符号非常多
空格和缩进有意义
路径、变量名、JSON、日志格式层出不穷
所以代码类内容往往会产生大量 token,尤其在:
长变量名
路径
stack trace
minified JSON
base64
这些场景中尤为明显。
这也是为什么很多 coding agent 系统会非常重视 token 管理。
八、Token 进入模型之后发生了什么
到这里为止,token 还是离散 ID。神经网络并不直接处理整数 ID,而是先把它们映射成向量。
这个过程叫 embedding。
1. Token ID 先变成 embedding 向量
例如:
[15496, 11, 995, 0]会被映射成:
[v1, v2, v3, v4]每个v都是一个高维向量。
这些向量不是手工定义的,而是在训练中学出来的。
直观理解上,你可以把 embedding 看成:
模型内部对 token 的数值表示。
2. 再叠加位置信息
仅有 token 向量还不够,因为:
dog bites man man bites dogtoken 集合一样,但顺序不同,含义完全不同。
所以模型还必须知道每个 token 在序列中的位置。
这就是 position encoding / positional information 的意义。
3. 然后进入 Transformer
有了:
token embedding
position information
之后,整段序列才真正进入 Transformer 层进行计算。
九、LLM 不是“按句子回答”,而是“按 token 预测”
这是理解生成式模型最重要的一步。
从训练目标看,LLM 干的事情非常朴素:
给定前面的 token,预测下一个最可能出现的 token。
例如输入:
The capital of France is模型不会一次性“想出一句完整答案”,而是先预测下一个 token,可能是:
Paris然后再把这个新 token 接回上下文,再继续预测下一个 token:
.然后再继续。
整个生成过程本质上是一个循环:
flowchart TD A[已有上下文 token] --> B[Transformer 前向计算] B --> C[输出下一个 token 的概率分布] C --> D[采样或选择一个 token] D --> E[把新 token 追加回上下文] E --> F{是否结束} F -- 否 --> B F -- 是 --> G[生成完成]这意味着一个非常关键的事实:
模型输出不是整段文字一次性喷出来的,而是一步一步自回归生成出来的。
十、为什么说 token 是“模型思维的步长”
虽然严格来说,大模型并不是像人一样“思考”,但从工程视角,你可以把 token 理解成它运行时的最小推进步长。
因为模型的每一步生成,都是:
看当前全部上下文 token
预测下一个 token
把这个 token 接回去
继续下一步
所以:
输出越长,需要生成的 token 越多
token 越多,延迟越高
token 越多,成本越高
这也是为什么同样一个问题:
简短回答更快更便宜
长篇解释更慢更贵
本质上不是因为“句子更复杂”,而是因为要走更多次 token 预测循环。
十一、上下文窗口为什么用 token 来衡量
当你听到:
32K context 128K context 1M context这里的单位不是字符,也不是单词,而是 token。
原因很简单:
模型内部真正处理的是 token 序列,而不是原始字符串。
1. 上下文窗口的本质
上下文窗口可以理解为:
模型这一次前向计算中,最多能同时“看到”的 token 数量。
这个数量里通常包括:
system prompt
历史对话
工具描述
工具结果
当前用户输入
模型已经生成的输出
所以当你把 prompt 写得很长时,你不是只在“多写了一点文字”,而是在消耗上下文预算。
2. 为什么上下文越长,系统越难做
因为 token 变多,不只意味着“能放更多文字”,还意味着:
注意力计算更重
延迟更高
显存占用更大
成本更高
噪声更多
所以大上下文不是免费午餐。
十二、Token 与成本的关系为什么这么直接
几乎所有商业 LLM API 都按 token 计费。
这不是厂商随便选的单位,而是因为 token 最接近模型真实的计算负载。
直观上:
输入 token 越多,模型要读的上下文越长
输出 token 越多,模型要执行的生成步数越多
于是计费模型通常会区分:
input tokens
output tokens
某些 provider 还会区分 cache read / cache write
从基础设施角度看,token 就像云计算里的:
CPU 时间片
存储字节数
网络流量
它是 LLM 世界里最基础的资源计量单位之一。
十三、为什么“同样长度的内容”,不一定有相同 token 成本
这里有几个常见坑。
1. 乱码、路径、日志、JSON 往往更贵
像这些内容:
stack trace
UUID
base64
minified JSON
文件路径
SQL
长变量名
虽然肉眼看着只是“一段文本”,但对 tokenizer 来说往往很难压缩,所以 token 数会膨胀。
2. 工具 schema 也会吃掉很多 token
在 agent 系统里,用户常常只关注聊天内容,但真正的大头经常来自:
tool 定义
JSON schema
系统提示词
历史工具结果
这些内容都要进入上下文,都会消耗 token。
3. 重复历史会线性累积
如果你的系统每一轮都把整段历史完整回放,token 成本会很快堆高。
所以真正的工程系统往往会做:
截断
摘要
压缩
检索式拼接
缓存
本质上,都是在管理 token 预算。
十四、Token 和“理解能力”是什么关系
很多人会把 token 数和“智力”混为一谈,这也是一个常见误区。
更准确地说:
token 是输入输出与计算的基本单位
智力表现则取决于模型参数、训练数据、架构、训练目标、对齐方式等
一个模型支持更长上下文,不代表它一定更聪明。
它只表示:
它能在一次计算中处理更多 token。
这和“会不会推理”“会不会规划”“会不会写代码”是相关但不同的问题。
十五、从工程角度,怎么正确管理 token
如果你在做 LLM 系统,真正重要的不是“背定义”,而是建立 token 视角。
1. 把 token 当预算,不要当抽象名词
每次请求其实都在消耗预算:
输入预算
输出预算
历史预算
工具预算
2. 优先优化高噪声内容
最该压缩的通常不是用户那一句话,而是:
冗长系统提示
过大的工具 schema
无用历史消息
原样粘贴的大日志和大 JSON
3. 区分“保留信息”和“保留原文”
很多时候模型不需要原始全文,只需要:
结构化摘要
关键字段
结论
关联引用
从 token 视角看,摘要和压缩往往是系统质量的重要来源。
4. 为不同内容类型选对模型和策略
例如:
长文分析需要关注上下文预算
代码 agent 要特别关注路径、diff、schema 的 token 开销
多轮对话要优先考虑记忆压缩
真正成熟的 LLM 系统,底层一定有 token 管理意识。
十六、几个最容易混淆的误区
误区 1:token 就是单词
不对。它可能是单词、子词、标点、空格前缀、字节片段。
误区 2:token 就是字符
也不对。字符只是原始文本单位,token 是 tokenizer 学出来的计算单位。
误区 3:所有模型的 token 计数一致
不对。不同模型有不同 tokenizer。
误区 4:上下文窗口越大,模型越聪明
不对。上下文窗口表示容量,不直接表示推理质量。
误区 5:只有用户输入才消耗 token
不对。system prompt、历史消息、工具 schema、工具结果、模型输出都消耗 token。
十七、把整件事串起来
如果把 token 在 LLM 里的角色压缩成一条完整链路,可以这么理解:
flowchart TD A[人类文本] --> B[Tokenizer] B --> C[Token 序列] C --> D[Token ID] D --> E[Embedding] E --> F[Transformer 读取全部上下文] F --> G[预测下一个 token 概率] G --> H[选择一个 token] H --> I[追加回上下文] I --> J[重复直到结束]所以,token 在整个系统里的角色同时有三层:
它是文本离散化后的表示单位
它是模型计算和生成的基本步长
它是上下文、成本、延迟的核心计量单位
十八、最后一句话总结
如果只留下一句最重要的话,我会这样总结:
Token 不是面向人类语义设计的“词”,而是面向神经网络计算设计的“文本原子”。
理解了 token,你就会真正看清大模型的很多底层现实:
模型不是直接理解字符串,而是处理 token 序列
模型不是整句输出,而是逐 token 自回归生成
上下文窗口本质上是 token 容量
成本、延迟、记忆管理,本质上都是 token 管理问题
也正因为如此,在 LLM 系统设计里,token 从来不是边角概念。
它是基础设施层最重要的单位之一。
