缓存读取降价 75%,每个任务的成本反而涨了 20%:LLM 成本到底该怎么算
2026-09-01,Anthropic 发布 Claude Fable 5.1。同一天 Artificial Analysis 给出了一个反直觉的实测结果:缓存读取价格砍掉了 75%(每百万 token 从 1 美元降到 0.25 美元),但 Fable 5.1 跑完一个智能指数任务的成本,比上一代还高 20%(3.76 美元 vs 3.14 美元)—— 因为它消耗的输出 token 大约是上一代的 1.7 倍。
这不是某一家的特例,而是所有做 LLM 成本预算的团队都会踩的坑:你按"每百万 token 单价"做的预算,和账单不是一回事。本文用可核实的公开数据把这件事拆开,并给一份能直接跑的成本测算脚本(只用标准库,附自测结果)。
一、先把数据摆出来(全部为可核实的公开来源)
以下是 Artificial Analysis 2026-09-01 对 Claude Fable 5.1 的实测与 Anthropic 官方定价,原文数字照抄:
| 项目 | 数值 |
|---|---|
| AA 智能指数(max 档) | 66—— 该机构当时测到的最高分 |
| 对照:Claude Opus 5 (max) | 63 |
| 对照:Claude Fable 5 (max) | 62 |
| 对照:GPT-5.6 Sol (max) | 61 |
| 对照:Grok 4.6 (high) | 61 |
| 标准定价(输入/输出,每百万 token) | $10 / $50(与 Fable 5 一致) |
| 缓存写入(每百万 token) | $12.5(与 Fable 5 一致) |
| 缓存读取(每百万 token) | $1 → $0.25(降 75%) |
| 每智能指数任务成本(max) | $3.76(Fable 5 为 $3.14,高 20%) |
| 每任务成本(xhigh 档) | $2.72(比 max 省 $1.04,分数 65) |
| 对照:Claude Opus 5 (max) 每任务 | $2.34 |
| 缓存降价带来的节省 | 约 $1.40 / 任务 |
| 若不降价,成本会是 | 约 $5.16 |
| 输出 token 用量 | 约为 Fable 5 的1.7 倍 |
| 上下文窗口 | 100 万 token |
| 安全回退(fallback)占比 | 约 4% 的输出 token |
其他同批实测:HLE 59.1%(此前最好 55.5%)、Terminal-Bench v2.1 91.4%、SciCode 62.0%、GDPval-AA v2 1,853 Elo、AA-Briefcase 1,694 Elo。
二、为什么"单价降了"和"成本涨了"能同时成立
把一次调用的账单拆成四项,事情就很清楚:
成本 = 未命中缓存的输入 × 输入价 + 命中缓存的输入 × 缓存读取价 + 输出 × 输出价 + 缓存写入 × 缓存写入价缓存降价只动第二项。而在这四家里,第二项在智能体(agentic)负载里占比最高 —— 长任务反复把同一段上下文(系统提示、工具定义、历史轨迹)重新读进去,这部分几乎全是缓存读取。AA 的原文明确说,这 1.40 美元的节省"集中在 agentic 评测里,因为那里大多数输入 token 是缓存读取"。
但账单的主导项是第三项:输出。Fable 5.1 的输出 token 约是上一代的 1.7 倍,而输出价是 $50 —— 是缓存读取价($0.25)的200 倍。所以:
输入侧省下 1.40 美元,输出侧多花约 2.00 美元,净结果是贵 20%。
这条结论可以推广成一句工程判据:
只要输出价 ÷ 缓存读取价 超过约 100 倍,优化缓存就救不了你的账单;能救的只有"少输出"。
三、比"选哪个模型"更影响成本的,是 effort 档位
同一个模型的不同推理档位,差距比跨厂商还大。AA 测到 Fable 5.1 的五个档位:
| 档位 | 输出 token 用量 | 智能指数 |
|---|---|---|
| low | 13.1M | 58 |
| … | … | … |
| max | 143.7M | 66 |
从 low 到 max,token 用量差 11 倍,分数只差 8 分。换算成钱:max 档 $3.76/任务,xhigh 档 $2.72/任务(省 29%),而 xhigh 的分数是 65 —— 只比 max 低 1 分。
AA 还指出一个容易忽略的下限差异:GPT-5.6 Sol (medium) 的 token 用量(12M)甚至略低于 Fable 5.1 (low) 的 13.1M—— 也就是说,跨厂商比较"谁更省"时,如果不锁定 effort 档位,比出来的东西没有意义。
四、可操作的三步:按自己的负载算,而不是按排行榜算
第 1 步:量出自己负载的四个数
不要估。从你的网关/代理日志里统计(大多数 OpenAI 兼容网关的usage字段直接给):
prompt_tokens(输入总量)prompt_tokens_details.cached_tokens(其中命中缓存的)completion_tokens(输出)- 平均每个任务调用几次
第 2 步:代进四项公式,别用简化版
下面这份脚本就是干这个的。它刻意不把"平均单价"当成一个数,而是按四项分别算:
@dataclass(frozen=True)classPrice:"""每百万 token 的价格(美元)。"""inp:float# 未命中缓存的输入cached:float# 命中缓存的输入(缓存读取)out:float# 输出cache_write:float# 缓存写入FABLE_5_1=Price(inp=10.0,cached=0.25,out=50.0,cache_write=12.5)FABLE_5=Price(inp=10.0,cached=1.00,out=50.0,cache_write=12.5)# 降价前@dataclassclassWorkload:"""一次任务的负载画像。"""prompt:int# 输入总 tokencached_ratio:float# 输入中命中缓存的比例 0–1out:int# 输出 tokencalls:int=1# 该任务拆成几次调用(agentic 场景常 >1)defbreakdown(w:Workload,p:Price)->dict:"""四项拆开算。返回每一块钱花在哪。"""cached=int(w.prompt*w.cached_ratio)fresh=w.prompt-cached ci=fresh*p.inp/1e6cc=cached*p.cached/1e6co=w.out*p.out/1e6per_call=ci+cc+co# 缓存写入只在第一次调用时付(后续调用读缓存)write=w.prompt*p.cache_write/1e6ifw.calls>1else0.0task=per_call*w.calls+writereturn{"ci":ci,"cc":cc,"co":co,"per_call_usd":per_call,"write_usd":write,"task_usd":task,"out_share":(co/per_call)ifper_callelse0.0}注意cache_write这一项:很多团队的预算表里根本没有它,但在多次调用的 agentic 负载下它会出现在账单上(见下一节的实测数字)。
第 3 步:看"输出占比"这一列
if__name__=="__main__":w=Workload(prompt=200_000,cached_ratio=0.90,out=20_000,calls=3)# breakdown() 与上面的 cost() 同一套四项公式,逐项打印...完整脚本见文末,运行python llm_cost.py即可复现。实测输出(本文自测,非手算):
负载画像:输入 200,000 tok(命中缓存 90%)、输出 20,000 tok、拆成 3 次调用 方案 输入费 缓存费 输出费 单次$ 写入$ 任务$ 输出占比 ---------------------------------------------------------------------------------------------- Fable 5.1 0.200 0.045 1.000 1.245 2.500 6.235 80% Fable 5(旧价) 0.200 0.180 1.000 1.380 2.500 6.640 72% 缓存降价带来的节省:每任务 $0.405 缓存这一项本身:$0.180 → $0.045(降 75%) 但它在单次成本里只占 13.0% 输出一项占 80% —— 这才是账单大头 若把输出砍一半(20,000 → 10,000 tok): 任务 $4.735(省 $1.500) 结论:输出价 ÷ 缓存读取价 = 200 倍 —— 优化缓存救不了账单,少输出才能。四个可以直接用的结论:
- 输出占了单次成本的 80%。缓存那一项只占13.0%—— 优化一个占 13% 的项,天花板就在那里。
- 缓存降价在这个负载下每任务省 $0.405($6.640 → $6.235)。注意它不是省 75%—— 降到 75% 的是缓存这一项本身($0.180 → $0.045),但那一项本来就不是大头。
- 把输出砍一半,每任务省 $1.500 —— 是缓存优化收益($0.405)的 3.7 倍。这一条是本文最该记住的数字。
- 输出价 ÷ 缓存读取价 = 200 倍。只要这个比值在百倍量级,任何输入侧优化都动不了大盘。
还有一个容易漏的项:缓存写入($12.5/百万 token)。在上面的负载里它是$2.500—— 比三次调用的全部输入费加起来还高。缓存不是免费的:只有当同一段前缀被重复读取到足够多次,写入费才摊得回来。一次性任务开缓存是纯亏。
五、选型时的三条判据
第一,锁定 effort 档位再比价格。11 倍的 token 跨度会让任何不锁档位的比较失去意义。要比就比"同一个任务、同一个通过率下的每任务成本"。
第二,看"每任务成本"而不是"每百万 token 价格"。后者是原料价,前者是成品价。AA 这类独立评测给的就是后者(Fable 5.1 max $3.76、Opus 5 max $2.34)。
第三,分数差在噪声里时,用钱做决定。Fable 5.1 (max) 66 分、Opus 5 (max) 63 分、GPT-5.6 Sol (max) 61 分,这个量级的差距在部分子项上已经落在置信区间内(AA 自己就指出 Fable 5.1 与 Opus 5 在 GDPval-AA v2 上的领先"在置信区间内")。而每任务成本 1.6 倍的差距是确定的。
六、一句话总结
缓存降价是输入侧的优化,而账单由输出侧主导。
把预算模型从"单价 × token 总量"改成四项分开算,你才会发现真正该动的是"让模型少说"。
附:完整脚本
#!/usr/bin/env python# -*- coding: utf-8 -*-"""LLM 成本测算:把账单拆成四项,而不是用"平均单价 × token 总量"。"""from__future__importannotationsimportargparsefromdataclassesimportdataclass@dataclass(frozen=True)classPrice:"""每百万 token 的价格(美元)。"""inp:float# 未命中缓存的输入cached:float# 命中缓存的输入(缓存读取)out:float# 输出cache_write:float# 缓存写入# 2026-09-01 官方价(Anthropic 文档;缓存读取为降价后)FABLE_5_1=Price(inp=10.0,cached=0.25,out=50.0,cache_write=12.5)FABLE_5=Price(inp=10.0,cached=1.00,out=50.0,cache_write=12.5)# 降价前@dataclassclassWorkload:"""一次任务的负载画像。"""prompt:int# 输入总 tokencached_ratio:float# 输入中命中缓存的比例 0–1out:int# 输出 tokencalls:int=1# 该任务拆成几次调用(agentic 场景常 >1)defbreakdown(w:Workload,p:Price)->dict:"""四项拆开算。返回每一块钱花在哪。"""cached=int(w.prompt*w.cached_ratio)fresh=w.prompt-cached ci=fresh*p.inp/1e6cc=cached*p.cached/1e6co=w.out*p.out/1e6per_call=ci+cc+co write=w.prompt*p.cache_write/1e6ifw.calls>1else0.0task=per_call*w.calls+writereturn{"fresh_in":fresh,"cached_in":cached,"ci":ci,"cc":cc,"co":co,"per_call_usd":per_call,"write_usd":write,"task_usd":task,"out_share":(co/per_call)ifper_callelse0.0,}defmain()->int:ap=argparse.ArgumentParser()ap.add_argument("--prompt",type=int,default=200_000)ap.add_argument("--cached",type=float,default=0.90)ap.add_argument("--out",type=int,default=20_000)ap.add_argument("--calls",type=int,default=3)a=ap.parse_args()w=Workload(prompt=a.prompt,cached_ratio=a.cached,out=a.out,calls=a.calls)print(f"负载画像:输入{w.prompt:,}tok(命中缓存{w.cached_ratio:.0%})"f"、输出{w.out:,}tok、拆成{w.calls}次调用\n")hdr=(f"{'方案':<14}{'输入费':>8}{'缓存费':>8}{'输出费':>8}"f"{'单次$':>9}{'写入$':>8}{'任务$':>9}{'输出占比':>9}")print(hdr)print("-"*94)res={}forname,pin(("Fable 5.1",FABLE_5_1),("Fable 5(旧价)",FABLE_5)):b=breakdown(w,p)res[name]=bprint(f"{name:<14}{b['ci']:>8.3f}{b['cc']:>8.3f}{b['co']:>8.3f}"f"{b['per_call_usd']:>9.3f}{b['write_usd']:>8.3f}"f"{b['task_usd']:>9.3f}{b['out_share']:>8.0%}")new,old=res["Fable 5.1"],res["Fable 5(旧价)"]print(f"\n缓存降价带来的节省:每任务 ${old['task_usd']-new['task_usd']:.3f}")print(f" 缓存这一项本身:${old['cc']:.3f}→ ${new['cc']:.3f}"f"(降{(1-new['cc']/old['cc'])*100:.0f}%)")print(f" 但它在单次成本里只占{old['cc']/old['per_call_usd']:.1%}")print(f" 输出一项占{new['out_share']:.0%}—— 这才是账单大头")print(f"\n若把输出砍一半({w.out:,}→{w.out//2:,}tok):")w2=Workload(w.prompt,w.cached_ratio,w.out//2,w.calls)print(f" 任务 ${breakdown(w2,FABLE_5_1)['task_usd']:.3f}"f"(省 ${new['task_usd']-breakdown(w2,FABLE_5_1)['task_usd']:.3f})")print("\n结论:输出价 ÷ 缓存读取价 = "f"{FABLE_5_1.out/FABLE_5_1.cached:.0f}倍 —— 优化缓存救不了账单,少输出才能。")return0if__name__=="__main__":raiseSystemExit(main())环境:Python 3.10+,只用标准库,无第三方依赖,可离线运行。
参考来源
- Artificial Analysis,《Claude Fable 5.1 tops the Artificial Analysis Intelligence Index but costs 20% more per task than Fable 5 despite a 75% cache read price cut》,2026-09-01:https://artificialanalysis.ai/articles/claude-fable-5-1
- Anthropic Claude Platform 文档 · Claude Fable 5.1 模型页(定价与上下文窗口):https://platform.claude.com/docs/en/models/fable-5-1/overview
- 文中脚本为本文自测产物,可离线运行,无第三方依赖。