
文章目录
-
- [1. 结论先行](#1. 结论先行)
- [2. 环境信息](#2. 环境信息)
- [3. 官方规则速查:五个数字决定你的账单](#3. 官方规则速查:五个数字决定你的账单)
- [4. 核心代码](#4. 核心代码)
- [5. 运行结果:第一轮是亏的,第二轮才回本](#5. 运行结果:第一轮是亏的,第二轮才回本)
- [6. 可视化:成本差在哪一轮被拉开](#6. 可视化:成本差在哪一轮被拉开)
- [7. 什么时候用 1 小时 TTL](#7. 什么时候用 1 小时 TTL)
- [8. 踩坑与避坑](#8. 踩坑与避坑)
- [9. 总结](#9. 总结)
- 参考链接
1. 结论先行
API 涨价的讨论很多,省钱手段的实测账单很少。这篇用官方倍率把 Prompt Caching 的账逐轮算给你看:4k token 的固定系统提示,5 轮对话,不开缓存累计 27000 个相对成本单位,开了缓存只要 9170,省 66% 。但第一轮单看是 贵 25% 的------缓存写入按 1.25 倍计费,不是免费午餐。
一句话判断标准:同一份长前缀要被用第二轮以上,才值得开缓存。判断依据全部来自官方倍率,代码在第四节,改两个数字就能套你自己的对话。
2. 环境信息
- Python 3.13,只用标准库 + matplotlib,零第三方依赖
- 本文所有成本单位是归一化相对值(基础输入价 = 1.0),不写死美元单价,官方调价不影响结论
- 模拟器纯本地计算,不调 API、不产生真实计费;真实请求的构造代码同样在第四节
3. 官方规则速查:五个数字决定你的账单
以下倍率来自 Anthropic 官方文档(多源交叉核验一致),是全文计算的输入:
| 项目 | 数值 | 说明 |
|---|---|---|
| 缓存写入(5 分钟 TTL) | 1.25x 基础输入价 | 首次请求为这段前缀付的溢价 |
| 缓存写入(1 小时 TTL) | 2.0x 基础输入价 | ttl: "1h" 时替代上者 |
| 缓存读取 | 0.1x 基础输入价 | 命中即省 90% |
| 最小可缓存 tokens | 1024(Sonnet)/ 2048(Opus) | 低于此值不产生缓存 |
| 断点上限 | 每请求 4 个 | 按 tools → system → messages 顺序建立 |
两个最容易忽略的细节:每次命中会刷新 TTL ,但计时起点是发出请求那一刻,不是响应结束------如果一次响应流式生成了 4 分钟,下一次想命中缓存只剩约 1 分钟窗口。另外前缀哈希是累积的,断点之前任何一块内容变了,下一个请求就是全新写入。
4. 核心代码
请求构造 + 计费模拟器,两段都能直接跑:
python
# ---------- 请求构造:断点放在静态 system 块上 ----------
def build_cache_request(turn_question: str) -> dict:
return {
"model": "claude-sonnet-5",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "[HK bilingual workplace knowledge base, ~4k tokens]",
"cache_control": {"type": "ephemeral"},
}
],
"messages": [{"role": "user", "content": turn_question}],
}
# ---------- 计费模拟器:倍率全部来自官方文档 ----------
BASE = 1.0
def bill(no_cache_tokens, write_tokens=0, read_tokens=0, ttl="5m"):
w_mult = 1.25 if ttl == "5m" else 2.0
return (no_cache_tokens * BASE
+ write_tokens * BASE * w_mult
+ read_tokens * BASE * 0.1)
SYSTEM_KB_TOKENS = 4000
TOOL_TOKENS = 800
TURN_TOKENS = 200
rows = []
for t in range(1, 6):
history = TOOL_TOKENS + SYSTEM_KB_TOKENS + (t - 1) * TURN_TOKENS
if t == 1:
cached = bill(0, write_tokens=history + TURN_TOKENS)
else:
cached = bill(TURN_TOKENS, read_tokens=history)
plain = bill(history + TURN_TOKENS)
rows.append((t, plain, cached))
tot_p = sum(r[1] for r in rows)
tot_c = sum(r[2] for r in rows)
for t, p, c in rows:
print(f"turn {t}: no-cache {p:.2f} | cached {c:.2f} | saved {100*(1-c/p):.1f}%")
print(f"total: {tot_p:.2f} vs {tot_c:.2f} | saved {100*(1-tot_c/tot_p):.1f}%")
模拟场景对应一个真实需求:香港职场双语知识库问答------4k token 的固定系统提示(术语表 + 语气规范 + 历史口径),每轮追问约 200 token。这套逐轮累加的模拟逻辑可以直接复制,把三个 token 数换成你自己的配置就能算,建议收藏这段备用。
5. 运行结果:第一轮是亏的,第二轮才回本
turn | no-cache | cached | saved%
1 | 5000.00 | 6250.00 | -25.0%
2 | 5200.00 | 700.00 | 86.5%
3 | 5400.00 | 720.00 | 86.7%
4 | 5600.00 | 740.00 | 86.8%
5 | 5800.00 | 760.00 | 86.9%
total| 27000.00 | 9170.00 | 66.0%
三个值得停下来看的点:
第一,第一轮 -25% 不是误差。 5000 token 全价 vs 5200 token 的 1.25 倍写入价,多付的 1250 就是"买断这段前缀"的入场费。如果你的对话只有一轮(一次性脚本、单次摘要),开缓存纯亏。
第二,第二轮起省 86% 且趋于稳定。 历史全部走 0.1x 读取通道,每轮只有新增的 200 token 按全价。5200 → 700,这就是 4k 固定前缀的杠杆效应:前缀越长、轮数越多,省得越狠。
第三,保本点在第 2 轮。 第一轮多付 1250,第二轮省 4500,一轮就收复失地。所以判断口诀很简单:预计对话会超过一轮,就开。
6. 可视化:成本差在哪一轮被拉开


第一张图看单轮:红色(无缓存)逐轮上涨因为历史越滚越长;绿色(有缓存)第 1 轮是唯一高于红色的柱。第二张图看累计:两条线在第 2 轮交叉后一路分叉,5 轮拉开 3 倍。这段逐轮画图逻辑值得存下来,接任何长前缀场景前先跑一遍自己的参数。
7. 什么时候用 1 小时 TTL
1 小时档写入 2.0x,比 5 分钟档贵 60%。适合两种情况:一是高峰间隔超过 5 分钟 的场景(客服系统每 10 分钟来一个新会话,5 分钟档每轮都要重写);二是预热后批量复用------先花 2 倍价格写一次缓存,随后一小时的几百个请求全部走 0.1x 读取。粗算:只要预期命中次数超过 5 次,1 小时档就反超。
反过来,交互式会话(用户在打字,轮间隔通常小于 5 分钟)用默认 5 分钟档就够,而且每次命中自动续期,实际有效期比标称的长。
把保本逻辑推广成公式会更直观:设前缀 P token、每轮新增 N token,第 k 轮开缓存的累计成本是 1.25P + 0.1P×(k-1) + N×k,不开缓存是 k×(P+N)。两者相等时 k ≈ 1 + 1/(P/N)------也就是说前缀越长,回本越快,4k 前缀几乎必然第 2 轮回本,而 1k 出头的前缀可能要等上十轮。写死这个比值再决定开不开,比凭感觉稳得多。
8. 踩坑与避坑
| 踩坑 | 后果 | 避开姿势 |
|---|---|---|
单轮任务也加 cache_control |
白付 25% 写入溢价 | 先确认前缀会被第二轮用 |
| 以为 TTL 从响应结束起算 | 生成 4 分钟后缓存已过期 | 计时起点是请求发出时刻 |
| 断点前的块内容微调(加个时间戳) | 前缀哈希全变,触发全新写入 | 静态内容放断点前且保持冻结 |
| 前缀不足 1024 token(Sonnet) | 不产生缓存,静默全价 | 断点前凑足最小 token 数 |
监控缓存是否生效看响应里的两个 usage 字段:cache_creation_input_tokens(写入)和 cache_read_input_tokens(命中)。如果第二个一直是 0,说明前缀哈希没对上,这张表建议收藏,排查时按行核对。
9. 总结
Prompt Caching 的账不复杂:写 1.25 倍买一个可复用的前缀,读 0.1 倍收 90% 折扣,保本点在第 2 轮。真正要动脑的是结构------静态的 system、工具定义冻结在断点前,动态内容放后面,缓存才有命中的可能。在「DeepSeek涨价你换了吗」这类晒账单的讨论里,涨价不可控,倍率结构是自己可以优化的部分------这篇的模拟器改三个数字就能算你自己的账。
代码、倍率表、逐轮模拟逻辑连同第 7 节的回本公式都是可复现的,建议整套收藏,下次接长前缀场景前先算再开。这篇也收录进「CodingPlan·八月创作之星博客挑战赛」的八月收官------把 AI 用便宜这件事,本身就是技术活。
本文为原创技术实践,倍率数据来自 Anthropic 官方文档(2026-08 检索),价格为归一化相对值,实际计费以官方定价页为准;模拟器未调用真实 API,不产生计费。
参考链接
- Anthropic 官方文档 - Prompt Caching:https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching
- Anthropic 官方文档 - Pricing:https://docs.anthropic.com/en/docs/about-claude/pricing
- Anthropic 官方文档 - Messages API:https://docs.anthropic.com/en/api/messages
