准备把一批中文资料交给大模型时,很多人会先看字数,五万字大概占多少上下文,整份合同会不会超限,一次摘要要花多少钱,这些问题最后都要落到 Token 上。汉字数只能给个粗略印象,模型收到文字以后还要经过分词器,同一段内容换一个模型,结果可能随编码方式一起变化。
我把 OpenAI、Gemini 和 Claude 当前的计数说明对了一遍。它们都提供了按目标模型计算 Token 的办法,也都提醒开发者把真实请求算进去。只把正文复制到网页小工具里数一下,常会漏掉系统提示词、消息角色、工具说明和文件等内容。
分词器先把文字变成编号
模型处理的是一串 Token 编号。一个 Token 可能对应单个字符、一个完整单词,也可能只是长词的一部分,空格、大小写和标点也会参与拆分。分词器使用的词表与规则不同,同样一句话在两个模型里得到的编号和数量就可能不同。差几个 Token 很常见,也值得记录。
OpenAI 开源的 tiktoken 使用 BPE 分词,并提供 encoding_for_model,让程序按目标模型选择编码。Gemini 文档把 tokenization 定义为把输入拆成 Token 的过程,还说明图片等非文本输入也要计数。这里容易漏掉一件事,模型看到的输入范围往往比聊天框里的正文更大。工具的参数 schema、历史消息和附件都会占位置。
中文也不适合直接套英文里的经验比例。Gemini 给出的每个 Token 大约四个字符,是面向其模型的粗略说明,官方同时把计数接口留给了开发者。做中文长文、代码或中英混排时,按实际模型计算更稳。模型升级以后也要重算,旧编码测出的数字不能长期当预算依据。
预算要以完整请求为准
上线前可以准备十条真实请求,包含系统规则、工具定义和常见附件,再用目标模型的计数接口逐条计算。Claude 的计数接口能在不生成回答的情况下处理消息、工具、图片和文档。Gemini 的 count_tokens 也能先算输入,真正生成后再从响应元数据读取实际用量。
预估值和最终用量要分开保存。前者负责在发送前拦住超长请求,响应里的实际输入、输出和缓存 Token 用来核账。流式请求还要确认客户端拿到了最后的用量记录,连接中途断开时,屏幕上少几个字并不代表服务没有处理前面的内容。
我更愿意把字符数当成编辑阶段的提示,把分词器计数当成运行阶段的尺子。每次换模型、增加工具或扩大历史消息,都抽样重算一次。这样上下文是否放得下、费用为何变化,能从请求记录里找到答案。