Token Counting

Token 计数 vs 字符计数:为什么差异很重要

字符数很容易测量。Token 数才是 LLM 在上下文限制、用量报告以及通常的计费中实际使用的指标。把两者视为可以互换,可能会让提示预算看起来安全,实际上并不安全——或者让你删掉本来完全可以放下的有用上下文。

实用规则很简单:写作和界面限制使用字符数;进行 LLM 规划时使用模型特定的 token 数。 每 token 字符数的比例可以帮助做粗略估算,但它不能替代使用目标模型所对应的分词器或 API 对完整请求进行计数。

本指南解释为什么 token 数与字符数会出现偏差、这种差异在何时重要,以及如何通过可直接粘贴的示例在 TokenTest 中测试其影响。

一张表看懂 token 数与字符数

度量 统计内容 最佳用途 主要限制
字符 可见文本中的 Unicode 字符或码位 编辑器限制、UI 校验、存储量估算 不能反映分词器词表或请求结构
字节 编码后的数据大小,通常是 UTF-8 字节 传输、存储、负载限制 多字节字符仍无法与 token 形成可预测映射
Tokens 模型分词器用于输入和输出的单位 上下文规划、用量检查、成本预测 取决于模型、分词器以及完整请求格式
人类可读的词边界 编辑长度和可读性 对代码、标点、中文、表情符号以及分词器行为的适用性较弱

一个 token 可能是一个完整的短词、较长词的一部分、标点、附着在词上的空白、代码片段,或非拉丁字符序列的一部分。这就是为什么不存在适用于所有输入的固定字符到 token 转换——也正因如此,token 数与字符数的比较必须使用真实示例。

一个 token 有多少个字符?

对于英文散文,每个 token 约四个字符是一个有用的初步经验法则。OpenAI 将其描述为经验性规则,而不是保证。Google 的 Gemini 文档给出了类似的英文估算,并明确指出对于非拉丁脚本,这个比例会更低。

这个注意事项很重要。该比例会随着以下因素变化:

如果将 10,000 个英文字符除以 4,结果——大约 2,500 个 token——只是一个规划估算,而不是实际计数。它对于早期电子表格来说也许足够好,但对于生产环境的上下文限制、每次请求的成本上限或回归测试来说远远不够。这正是 token 数与字符数 会改变工程决策的第一个地方。

为什么相同的字符数会产生不同的 token 数

分词器是围绕可复用的文本模式设计的,而不是围绕等长的字符块。常见模式可以压缩成更少的 token,而不常见的混合内容则会被更细粒度地拆分。

以下以 OpenAI 的 o200k_base 编码作为一个示意性的本地估算,这两个 ASCII 字符串的字符数几乎相同:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aB7!qZ9@kL2#mN4$pR6%tV8&wX0*yC1

第一个有 32 个字符,在这个示例中编码为 4 个 token。第二个有 31 个字符,编码为 27 个 token。字符数几乎没有变化;token 数量却发生了巨大变化。

这并不是对每个模型的承诺。它展示了字符限制对 LLM 预算不可靠的核心原因:分词器词表会高效识别某些序列,而将另一些序列拆成许多片段。token 计数 vs 字符计数之间的差距由模式驱动,而不仅仅由长度决定。

导致字符到 token 估算失真的四个因素

1. 语言和书写系统

英语单词通常会匹配分词器词表中的常见模式。中文不会在每个词之间使用空格,而且其字符使用多个 UTF-8 字节。更新的多语言分词器可以比旧分词器更高效地表示中文,但具体比例仍取决于所用模型。

试试这个语义对应的示例:

Summarize this customer review in three bullet points.
请用三个要点总结这条客户评价。

在同一个示意性的 o200k_base 测试中,英文行有 54 个字符和 11 个 token;中文行有 15 个字符,也有 11 个 token。字符数会让人觉得中文提示短得多,但 token 预算并没有变少。

如果是专门的多语言工作流,请参见为什么中文提示词可能使用与英文提示词不同的 token 预算

2. 空白字符和请求格式

空白字符并不总是免费。换行、缩进、分隔符以及标点周围的空格都可能改变分词结果。在结构化提示中,即使格式本身没有带来新的业务信息,token 计数 vs 字符计数的差距也可能扩大。比较以下两个 JSON 负载:

{"task":"summarize","limit":3,"language":"en"}
{
  "task": "summarize",
  "limit": 3,
  "language": "en"
}

在这个示意性的本地测试中,紧凑形式有 46 个字符和 15 个 token。格式化后的形式有 59 个字符和 25 个 token。漂亮的格式能提升可读性,但如果在大型工具 schema 或示例中反复出现,就会消耗相当可观的上下文。

不要盲目地压缩每一个提示词。更好的做法是衡量格式是否具有实际意义,并保留人类维护系统所需的结构。

3. 代码、标识符和看起来像随机的文本

源代码混合了关键字、缩进、运算符、路径、哈希值、UUID 和标识符。常见的语言语法可能会被高效地分词;而随机字符串、压缩后的代码、编码数据或很长的标识符则未必如此。

这就是为什么 20,000 个字符的堆栈跟踪和 20,000 个字符的产品文章不应共用一个 token 估算。如果你的应用会发送 diff、日志或文件,请使用组件级预算。我们关于代码提示的 token 计数指南展示了如何区分指令、源文件、补丁、日志和错误输出。

4. 表情符号和 Unicode 细节

两个字符串看起来同样简短,但使用的字节数和 token 数可能不同:

Launch status: ready OK
Launch status: ready ✅🚀

按基本字符计数,两行都包含 23 个字符。在这个示例性的本地测试中,纯文本行使用 5 个 token,而表情符号行使用 7 个 token。有些可见符号由多个 Unicode 码点组成,因此即使是“字符计数”,也可能因编程语言或计数方法而异。

字符计数器看不到的隐藏 token

可见的提示文本可能只是请求的一部分。生产环境调用还可能包含:

OpenAI 的输入 token 计数端点接受与 Responses API 相同的请求输入格式,并包含请求格式化开销。Anthropic 提供了一个 token 计数端点用于 Messages 输入,并指出其估算结果可能与最终用量略有不同。Gemini 提供 countTokens,并且也会在生成后返回 token 用量。

重要的教训不是某个提供商计数“更好”。而是每个提供商都提供了与模型感知相关的计数,因为通用字符计数器看不到整个请求。 因此,任何严肃的 token 计数 vs 字符计数 测试都应从完整的模型输入开始。

为什么这种差异在生产环境中很重要

上下文窗口安全性

请求必须为输入和输出都留出空间。如果你的限制检查使用字符数,那么一个不利于 tokenizer 的输入即使 UI 显示低于文本限制,也可能超出可用上下文。

使用这个预算模型:

可用输入预算
= 模型上下文容量
- 预留输出 token
- 安全边际
- 已知请求开销

然后将特定模型的输入 token 计数——而不是字符计数——与可用输入预算进行比较。更多细节请阅读上下文窗口规划开发者指南

成本预测

LLM 使用通常按输入和输出 token 进行衡量。基于字符的预测会错误估计多语言流量、重代码工作负载以及工具调用请求的成本。即使粗略的英文比例在月度平均值上可行,它也可能掩盖昂贵的请求片段。按工作负载测量 token 计数 vs 字符计数 可以让这些片段变得可见。

按工作负载类型进行预测:英文支持、中文支持、代码审查、检索、工具调用以及长对话。记录提供商实际报告的使用量,并根据生产数据更新假设。

提示词回归测试

一个小小的文案修改就可能增加一个大型 schema、重复示例或检索字段。字符数可能会捕捉到整体增长,但不一定能捕捉到特定分词器的增长。为具有代表性的请求保存 token 预算固定样本,并在提示词、工具、模型或检索模板发生变化时重新运行这些样本。

多语言产品限制

单一字符限制对文本框来说是公平的,但对于不同语言而言,它不一定是公平的 token 预算。如果业务规则基于 LLM 容量或成本,请针对每种受支持语言验证具有代表性的输入,而不是假设一个全球统一比例。

实用的计数工作流程

  1. 在写作界面使用字符数。 当这样做能提升可用性时,向用户显示清晰的文本限制。
  2. 构建完整的模型请求。 包括指令、历史记录、检索、工具 schema 和媒体输入。
  3. 使用目标提供商和模型进行计数。 如有可用,使用官方 token 计数端点或匹配的分词器。
  4. 预留输出和安全余量。 不要用输入填满整个上下文窗口。
  5. 运行请求并记录实际使用量。 将预检估算与提供商返回的输入、输出、缓存和总 token 进行比较。
  6. 按工作负载和语言分段。 跟踪分布,而不是单一的全局平均值。
  7. 在变更后重新计数。 模型、分词器、提示词、工具或格式变化都可能使旧比例失效。

将这些示例粘贴到 TokenTest 中

TokenTest 旨在评估在线模型端点,并检查 token 使用情况是否可信。使用下面的配对创建测试用例,在你实际计划使用的模型端点上运行它们,并比较报告的输入 token,而不是假设本地示意性的计数会完全一致。

测试 可直接粘贴的输入 要检查什么
相似字符,不同模式 上面重复的 a 字符串 vs 混合字母、数字和标点 尽管字符长度相似,输入用量是否会明显变化?
英文 vs 中文 上面的双语摘要配对 模型特定的 token 比率是否与字符比率不同?
紧凑 vs 格式化 JSON 上面的两个 JSON 示例 缩进会增加多少 token 开销?
纯文本 vs 表情符号 上面的两行发布状态文本 Unicode 符号是否会意外增加 token 或字节?

TokenTest 还可以帮助验证输入/输出/总用量的一致性,并运行重复的端点测试。它不能替代提供商的分词器定义;它提供的是你准备上线的端点和响应中的实时证据。

token 计数 vs 字符计数:最终规则

字符计数回答的是:“有多少文本是可见的?”Token 计数回答的是:“这次请求消耗了多少模型容量?”这两种度量彼此相关,但这种关系会随着分词器、语言、格式、内容和请求结构而变化。

只有在粗略的英文规划中,才使用“每个 token 约等于四个字符”的经验法则。对于成本控制、上下文限制、多语言预算和生产环境检查,请统计所选模型的完整请求——然后在 TokenTest 中确认端点的真实用量。

常见问题

一个 token 总是等于四个字符吗?

不是。每个 token 对应四个英文字符只是一个粗略经验法则,并不是固定换算。代码、中文、标点、表情符号、非常规字符串以及不同的分词器都可能产生差异很大的比例。

我可以把字符数换算成 token 数吗?

你可以先用英文字符数除以四,作为早期估算。在执行限制或预测支出之前,请使用目标模型的官方 token 计数方法重新统计完整请求。

空格也算作 token 吗?

空格和换行会影响分词,但一个空格并不一定等于一个 token。分词器通常会把空白字符与相邻文本合并,因此影响取决于具体序列。

中文提示词比英文提示词更占 token 吗?

有时是,但并不总是。结果取决于措辞、含义、分词器和模型。请用你计划使用的确切模型,对语义等价的样本进行比较。

为什么 API 的 token 用量会超过我本地的文本计数?

API 可能会统计消息格式、角色、工具 schema、检索到的上下文、媒体、缓存内容,或普通字符串计数器未包含的、不可见的生成 token。

我应该使用哪种 token 计数器?

优先使用与目标模型相关联的官方计数端点或分词器。使用实时请求评估来确认返回的 usage 字段在内部是一致的。

来源