📌 内容摘要

  • 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)是锦上添花。