📌 内容摘要
- Claude API 按 token 计费,输入和输出分开定价,输出价格通常是输入的 3-5 倍。
- 中文比英文消耗更多 token——1个汉字约等于 1.5-2 个 token,这是中文用户最容易踩的坑。
- Prompt Caching 可节省重复输入 token 费用高达 90%,是最值得优先使用的省钱手段。
- Batch API 所有请求费用打5折,适合非实时的批量处理任务。
一、Token 是什么?
Token 是 Claude 处理文本的最小单位,不完全等同于字或词。简单理解:
- 英文:1个 token ≈ 4个字母 ≈ 0.75个单词。
Hello是1个 token,understanding是1-2个 token - 中文:1个汉字 ≈ 1.5-2个 token。
你好约3个 token,人工智能约6-8个 token - 代码:通常比自然语言消耗更多 token,缩进、括号、分号都会计入
- 空格和标点:也消耗 token,不可忽略
同样的内容,中文比英文消耗约 1.5-2 倍的 token。一篇 1000 字的中文文章,大约消耗 1500-2000 token。做成本预估时一定要以中文内容实际测试,不能直接套英文的经验值。
二、Claude API 的计费结构
Claude API 采用输入输出分开计费的模式,单位是每百万 token(per million tokens)的美元价格:
| 模型 | 输入价格 | 缓存写入 | 缓存读取 | 输出价格 |
|---|---|---|---|---|
| Claude Opus 4.6 | $5.00 | $6.25 | $0.50 | $25.00 |
| Claude Sonnet 4.6 | $3.00 | $3.75 | $0.30 | $15.00 |
| Claude Haiku 4.5 | $1.00 | $1.25 | $0.10 | $5.00 |
价格单位:美元 / 百万 token,2026年3月。缓存读取价格约为标准输入价格的 1/10。
计费公式:
费用 = (输入 token 数 × 输入单价 + 输出 token 数 × 输出单价) / 1,000,000
举例:用 Sonnet 4.6 处理一个请求,输入 2000 token,输出 500 token:
费用 = (2000 × $3 + 500 × $15) / 1,000,000
= ($6,000 + $7,500) / 1,000,000
= $0.0135(约合人民币0.1元)
三、哪些内容计入输入 Token?
很多开发者低估了输入 token 的实际消耗,以下内容全部计入输入 token:
| 输入类型 | 说明 | 容易被忽视的点 |
|---|---|---|
| System Prompt | 角色设定、规则说明 | 每次请求都重新计费,即使内容不变 |
| 对话历史 | 多轮对话中的所有历史消息 | 对话越长,每次请求的输入越贵 |
| 当前用户消息 | 本轮用户输入的内容 | — |
| 上传的文件/图片 | 文档内容、图片描述 | 长 PDF 的 token 消耗可能超乎预期 |
| 工具定义(Tool Use) | 声明的函数/工具 schema | 工具越多,输入 token 越多 |
四、用 Python 精确计算 Token 数
import anthropic
client = anthropic.Anthropic()
# 发送请求前估算 token 数(不实际生成内容,费用极低)
response = client.messages.count_tokens(
model="claude-sonnet-4-6",
system="你是一个专业的中文写作助手,擅长商业文案写作。",
messages=[
{"role": "user", "content": "帮我写一篇关于人工智能的800字科普文章"}
]
)
print(f"预计输入 token 数:{response.input_tokens}")
# 实际请求后,从响应中获取精确用量
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system="你是一个专业的中文写作助手,擅长商业文案写作。",
messages=[
{"role": "user", "content": "帮我写一篇关于人工智能的800字科普文章"}
]
)
input_tokens = message.usage.input_tokens
output_tokens = message.usage.output_tokens
cost = (input_tokens * 3 + output_tokens * 15) / 1_000_000
print(f"实际输入 token:{input_tokens}")
print(f"实际输出 token:{output_tokens}")
print(f"本次费用:${cost:.5f}(约 ¥{cost * 7.2:.4f})")
五、7个降低成本的实用技巧
技巧一:Prompt Caching——最重要的省钱手段(节省 50-90%)
如果你的请求包含大量重复不变的内容(长 System Prompt、知识库文档、Few-shot 示例),开启 Prompt Caching 后,这部分内容首次写入缓存收取 1.25 倍费用,后续命中缓存只收取标准输入的 1/10 费用。
import anthropic
client = anthropic.Anthropic()
# 假设这是一份长达 5000 token 的知识库文档
KNOWLEDGE_BASE = """
[此处放入你的知识库内容,可以是产品文档、业务规则等...]
这部分内容在每次请求中都不变,非常适合缓存。
"""
def ask_with_cache(user_question: str) -> str:
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": KNOWLEDGE_BASE,
"cache_control": {"type": "ephemeral"} # 标记为可缓存
# ephemeral 缓存存活 5 分钟
# 高频应用可申请 extended cache(1小时)
}
],
messages=[
{"role": "user", "content": user_question}
]
)
# 查看缓存命中情况
usage = message.usage
if hasattr(usage, 'cache_read_input_tokens'):
print(f"缓存命中:{usage.cache_read_input_tokens} tokens(省了90%)")
print(f"缓存写入:{getattr(usage, 'cache_creation_input_tokens', 0)} tokens")
return message.content[0].text
# 第一次调用:写入缓存(1.25倍费用)
print(ask_with_cache("产品的退款政策是什么?"))
# 第二次及之后:命中缓存(0.1倍费用)
print(ask_with_cache("如何申请售后服务?"))
假设 System Prompt 5000 token,每天调用 1000 次,使用 Sonnet 4.6:
不缓存:5000 × 1000 × $3 / 1M = $15/天
有缓存:首次写入 $0.019 + 999次读取 5000 × 999 × $0.3 / 1M = $1.52/天
节省约 90%,每月少花 $400。
技巧二:Batch API——非实时任务打5折
对于不需要实时响应的任务(内容批量生成、数据处理、离线分析),使用 Batch API 所有费用直接打5折,且没有并发速率限制:
import anthropic
import json
client = anthropic.Anthropic()
# 准备批量请求(最多 10,000 条)
requests = [
{
"custom_id": f"task-{i}",
"params": {
"model": "claude-sonnet-4-6",
"max_tokens": 256,
"messages": [
{"role": "user", "content": f"用一句话总结:{text}"}
]
}
}
for i, text in enumerate([
"人工智能正在改变各行各业的工作方式...",
"量子计算有望在未来十年内实现突破...",
"气候变化导致全球极端天气事件增加...",
])
]
# 提交批量任务
batch = client.messages.batches.create(requests=requests)
print(f"Batch ID: {batch.id},状态: {batch.processing_status}")
# 轮询等待完成(通常 1-24 小时内完成)
import time
while True:
batch = client.messages.batches.retrieve(batch.id)
if batch.processing_status == "ended":
break
print(f"进度: {batch.request_counts.succeeded}/{batch.request_counts.processing}")
time.sleep(60)
# 获取结果
for result in client.messages.batches.results(batch.id):
if result.result.type == "succeeded":
print(f"{result.custom_id}: {result.result.message.content[0].text}")
技巧三:按任务选择合适模型
不要对所有任务都用最贵的模型。建立任务分级,按复杂度路由:
def get_model_for_task(task_type: str) -> str:
"""根据任务类型选择最合适(最省钱)的模型"""
routing = {
# 简单任务 → Haiku($1/$5,最便宜)
"classify": "claude-haiku-4-5-20251001", # 文本分类
"extract": "claude-haiku-4-5-20251001", # 信息提取
"translate": "claude-haiku-4-5-20251001", # 简单翻译
"summarize_short": "claude-haiku-4-5-20251001",
# 中等任务 → Sonnet($3/$15,主力)
"write": "claude-sonnet-4-6", # 内容写作
"code_simple": "claude-sonnet-4-6", # 简单代码
"qa": "claude-sonnet-4-6", # 问答
"summarize_long": "claude-sonnet-4-6",
# 复杂任务 → Opus($5/$25,旗舰)
"code_complex": "claude-opus-4-6", # 复杂架构设计
"analysis": "claude-opus-4-6", # 深度分析
"reasoning": "claude-opus-4-6", # 复杂推理
}
return routing.get(task_type, "claude-sonnet-4-6")
# 使用示例:同样是"翻译"任务,用 Haiku 比 Sonnet 便宜 3 倍
model = get_model_for_task("translate")
print(f"翻译任务使用模型:{model}")
技巧四:压缩 System Prompt
System Prompt 的 token 消耗在每次请求中都会累计。把 1000 token 的 System Prompt 压缩到 300 token,对于高频应用来说意味着每次请求节省 700 token 的输入费用。
# 低效写法(~200 token): BAD_SYSTEM = """ 你是一个非常有帮助的AI助手,你的目标是帮助用户解决各种问题。 你应该总是保持友好和专业的态度。当用户提问时,你需要仔细 理解他们的问题,然后给出清晰、准确、有帮助的回答。如果你 不确定某些信息,你应该如实告知用户,而不是编造信息。 """ # 高效写法(~50 token): GOOD_SYSTEM = "有帮助的AI助手。回答准确清晰,不确定时说明。" # 节省约75%的 System Prompt token 消耗
技巧五:控制对话历史长度
多轮对话中,每次请求都要传入完整历史,历史越长成本越高。在不影响体验的前提下限制历史条数:
def trim_history(history: list, max_turns: int = 10) -> list:
"""只保留最近 N 轮对话,降低输入 token 成本"""
if len(history) <= max_turns * 2:
return history
# 保留最近的 N 轮(每轮含 user + assistant 各一条)
return history[-(max_turns * 2):]
def summarize_history(history: list, client) -> list:
"""当历史过长时,先总结再继续(更智能的策略)"""
if len(history) < 20:
return history
# 让 Claude 总结前半段对话
summary_prompt = f"请用200字以内总结以下对话的关键信息:\n{str(history[:10])}"
summary = client.messages.create(
model="claude-haiku-4-5-20251001", # 用 Haiku 做总结,省钱
max_tokens=300,
messages=[{"role": "user", "content": summary_prompt}]
).content[0].text
# 用摘要替换前半段
return [
{"role": "assistant", "content": f"[之前对话摘要:{summary}]"},
*history[10:]
]
技巧六:精确设置 max_tokens
max_tokens 是输出上限,设得过大会导致 Claude 生成不必要的冗长内容。根据实际需求合理设置,强制 Claude 简洁回答:
task_token_limits = {
"分类任务": 64, # 只需要一个类别词
"情感分析": 32, # 正面/负面/中性
"关键词提取": 128, # 几个词
"单句翻译": 256, # 约等于原文长度
"段落摘要": 512, # 压缩到原文 1/3
"文章写作": 2048, # 中等长度文章
"代码生成": 4096, # 完整函数
"深度分析": 8192, # 长报告
}
# 在 Prompt 中也要求 Claude 简洁
CONCISE_INSTRUCTION = "回答简洁直接,不要重复问题,不要废话。"
技巧七:监控和设置消费上限
class CostMonitor:
"""实时监控 API 费用,超出预算时发出警告"""
PRICES = {
"claude-opus-4-6": {"input": 5.0, "output": 25.0},
"claude-sonnet-4-6": {"input": 3.0, "output": 15.0},
"claude-haiku-4-5-20251001": {"input": 1.0, "output": 5.0},
}
def __init__(self, daily_budget_usd: float = 10.0):
self.daily_budget = daily_budget_usd
self.today_cost = 0.0
self.today_requests = 0
def record(self, model: str, input_tokens: int, output_tokens: int):
p = self.PRICES.get(model, {"input": 3.0, "output": 15.0})
cost = (input_tokens * p["input"] + output_tokens * p["output"]) / 1_000_000
self.today_cost += cost
self.today_requests += 1
if self.today_cost > self.daily_budget * 0.8:
print(f"⚠️ 警告:今日费用 ${self.today_cost:.3f} 已超过预算的80%")
if self.today_cost > self.daily_budget:
raise Exception(f"❌ 已超出今日预算 ${self.daily_budget}")
return cost
def report(self):
print(f"今日请求:{self.today_requests} 次")
print(f"今日费用:${self.today_cost:.4f}")
print(f"平均单次:${self.today_cost/max(self.today_requests,1):.5f}")
# 全局监控实例
monitor = CostMonitor(daily_budget_usd=5.0)
# 在每次 API 调用后记录
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
messages=[{"role": "user", "content": "你好"}]
)
cost = monitor.record(
response.model,
response.usage.input_tokens,
response.usage.output_tokens
)
print(f"本次费用:${cost:.5f}")
六、各方案综合节省效果
| 省钱技巧 | 适用场景 | 节省幅度 | 实施难度 |
|---|---|---|---|
| Prompt Caching | 有固定长 System Prompt | 50-90% | 低(加几行代码) |
| Batch API | 非实时批量任务 | 50%(全部) | 中(改请求方式) |
| 模型分级路由 | 任务复杂度差异大 | 30-70% | 中(需任务分类) |
| 压缩 System Prompt | 所有场景 | 10-40% | 低 |
| 控制历史长度 | 多轮对话应用 | 20-60% | 低 |
| 精确设置 max_tokens | 短回答任务 | 10-30% | 低 |
常见问题
Q:流式输出和普通输出费用一样吗?
完全一样。流式输出只是改变内容的传输方式(逐块推送而非一次性返回),不影响 token 数量和计费逻辑。输入 token 数 × 输入价格 + 输出 token 数 × 输出价格,与是否使用 streaming 无关。
Q:请求失败了还收费吗?
取决于失败阶段。如果请求在模型开始生成前就失败了(如参数错误、认证失败),不收费。如果模型已经开始生成内容但中途中断,已生成的 token 会计费。网络超时后重试会产生两次计费。
Q:Prompt Caching 的缓存什么时候失效?
ephemeral(默认)缓存有效期为 5 分钟,5 分钟内没有新请求命中就会过期。对于高频应用(每分钟多次调用)缓存命中率非常高;低频应用(每小时几次)可以申请 extended cache 延长到 1 小时。
Q:Console 上看到的费用和自己计算的不一样,为什么?
最常见的原因是中文 token 消耗被低估,或者忽略了对话历史中 AI 回复也会计入下一次请求的输入 token。建议直接从 response.usage 读取实际 token 数,而不是靠字数估算。
总结
降低 Claude API 成本的优先顺序:首先开启 Prompt Caching(有固定长内容的话效果立竿见影),其次考虑 Batch API(非实时任务直接打5折),再做 模型分级路由(简单任务用 Haiku)。这三步组合下来,大多数应用的 API 成本可以降低 60-80%,剩下的精细优化(压缩 prompt、控制历史、精确 max_tokens)是锦上添花。