Notes · 2026-06-20
什么是 Token?理解 AI API 计费的核心概念
什么是 Token?
在 AI 大模型的世界里,Token 是文本处理和计费的基本单位。你可以把它理解为模型"阅读"和"写作"时的最小单元。
模型内部不直接处理「字」或「单词」,而是先把文本切成 Token,再转成数字向量去计算。所以你看到的 API 账单、上下文长度限制、速度统计,背后都是 Token。
简单说:你发给 AI 的每一段文字,以及 AI 回复给你的每一段文字,都会被拆分成一个个 Token,而你最终的费用就取决于这些 Token 的总数。
一次 API 调用通常分开统计:
| 类型 | 是什么 | 谁产生 |
|---|---|---|
| 输入 Token | 你发过去的内容 | 系统提示词 + 历史对话 + 用户问题 + 检索到的文档等 |
| 输出 Token | 模型生成回来的内容 | AI 的回答 |
两者单价往往不同,输出一般更贵(见下文)。
Token ≠ 字 ≠ 词
Token 的切分方式取决于模型使用的分词器(Tokenizer)。不同语言、不同模型的分词规则有所不同:
| 语言 | 示例文本 | 大致 Token 数 |
|---|---|---|
| 英文 | "Hello, world!" | 4 |
| 中文 | "你好,世界!" | 5-7 |
| 代码 | console.log("hi") | 5-6 |
同一段中文,换用 GPT、Claude、DeepSeek,Token 数也可能略有差别——计费以该模型自己的分词结果为准。
经验法则
- 英文:1 个 Token ≈ 4 个字符,或约 0.75 个单词
- 中文:1 个汉字通常 = 1-2 个 Token
- 代码:因符号和关键字较多,Token 数通常比等长的自然语言更多
- 空格和标点:也会占 Token,不要当成「免费字符」
分词器在干什么(了解即可)
常见做法叫 BPE(字节对编码):从字符出发,把高频出现的片段合并成 Token。比如英文里 "ing"、"tion" 可能是一个 Token;中文里一个常见词组也可能被拆成 1~2 个 Token。
你不需要自己实现分词,但要知道:同样一句话,换模型可能 Token 数不同,估算成本时要按目标模型的分词器来算。
Token 如何影响费用?
AI API 的计费公式很简单:
总费用 = (输入 Token 数 × 输入单价) + (输出 Token 数 × 输出单价)
以 GPT-4o 为例(价格会调整,以官网为准):
| 项目 | 单价(每百万 Token) |
|---|---|
| 输入 | $2.50 |
| 输出 | $10.00 |
如果你发送了 1,000 个 Token 的提示词,AI 回复了 500 个 Token,那么这次调用的费用为:
(1000 / 1,000,000) × $2.50 + (500 / 1,000,000) × $10.00
= $0.0025 + $0.005
= $0.0075
一次不到 1 美分,看起来很少;但应用里如果每用户每天几十次调用、每次还带长文档,乘起来就可观了。
为什么输出比输入贵?
因为生成文本比读取文本需要更多的计算资源。模型在生成每一个输出 Token 时,都要在已有上下文上再跑一步推理;输入是一次性读入,输出是逐个「蹦」出来的。
可以粗理解为:输入是「看一遍」,输出是「写一遍,且写多少步算多少步」。
还有哪些会影响账单?
- 流式输出(stream):只是字一个个返回,总 Token 数不变,费用与不流式相同
- 失败重试:每次成功的 API 调用都计费;报错若已产生输出 Token 也可能计费,视提供商而定
- Batch 接口:部分平台批量任务有折扣,适合离线、不急的任务
- 图像 / 多模态:图片往往按「等价 Token 数」或单独规则计费,和纯文本不是一套单价
上下文窗口与 Token 的关系
每个模型都有一个上下文窗口(Context Window)限制,表示一次请求里,输入 + 输出合计能占用的最大 Token 数(具体定义各平台文档略有差异,以官方为准):
| 模型 | 上下文窗口 |
|---|---|
| GPT-4o | 128K |
| Claude Sonnet 4 | 200K |
| Gemini 2.5 Pro | 1M+ |
| DeepSeek-V3 | 128K |
128K 大约相当于一本中等篇幅的书;1M 则可以把更长的资料一次性塞进一次对话。
窗口满了会怎样?
- 超出部分会被截断或拒绝,取决于 API 和客户端实现
- 对话很长时,早期消息可能被丢弃,模型会「忘记」前面说过什么
- 窗口越大,能塞的背景越多,但输入 Token 越多、单次费用越高
上下文窗口越大,意味着你可以在一次对话中传入更多的背景信息,但同时也意味着更多的 Token 消耗和更高的费用。
和 RAG、长文档的关系
做知识库问答时,检索出来的文档片段也会算进输入 Token。所以:
- 不是「模型窗口大就随便塞」——塞越多,单次越贵、越慢
- 常见做法是控制
top_k、限制每段 chunk 长度、只传与问题相关的部分
如何估算和控制 Token 用量?
1. 使用 Tokenizer 工具
OpenAI 提供了在线 Tokenizer 工具,可以直观地看到文本被拆分成了多少个 Token。
代码里常用库(按模型选):
# OpenAI 系
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4o")
print(len(enc.encode("你好,世界!")))
# 通用方案(Hugging Face)
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("模型名")
print(len(tok.encode("你好,世界!")))
上线前用真实 prompt 样例跑一遍 Token 数,比凭感觉靠谱。
2. 精简提示词
去掉不必要的冗余描述,用结构化格式(如列表、表格)代替长段落。
同样意思,下面两种写法 Token 差很多:
❌ 冗长:我想请你扮演一个非常专业的、有丰富经验的编程助手,在我提问的时候……
✅ 精简:你是编程助手。根据用户问题给出可运行代码,缺信息先提问。
系统提示词(System Prompt)每次请求都会带上,写得越长,每次调用都多付一遍它的 Token。
3. 控制输出长度
在提示词中明确要求输出长度,如「请用 100 字以内回答」。
很多 API 还支持 max_tokens 参数,硬性限制模型最多生成多少 Token——防止它一口气写太长。
4. 利用上下文缓存
部分 API 提供商支持上下文缓存(Context Caching),对重复出现的长输入(常见是固定的系统提示词、长文档前缀)只收取缓存价格(通常为原价的 10%-25%)。
适合:同一个长 system prompt、同一份产品文档被反复问很多次的场景。
不适合:每次用户问题都不同、前缀几乎不重复的场景。
5. 对话历史别无限堆
多轮聊天时,历史消息会反复作为输入发回去。对话越长,输入 Token 线性涨。常见做法:
- 只保留最近 N 轮
- 对更早的内容做摘要再塞进上下文
- 重要事实写入数据库,需要时再检索,而不是永远挂在 history 里
6. 开发阶段先看统计再优化
LangSmith、各云平台控制台、OpenAI Usage 页面都会按请求显示 Token 用量。先找出最费 Token 的接口,再决定是缩 prompt、减检索、换小模型,还是加上缓存。
常见误解
| 误解 | 实际情况 |
|---|---|
| Token = 一个汉字 | 中文往往 1~2 个 Token 一个汉字,不是固定 1:1 |
| 流式更便宜 | 流式只影响体验,不影响总 Token |
| 窗口越大越划算 | 窗口是上限,用多少算多少;塞满更贵 |
| 只有用户问题算输入 | 系统提示、RAG 文档、工具返回结果都算输入 |
| 本地跑模型就没有 Token | 本地没有 API 账单,但上下文长度仍是按 Token 计的硬件限制 |
小结
- Token 是模型处理和 API 计费的单位,不是字也不是词
- 费用 = 输入 Token × 输入价 + 输出 Token × 输出价,输出通常更贵
- 上下文窗口 限制一次能处理多长,输入和输出共享这份额度
- 控费从可量化处下手:量 prompt、限输出、减历史、用缓存、RAG 别塞太满
搞懂 Token,后面看模型选型、RAG 切片、Agent 多轮调用,才有统一的「尺子」。