一、为什么 2026 年你必须关心 Token 经济学
2026 年 4 月 20 日,Anthropic 发布 Claude Opus 4.7,这是 Claude 系列首次更换 tokenizer。Simon Willison 第一时间实测发现:
- 纯文本场景:token 增长 1.46×
- 高分辨率图像(3456×2234):token 增长 3.01×
- 30 页 PDF 文档:token 增长 1.08×
在定价不变(输入 $5/百万 token,输出 $25/百万 token)的前提下,实际使用成本上升了约 40%。
这意味着什么?如果你的企业每月在 Claude API 上花费 $10,000,tokenizer 更换后同样的工作量需要 $14,600——每月多支出 $4,600。
Token 经济学不再是理论问题,而是直接影响项目预算的核心变量。
本文将从四个维度系统解析:
- Tokenizer 工作原理(BPE、WordPiece、SentencePiece)
- 2026 年主流模型 token 策略全景对比
- 用 Python 构建多模型 token 计数器
- 6 个实战级成本优化策略(含代码)
关键认知: Token 不是「字数」,而是模型「理解的语义单元」。同一个文本在不同模型的 tokenizer 下,token 数量可以差异 2-3 倍。理解这一点,是优化 LLM 成本的第一步。
二、Tokenizer 工作原理:从字符到语义单元
要理解 token 经济学,首先要理解 tokenizer 到底在做什么。
2.1 Tokenizer 的核心任务
Tokenizer 将人类可读的文本转换为模型可处理的整数序列。这个过程分为两步:
- 编码(Encoding):文本 → token 序列 → token ID 序列
- 解码(Decoding):token ID 序列 → token 序列 → 文本
不同 tokenizer 的「分词策略」决定了 token 的数量和质量。
22 三大主流分词算法对比
目前主流 LLM 使用三种分词算法,各有优劣:
| 算法 | 代表模型 | 原理 | 词表大小 | 优点 | 缺点 |
|---|---|---|---|---|---|
BPE | GPT-4/4o/ | 从字符级开始,迭代合并最高频字节对 | 50K-200K | 处理未知词汇能力强;支持多语言 | 可能产生无意义的 subword 切分 |
WordPiece | BERT / | 基于概率最大化选择合并,优先保留常见词 | 30K-50K | 对常见词保持完整,语义更连贯 | 对新词/罕见词切分较激进 |
SentencePiece | Llama 3/ | 无监督训练,直接在 Unicode 字符上操作 | 32K-256K | 不依赖预分词,支持所有语言 | 英文场景效率不如 BPE |
23 BPE 算法详解(Claude & GPT 系列使用的核心算法)
BPE(Byte Pair Encoding)最初是数据压缩算法,后被引入 NLP。它的核心思想很简单:
- 从字符级别的词表开始(每个字符是一个 token)
- 统计语料库中相邻符号对的出现频率
- 将出现频率最高的符号对合并为一个新符号
- 重复步骤 2-3,直到达到目标词表大小
这样,高频词(如 "the"、"hello")会作为一个完整 token 存在,低频词则被拆分为 subword。
为什么 Claude Opus 4.7 的 token 会变多?
新的 tokenizer 可能做了以下调整:
- 增加了更多 subword 级别的切分(更细粒度的语义单元)
- 改变了合并策略,优先保留更小的语义单元
- 扩大了多语言覆盖,导致英文场景的 token 密度上升
这类似于把「整块积木」换成了「更小的积木」——搭建同样的东西需要更多块。
三、Python 实战:构建多模型 Token 计数器
理论讲完了,让我们用代码来验证。以下是一个完整的 Python token 计数器,支持对比多个模型的 token 策略。
3.1 安装依赖
# 安装所需库
# pip install tiktoken transformers openai anthropic
import tiktoken
from transformers import AutoTokenizer
import json
class TokenCounter:
"""多模型 Token 计数器"""
def __init__(self):
self.encoders = {}
self._init_encoders()
def _init_encoders(self):
"""初始化各模型的 tokenizer"""
# OpenAI 系列 (tiktoken)
self.encoders["gpt-4o"] = tiktoken.encoding_for_model("gpt-4o")
self.encoders["gpt-4"] = tiktoken.encoding_for_model("gpt-4")
self.encoders["gpt-3.5-turbo"] = tiktoken.encoding_for_model("gpt-3.5-turbo")
# Claude 系列 (通过 Anthropic 官方库)
try:
import anthropic
self.encoders["claude-opus-4.7"] = anthropic.Client()
self.has_claude = True
except:
self.has_claude = False
def count_tiktoken(self, text: str, model: str) -> int:
"""使用 tiktoken 计算 token 数"""
if model not in self.encoders:
raise ValueError(f"不支持的模型: {model}")
return len(self.encoders[model].encode(text))
def count_transformers(self, text: str, model_name: str) -> int:
"""使用 HuggingFace transformers 计算 token 数"""
tokenizer = AutoTokenizer.from_pretrained(model_name)
return len(tokenizer.encode(text))
def compare_models(self, text: str) -> dict:
"""对比多个模型的 token 数量"""
results = {}
tiktoken_models = ["gpt-4o", "gpt-4", "gpt-3.5-turbo"]
for model in tiktoken_models:
count = self.count_tiktoken(text, model)
results[model] = {
"tokens": count,
"chars_per_token": len(text) / count if count > 0 else 0
}
return results
def estimate_cost(self, text: str, model: str,
input_price: float, output_price: float) -> dict:
"""估算 API 调用成本"""
counter = TokenCounter()
input_tokens = counter.count_tiktoken(text, model)
# 假设输出 token 数为输入的 50%
output_tokens = int(input_tokens * 0.5)
input_cost = (input_tokens / 1_000_000) * input_price
output_cost = (output_tokens / 1_000_000) * output_price
return {
"model": model,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"total_tokens": input_tokens + output_tokens,
"input_cost_usd": round(input_cost, 6),
"output_cost_usd": round(output_cost, 6),
"total_cost_usd": round(input_cost + output_cost, 6)
}
# 使用示例
if __name__ == "__main__":
counter = TokenCounter()
test_text = """
LLM Token Economics is a critical concept for AI engineers.
Understanding how different models tokenize text can save
thousands of dollars in API costs.
"""
results = counter.compare_models(test_text)
print(json.dumps(results, indent=2))
# 估算成本
cost = counter.estimate_cost(
test_text * 1000, # 模拟 1000 倍文本
"gpt-4o",
input_price=5.0, # $5/M input tokens
output_price=15.0 # $15/M output tokens
)
print(f"\n估算成本: ${cost['total_cost_usd']:.4f}")32 图像 token 计数(Claude Opus 4.7 场景)
图像处理的 token 计算与文本不同。Claude Opus 4.7 支持高达 2,576 像素的长边(约 375 万像素),而旧模型只支持约 120 万像素。这意味着:
- 高分辨率图像 → 更多 token → 更高成本
- 但如果模型理解能力显著提升,多花的 token 可能是值得的
下面是计算图像 token 的实用代码:
import base64
import anthropic
def estimate_image_tokens(image_path: str,
model: str = "claude-opus-4-7-20260414") -> dict:
"""估算图像输入的实际 token 消耗"""
client = anthropic.Anthropic()
# 读取图像
with open(image_path, "rb") as f:
image_data = base64.b64encode(f.read()).decode("utf-8")
# 确定媒体类型
media_type = "image/png" if image_path.endswith(".png") else "image/jpeg"
# 使用 Claude 的 token counting API
message = client.beta.messages.count_tokens(
model=model,
messages=[{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": media_type,
"data": image_data
}
},
{
"type": "text",
"text": "请描述这张图片"
}
]
}]
)
return {
"model": model,
"input_tokens": message.input_tokens,
"estimated_cost_usd": round(
message.input_tokens / 1_000_000 * 5.0 +
1000 / 1_000_000 * 25.0, # 假设输出 1000 tokens
4
)
}
def compare_image_token_costs(image_path: str) -> dict:
"""对比同一图像在不同模型下的 token 消耗"""
results = {}
models = {
"claude-opus-4-6-20251022": {"input_price": 5.0, "output_price": 25.0},
"claude-opus-4-7-20260414": {"input_price": 5.0, "output_price": 25.0},
}
for model, prices in models.items():
try:
token_info = estimate_image_tokens(image_path, model)
results[model] = token_info
except Exception as e:
results[model] = {"error": str(e)}
return results
# 使用示例
# results = compare_image_token_costs("test_image.png")
# for model, info in results.items():
# print(f"{model}: {info.get('input_tokens', 'N/A')} tokens, "
# f"${info.get('estimated_cost_usd', 'N/A')}")四、2026 年主流模型 Token 策略全景
了解各模型的 token 策略,是做出明智选型的前提。
| 模型 | Tokenizer | 词表大小 | 输入价格 ($/M tokens) | 输出价格 ($/M tokens) | 字符/token (英文均值) |
|---|---|---|---|---|---|
Claude Opus 4.7 | 新版 BPE | ~200K | $5.00 | $25.00 | ~2.7 |
Claude Opus 4.6 | 旧版 BPE | ~100K | $5.00 | $25.00 | ~3.9 |
Claude Sonnet 4.6 | 同 Opus 4.6 | ~100K | $3.00 | $15.00 | ~3.9 |
Claude Haiku 4.5 | 同 Opus 4.6 | ~100K | $0.80 | $4.00 | ~3.9 |
GPT-4o | tiktoken | ~100K | $2.50 | $10.00 | ~3.5 |
GPT-4 | tiktoken | ~100K | $10.00 | $30.00 | ~3.5 |
Llama 3.1 405B | SentencePiece | 256K | 免费 | 免费 | ~3.2 |
Kimi 2.6 | 自研 Tokenizer | ~150K | $1.50 | $6.00 | ~3.0 |
五、6 个实战级成本优化策略
掌握了 token 经济学原理后,以下是经过实战验证的成本优化策略,可以将 LLM API 成本降低 30%-60%。
策略 1:选择 token 效率最高的模型
不是最便宜的模型最省钱。如果模型 A 的 token 效率是模型 B 的 1.5 倍,即使单价稍高,总成本可能更低。
def find_cheapest_model(text: str, models: list) -> dict:
"""找出处理给定文本最便宜的模型
Args:
text: 输入文本
models: 模型列表,每项包含:
- name: 模型名称
- encoder: tiktoken encoder
- input_price: 输入价格 ($/M tokens)
- output_price: 输出价格 ($/M tokens)
- output_ratio: 预计输出/输入 token 比例
Returns:
最便宜的模型及其成本信息
"""
results = []
for model in models:
input_tokens = len(model["encoder"].encode(text))
output_tokens = int(input_tokens * model.get("output_ratio", 0.5))
input_cost = (input_tokens / 1_000_000) * model["input_price"]
output_cost = (output_tokens / 1_000_000) * model["output_price"]
results.append({
"name": model["name"],
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"total_tokens": input_tokens + output_tokens,
"total_cost_usd": round(input_cost + output_cost, 6),
"chars_per_token": round(len(text) / input_tokens, 2)
})
# 按总成本排序
results.sort(key=lambda x: x["total_cost_usd"])
return results[0]
# 使用示例
import tiktoken
models = [
{
"name": "gpt-4o",
"encoder": tiktoken.encoding_for_model("gpt-4o"),
"input_price": 2.50,
"output_price": 10.00,
"output_ratio": 0.5
},
{
"name": "gpt-4",
"encoder": tiktoken.encoding_for_model("gpt-4"),
"input_price": 10.00,
"output_price": 30.00,
"output_ratio": 0.5
},
]
text = "Your long input text here..." * 100
best = find_cheapest_model(text, models)
print(f"最便宜: {best['name']}, 成本: ${best['total_cost_usd']:.4f}")策略 2:Prompt 压缩 —— 用最少 token 表达同样意思
Prompt 中的冗余是 token 浪费的最大来源。以下是经过验证的 Prompt 压缩技巧:
| 技巧 | 原始 Prompt | 优化后 | Token 节省 |
|---|---|---|---|
移除冗余修饰词 | "Please kindly and carefully analyze the following text and provide a comprehensive and detailed response" | "Analyze the text. Provide detailed response." | ~60% |
使用结构化格式 | 长段落描述任务要求 | JSON/YAML 格式定义任务 | ~40% |
精简示例 | 5 个完整的 few-shot 示例 | 2 个关键示例 + 格式模板 | ~50% |
移除重复上下文 | 每次请求都发送完整系统提示 | 只发送变更部分 | ~70% |
缓存系统提示 | 重复发送相同系统提示 | 利用 system prompt caching | ~90% |
策略 3:利用 System Prompt Caching
Claude 和 OpenAI 都支持系统提示缓存。如果你的应用有较长的系统提示(如角色定义、规则说明),缓存可以节省 90% 的系统提示 token 成本。
import anthropic
def call_claude_with_caching(system_prompt: str, user_message: str) -> str:
"""使用 Claude 系统提示缓存降低重复成本
原理: Claude 会缓存系统提示的 token 表示,
同一系统提示的重复调用只需支付一次编码成本。
"""
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-6-20260314",
max_tokens=4096,
system=[{
"type": "text",
"text": system_prompt,
# 启用缓存锚点
"cache_control": {"type": "ephemeral"}
}],
messages=[{
"role": "user",
"content": user_message
}]
)
# 检查缓存命中情况
usage = message.usage
print(f"输入 tokens: {usage.input_tokens}")
print(f"缓存读取 tokens: {usage.cache_read_input_tokens}")
print(f"创建 tokens: {usage.cache_creation_input_tokens}")
return message.content[0].text
# 实际效果:
# 第一次调用:完整编码系统提示
# 后续调用:缓存读取,成本仅为原来的 10%
#
# 典型场景:
# - 长系统提示(2000+ tokens)+ 高频率调用
# - 月节省可达 $2,000-$5,000策略 4:图像预处理 —— 降低分辨率以减少 token
Claude Opus 4.7 的 tokenizer 对高分辨率图像极为「贪婪」。如果不需 2576px 的细节,预处理可以大幅降低成本:
from PIL import Image
import os
def optimize_image_for_llm(image_path: str,
max_long_edge: int = 1024,
quality: int = 85) -> str:
"""优化图像尺寸以减少 LLM token 消耗
Args:
image_path: 原始图像路径
max_long_edge: 长边最大像素数(Claude 4.7 支持到 2576)
quality: JPEG 质量 (1-100)
Returns:
优化后的图像路径
"""
img = Image.open(image_path)
w, h = img.size
long_edge = max(w, h)
if long_edge > max_long_edge:
scale = max_long_edge / long_edge
new_w = int(w * scale)
new_h = int(h * scale)
img = img.resize((new_w, new_h), Image.LANCZOS)
# 输出路径
base, ext = os.path.splitext(image_path)
output_path = f"{base}_optimized.jpg"
# 转为 JPEG 以进一步压缩
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
img.save(output_path, 'JPEG', quality=quality, optimize=True)
original_size = os.path.getsize(image_path)
new_size = os.path.getsize(output_path)
print(f"原始: {w}x{h}, {original_size/1024:.1f} KB")
print(f"优化: {new_w if long_edge > max_long_edge else w}x"
f"{new_h if long_edge > max_long_edge else h}, "
f"{new_size/1024:.1f} KB")
print(f"压缩率: {(1 - new_size/original_size)*100:.1f}%")
return output_path
# 实测效果(基于 Simon Willison 的数据):
# 3456x2234 PNG (3.7MB) → 优化为 1024x664 JPEG (120KB)
# Token 消耗从 3.01× 降至 ~1.2×
# 成本降低约 60%策略 5:流式输出 + Token 预算控制
对于不确定长度的输出,流式 API 配合 token 预算可以防止意外的高成本。
import openai
from typing import Generator
def stream_with_budget(client: openai.OpenAI,
messages: list,
max_tokens: int = 2000,
budget_warning: int = 1500) -> Generator[str, None, None]:
"""流式输出 + token 预算控制
当输出接近预算上限时发出警告,避免意外成本。
"""
token_count = 0
stream = client.chat.completions.create(
model="gpt-4o",
messages=messages,
max_tokens=max_tokens,
temperature=0.7,
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
token_count += 1
if token_count == budget_warning:
print(f"\n⚠️ 警告: 已使用 {token_count} tokens,接近预算上限")
yield content
print(f"\n✅ 完成: 总输出 {token_count} tokens")
# 估算成本
cost = (token_count / 1_000_000) * 10.0 # GPT-4o 输出价格
print(f"💰 输出成本: ${cost:.4f}")
# 使用示例
# client = openai.OpenAI()
# messages = [{"role": "user", "content": "写一篇关于 AI 的文章"}]
# for text in stream_with_budget(client, messages, max_tokens=2000):
# print(text, end="", flush=True)策略 6:混合模型路由 —— 用便宜模型做简单任务
不是所有任务都需要最强大的模型。建立智能路由规则,根据任务复杂度自动选择模型:
class ModelRouter:
"""智能模型路由器 —— 根据任务复杂度选择最优模型"""
ROUTING_RULES = [
{
"name": "simple_classification",
"condition": lambda t: len(t.split()) < 50,
"model": "claude-haiku-4-5",
"reason": "短文本分类不需要强大推理"
},
{
"name": "summarization",
"condition": lambda t: "summarize" in t.lower() or "总结" in t,
"model": "gpt-4o-mini",
"reason": "摘要任务中等模型即可"
},
{
"name": "code_generation",
"condition": lambda t: any(k in t.lower()
for k in ["code", "function", "实现", "写代码"]),
"model": "claude-sonnet-4-6",
"reason": "代码生成需要较强推理"
},
{
"name": "complex_analysis",
"condition": lambda t: len(t.split()) > 500 or
any(k in t.lower()
for k in ["analyze", "分析", "compare", "对比"]),
"model": "claude-opus-4-7",
"reason": "复杂分析需要最强模型"
},
{
"name": "default",
"condition": lambda t: True,
"model": "claude-sonnet-4-6",
"reason": "默认使用性价比最优模型"
}
]
@classmethod
def route(cls, task_description: str) -> dict:
"""根据任务描述路由到最优模型"""
for rule in cls.ROUTING_RULES:
if rule["condition"](task_description):
return {
"model": rule["model"],
"rule": rule["name"],
"reason": rule["reason"]
}
return cls.ROUTING_RULES[-1] # fallback
# 使用示例
# router = ModelRouter()
# result = router.route("请分析这份财报的关键财务指标变化")
# print(f"路由到: {result['model']} ({result['reason']})")
# → 路由到: claude-opus-4-7 (复杂分析需要最强模型)
#
# result = router.route("这是正面还是负面评价?")
# print(f"路由到: {result['model']} ({result['reason']})")
# → 路由到: claude-haiku-4-5 (短文本分类不需要强大推理)
#
# 实际效果:月度 API 成本降低 35%-50%六、成本优化效果总结
综合使用以上 6 个策略,在不同场景下的成本优化效果如下:
| 策略 | 典型场景 | 成本降低 | 实施难度 |
|---|---|---|---|
选择高效模型 | 所有场景 | 20%-40% | ⭐ 低 |
Prompt 压缩 | 高频调用 | 30%-60% | ⭐ 低 |
System Prompt Caching | 长系统提示 | 50%-90% | ⭐ 低 |
图像预处理 | 图像理解任务 | 40%-60% | ⭐⭐ 中 |
Token 预算控制 | 不确定长度输出 | 防止意外成本 | ⭐⭐ 中 |
混合模型路由 | 多任务混合场景 | 35%-50% | ⭐⭐⭐ 较高 |
七、总结与行动清单
核心要点
- Token ≠ 字数:不同模型的 token 策略差异可达 2-3 倍
- Claude Opus 4.7 更换 tokenizer 是 2026 年最重要的成本事件之一,直接影响约 40% 的使用成本
- 理解 BPE 分词原理 是做出明智优化的基础
- 6 个实战策略 可将 LLM API 成本降低 30%-60%
立即行动清单
- ✅ 用 token counting API 评估你的场景实际影响
- ✅ 对高分辨率图像进行预处理降分辨率
- ✅ 启用 System Prompt Caching
- ✅ 建立混合模型路由策略
- ✅ 设置 token 预算告警,防止意外成本