我手上有一份很长的产品文档,打算反复拿去问模型。第一反应当然是去开上下文缓存——同一段前缀不用每次重发,命中部分按更低的价算,这在各家文档里都算省钱常识。
结果我把定价页翻到缓存那一节,发现多了一行我以前没见过的收费项:缓存写入。它不是免费的,而且分两档,贵的那一档写一次四十块,比我把这段前缀原样重发一遍还贵一倍。我把整页翻完,把这笔账算了一遍。
我把这一页的四行价抄了下来
第一眼盯的是 kimi-k3 这一组,四个数都按每 1M tokens 计:输入未命中 20 元,输入命中 2 元,缓存写入 5 分钟档 20 元,缓存写入 1 小时档 40 元。输出另算,100 元。页面在表下面专门注了一句,这里的 1M 等于 1,000,000。
同一张表下面还挂着 K2 系列三档,我顺手一起抄了:kimi-k2.7-code 命中 1.30、未命中 6.50、输出 27.00;kimi-k2.7-code-highspeed 是 2.60、13.00、54.00,三项都正好是前一档的 2 倍;kimi-k2.6 是 1.10、6.50、27.00,跟 k2.7-code 只差在命中价上。三档的上下文窗口都是 262,144 tokens。
这里有个我差点看漏的地方:窗口那一列写的是 262,144 和 1,048,576,是二的整数次幂;而计费单位那句写的是 1M 等于 1,000,000,是十的整数次幂。同一个 M,装进去的时候按前者算,算钱的时候按后者算,中间差 4.86 个百分点。也就是说,把 k3 的窗口塞满,账单上记的是 1.048576 个计费单位。
命中价是未命中价的十分之一,也就是每有 1M 前缀被复用,就比原来少花 18 元。这一半是我本来就熟悉的算法。真正让我停下来的是写入那两行:5 分钟档 20 元,跟未命中一个价;1 小时档 40 元,是未命中的 2 倍。换句话说,把前缀存进缓存这个动作,自己就是一笔账,而且这笔账跟命中省下的钱方向相反。
写入一次四十块,比不开缓存还贵一倍
我拿一段 1M 的前缀算了三种情况。第一种最极端:写完就再也不用了。不开缓存,这一百万 token 按未命中算 20 元;选了 1 小时档,写入费 40 元,一次命中都没有,白付 20 元,正好贵一倍。
第二种是只复用一次。1 小时档是写入 40 加命中 2,共 42 元;不开缓存是两次各 20,共 40 元。这时候缓存还是亏的,贵 2 元,贵 5 个百分点。
第三种是复用两次,局面就翻过来了:1 小时档 40 加 4 等于 44 元,不开缓存是三次 60 元,省 16 元,省 26.7%。复用十次的时候差距拉开到最大,1 小时档总共 60 元,不开缓存 220 元,省 160 元,省 72.7%。
我把临界值算成了一个倍数
算完我就想找一个能直接拿去对账的数。控制台里现成有一个:缓存写入摊销倍数,等于命中 tokens 除以写入 tokens。我把它换成钱重新推了一遍。
对 1 小时档,省钱的条件是写入费加命中费小于全部按未命中价计,化简之后是命中量除以写入量要大于 1.11。也就是说每写进去 1 个 token,至少得命中回来 1.11 个,这笔缓存才开始回本。前面那三种情况正好对得上:只写不用是 0,复用一次是 1,都过不了 1.11 这道线;复用两次是 2,过了。
5 分钟档不用算这个倍数,因为它的写入价和未命中价一样,等于先把该付的那份付了,之后命中多少都是净赚。这两个档位的差别,全在那多出来的 20 元。
我另外算了一版间隔刚好卡在中间的情形:每 6 分钟问一次,5 分钟档每次来都过期,得重写一遍。问两次时,5 分钟档 40 元胜过 1 小时档 42 元;问三次就反过来,1 小时档 44 元,5 分钟档 60 元,差 16 元;问十次差到 142 元。所以这个选择不是看一次两次,是看这一轮一共要问几轮。
拿我开头那份文档试一遍:30 万 token 的前缀,问十次。不开缓存是 60 元;选 1 小时档是 12 元加 5.4 元,共 17.4 元,省 71%;如果能把间隔压到 5 分钟以内用默认档,是 11.4 元,省 81%。
还有一个折扣力度上的落差值得记一下:k3 的命中价是未命中的十分之一,而 k2.7-code 是五分之一,k2.6 是六分之一多一点。同一页上三家一样叫缓存,便宜的程度差着一倍,混着用的时候别拿一个数去套全部。
写进去就改不了,两档还不互通
真正让我把这条记下来的,是 TTL 在第一次写入时就锁死了。页面写得很清楚:同一个前缀命中后续期,续的是原来的 TTL,不收费但也改不了档;5 分钟和 1 小时是两个互不打通的缓存;缓存不支持手动清除,要等它彻底过期,才能按新的 TTL 重新写。
这意味着第一发请求就把这笔账定死了。不传参数时系统默认按 5 分钟档写入;想要 1 小时档,得显式传 prompt_cache_options,走 Anthropic 接口则是顶层的 cache_control,而且省略这个字段时本次只读 5 分钟缓存、根本不写入。
还有两条容易漏的门槛。一条是缓存按块存,凑不满一整块的尾巴写不进去,那部分按未命中价算。另一条是前缀要一字不差,我在前缀里插个时间戳或者随机 ID,它后面就全部作废。
我先给自己定下三条规矩
第一条看间隔。连续追问、间隔通常不超过 5 分钟,用默认的 5 分钟档;间隔会超过 5 分钟但能在 1 小时内复用,选 1 小时档;同一个前缀往往隔一小时以上才再用到,就别专门配缓存了。
第二条看倍数。选 1 小时档之前,我先估一下命中量能不能到写入量的 1.11 倍以上,过不了就别多付那 20 元。
第三条看摆放。稳定的 system prompt、工具定义、参考文档放请求前部,用户问题和工具结果放后部,前缀里不插任何动态字段。
对账的时候我记了三处:输入 tokens 等于未命中加命中加写入,三者互斥;响应头里有 Msh-Usage-Cache-Write-Tokens-5m 和 Msh-Usage-Cache-Write-Tokens-1h 两个字段,能看出这次写的是哪一档;控制台的 Caching 概览页直接给了命中率和摊销倍数,不用自己除。
有两句话我得一并放这儿。一是页面自己写明,写入成本原先就含在输入价格里,拆开只是计费透明化,现有请求的总体费用不变,所以这不是涨价。二是这套写入计费只有 kimi-k3 有,kimi-k2.7、kimi-k2.7-highspeed、kimi-k2.6 都不支持,但这三档的定价表里仍然列着缓存命中价,我没找到把这两处说法统一起来的说明,只能照录。
顺带说一个我算完才注意到的比例:这一页上输出 100 元,是未命中的 5 倍、命中的 50 倍。每输出 1M token 花掉的钱,相当于 5.56M token 命中省下来的钱。缓存能省的是输入那一头,输出那一头它一点不碰。
我这份文档最后选了 1 小时档,一天问十几次,间隔不定,命中量远远够过 1.11 那道线。你手上那份反复喂的前缀大概多长、多久问一次?把这两个数报给我,我照上面那张表帮你算该选哪一档。
本文含 AI 辅助创作内容:资料检索与初稿由 AI 完成,观点梳理、数据核验与编校由人工完成。