粘贴前先算Token:LLM Token数学实用指南

Token是模型处理文本的基本单位,理解其计数、估算与成本机制可避免上下文超限和账单失控。
文章从长文档粘贴进大模型时的三类常见故障切入,指出它们都源于Token这一基本单位。分词器按固定词表把文本切块,英文常见词多为一个Token,罕见词、非拉丁文字、代码和URL的Token密度显著更高。文章给出英文散文的经验估算(1 Token≈4字符≈¾单词,100词≈130 Token),并演示了用js-tiktoken和Python tiktoken精确计数,以及通过Claude、Gemini的API计数端点获取数字。成本方面,输入与输出按每百万Token分别计价,聊天历史每轮重发、输出通常更贵,是两大易被忽视的开支来源。最后提供五种省Token策略和不写代码的浏览器计数工具。
把一份长文档粘贴进ChatGPT、Claude或Gemini时,常见三种翻车方式:回答忽略了结尾、触发了上下文上限、API账单比预期高出一截。这三个问题的根源指向同一个数字——Token。

Token到底是什么
模型不直接读字符或单词。分词器(Tokenizer)按固定词表把文本切成块,模型看到的只是一串块ID。
- 常见英文单词通常是一个Token:
the、house、token - 更长或更罕见的词会被拆分:
tokenization→token+ization - 空格和标点也算数,前导空格往往属于下一个Token
- 数字、代码、URL和非拉丁文字,每字符消耗的Token更多
最后一点最容易被低估。同一句话翻译成印地语、日语或阿拉伯语,Token数可能是英文版的两三倍;压缩过的JSON或一段堆栈跟踪,密度远高于普通散文。理解这个差异,是估算成本的第一步。
分词器(Tokenizer)和模型是两套独立的东西。分词器是文本与模型之间的"翻译层",它的词表在模型训练之前就已固定,训练完成后不会再变。这意味着同一个词在不同模型家族中可能被切成完全不同的块——GPT-4o用的o200k_base词表约20万条,能更高效地表示多语言文本,而老模型用的cl100k_base只有约10万条,遇到罕见词时切得更碎。分词算法本身通常是BPE(字节对编码)或其变体:从单个字符出发,反复合并出现频率最高的相邻组合,直到词表填满。这个过程的统计来源是训练语料,所以英文占主导的语料会让英文词切得更"整",其他语言的文本则被切得更"碎"——这正是非英文Token密度高的根本原因,而不是模型"不擅长"某种语言。
心算就够了:经验法则
对于英文散文和OpenAI当前的分词器:
- 1 Token ≈ 4个字符
- 1 Token ≈ ¾个单词,即100词 ≈ 130 Token
- 一页密集的A4文本 ≈ 600–800 Token
其他厂商也公布过自己的粗略比例,数值略有差异,因为每个模型家族的分词器不同。把这些当作估算值即可,涉及关键决策时还是得实际计数。
用代码精确计数
OpenAI的分词器是开源的。在JavaScript中,js-tiktoken可以在任何环境运行,包括浏览器:
import { Tiktoken } from "js-tiktoken/lite";
import o200k_base from "js-tiktoken/ranks/o200k_base";
const enc = new Tiktoken(o200k_base);
const text = "Count your tokens before you paste.";
console.log(enc.encode(text).length); // Token数量
o200k_base是GPT-4o及更新OpenAI模型使用的编码,较老的GPT-4和GPT-3.5则使用cl100k_base。Python里对应的是tiktoken包:
import tiktoken
enc = tiktoken.get_encoding("o200k_base")
print(len(enc.encode("Count your tokens before you paste.")))
Claude和Gemini的分词器没有公开,但两家API都提供了计数端点(Anthropic的count_tokens、Gemini的countTokens),需要在发送请求前拿到精确数字时可以用上。
需要注意encode返回的是Token ID数组,其长度即Token数量,但它并不等于模型实际处理的全部Token。多数API会在输入前后自动附加对话模板标记(如特殊的角色分隔符),这些"隐形成本"通常有几十个Token,短Prompt时可忽略,但在批量调用或极短请求中会累积成可观的偏差。此外,计数的结果依赖使用的词表:用cl100k_base去估算一个GPT-4o的请求,结果会系统性偏高。因此精确估价的正确做法是——先确认目标模型对应的编码名称,再计数,最后加上对话模板的固定开销。Claude和Gemini由于分词器未公开,只能依赖官方计数端点,本地无法复现其结果。
一个Prompt要花多少钱
所有API价目表都按每百万Token计价,输入和输出分开收费:
cost = input_tokens / 1,000,000 × input_price
+ output_tokens / 1,000,000 × output_price
用一个虚构的整数价格走一遍:假设输入每百万Token收费2美元,输出8美元。一个3,000 Token的Prompt加500 Token的回答,成本为:
3,000 / 1,000,000 × $2 = $0.006
500 / 1,000,000 × $8 = $0.004
total = $0.010 每次请求
一美分看起来微不足道,直到它每天运行50,000次。有两个常被忽略的点:
- 聊天历史每次都是输入。 长对话中每条新消息都会重发整个线程,输入Token随轮次不断增长。
- 输出通常是更贵的一侧。 要求"简短"回答或固定格式,往往比精简Prompt省得更多。
上下文窗口(Context Window)和计费是两件相关但不同的事。上下文窗口指一次请求中模型能"看到"的Token总数上限,包括系统提示、聊天历史、当前输入和即将生成的输出,各家模型从8K到200K不等。计费则按实际消耗的输入与输出Token分别计算。关键在于:聊天历史虽然可能早已"过时",但只要还在窗口内,每一轮都会作为输入重新计费。也就是说,一段20轮的对话,第20轮要为前19轮的全部内容付费。这也是为什么长会话的边际成本会随轮次上升,而非保持常数。当历史逼近窗口上限时,部分API会触发截断或报错,这就是开头提到的"忽略结尾"和"触发上限"两个翻车场景的共同机制。
不损质量的五种省Token方法
- 先剥离HTML和模板内容:粘贴网页前删掉导航、页脚和标签,这些纯属浪费。
- 压缩或裁剪JSON:只发送模型需要的字段,而不是整个API响应。
- 总结旧上下文:把长线程的前20条消息替换成五行摘要。
- 不要在每条消息里重复指令:放进系统提示词一次即可。
- 检查非英文和代码密集输入:这两类最容易让Token数超出预期。
不写代码的快速检查法
如果只想粘贴一段文本看看数量,作者提供了一个免费Token计数器,完全在浏览器内运行,粘贴的内容不会上传。它对OpenAI分词器给出精确计数,对Claude和Gemini标注为估算,并附带一个带日期、可编辑价格表的成本计算器。
你遇到过最大的Token意外是什么:超长的聊天历史、非英文文档,还是一个吃掉整个上下文窗口的JSON?
相关推荐

如何评估AI生成的研究摘要?三个关键维度
AI生成的研究摘要读起来流畅,但事实未必可靠。本文基于Reddit讨论,梳理评估AI研究摘要系统的三个核心维度:来源可追溯性、事实一致性与不确定性处理,并探讨其对深度学习从业者的实践意义。

Go工具Unspill:扫描AI编程助手历史记录中的凭证泄露
介绍Go语言CLI工具Unspill,可本地扫描Copilot CLI、Claude Code、Codex等AI编程助手的历史记录,检测泄露的API密钥和凭证,支持脱敏报告且无网络请求。

AI工具正在"入侵"复古游戏:一场创造力与版权的博弈
AI工具正在大幅降低复古游戏移植门槛,浏览器版《光环》、iPhone版《风之杖》等项目病毒式传播,但也引发版权争议与行业监管担忧。