阶跃星辰 Prompt 缓存怎么用:命中条件与 usage 字段排查

2026-08-25

数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。

阶跃星辰的 Prompt 缓存跟很多人想的不一样:它没有「开启缓存」的开关,也没有让你标记缓存断点的参数。官方文档《Prompt 缓存最佳实践》里的机制是自动前缀缓存——请求长度超过官方给出的最小 Token 门槛后缓存会自动启用,系统拿你这次请求的 Prompt 前缀去查有没有现成缓存,命中就复用、没命中就正常推理并把前缀存下来供下次用。所以你能做的优化全在 Prompt 的排布上:把稳定不变的内容放前面、把每次都变的内容放后面,让前缀尽可能长期保持一字不差。验证有没有命中也只有一条路,就是去看返回里的 cached_tokens

先确认你的模型在支持范围内

官方把「缓存支持模型」放在整篇《Prompt 缓存最佳实践》的第一节,排在基础原理、命中判断、可缓存内容、最佳实践、排查思路之前。这一节点名列出了支持 Prompt 缓存的模型,并且明确写了「其他模型暂时不支持 Prompt 缓存」——注意这是一个白名单,不是黑名单。写作时官方页面上列出的是 step-3.7-flash、step-3.5-flash(含带日期后缀的版本)以及 step-1o-turbo-vision 这一类模型,具体名单以官方文档当前版本为准,模型迭代之后这一栏是会变的。

这条约束的实际后果是:如果你在选型阶段就把「靠缓存压住重复上下文的开销」写进了方案,那模型选择这一步就已经被限制住了,不能等到接完了才回头查支持列表。跨厂商的通用规律可以先看大模型 API 缓存计费机制,但每家支持哪些模型都得回自家文档核。

缓存怎么被启用:前缀查询与最小单元

官方把这个过程拆成了三步,值得逐字理解:

  1. 缓存查询——根据你这次请求的 Prompt 的前缀,查询当前 Prompt 是否有系统的缓存;
  2. 缓存命中——命中的话,系统使用缓存,再加上本次请求里缓存不包含的那部分内容进行推理;
  3. 缓存未命中——未命中则正常推理,处理完成后把 Prompt 前缀缓存起来,供下一次请求使用。

有两个细节藏在这三句话里。第一,匹配的单位是「前缀」,不是「相似度」。前面只要改了一个字,从改动点往后的缓存就接不上了,这也是为什么官方的最佳实践第一条就是把静态内容放在 Prompt 开头。第二,缓存是请求本身副作用式地建立的,你不需要(也没法)单独发一个「预热请求」去声明缓存内容,第一次请求走完之后前缀自然就在缓存里了。

长度上还有一个硬门槛:官方写明会以一定 Token 数作为最小单元开始缓存,Prompt 长度不到这个门槛就不会命中,当前版本文档里给出的门槛是 256 个 Token(以官方文档当前版本为准)。这也就解释了一种情形——短问答类的接口不管调多少次都看不到命中,不是缓存坏了,是压根没到起步长度。

淘汰策略官方也说了,用的是最近最少使用(LRU):系统请求高峰期,不使用的缓存更容易被逐出;低峰期缓存的生命周期则会更长。换句话说缓存的存活时间不是一个你能依赖的固定值,它跟平台整体负载有关。

怎么确认自己真的命中了:看 usage 里的 cached_tokens

官方给的判断方法很直接:调用 Chat API 做补全时,如果返回的 usage 里存在缓存命中的 token 字段,就表明这次请求命中了缓存,字段的值就是具体命中的 Token 长度。指南页里的示例响应把它放在 usage 对象下,和 prompt_tokenscompletion_tokenstotal_tokens 平级;工具调用、联网搜索、图片对话几篇指南里的示例响应也都是这个位置。

但 API 参考页写的位置不一样。「创建 Chat Completion」的响应说明里,usage 下有一个可选对象 prompt_tokens_detailscached_tokens 挂在它里面,同一层还有一个 completion_tokens_details,里面是 reasoning_tokens。Responses 接口又是第三种写法:usage 下是 input_tokensinput_tokens_details.cached_tokensoutput_tokensoutput_tokens_details(含 reasoning_tokenstool_output_tokens)和 total_tokens

我们没有实际调用过这些接口,无法判断线上到底返回哪一种结构,但对写代码的人来说结论是明确的:解析命中长度时别只认一个路径,顶层和 details 子对象两个位置都取一遍,取不到时按未命中处理,这样官方哪天统一了字段也不会把你的监控打成一片零。

判空要判在哪一层,也值得按文档原文对一遍,别想当然。「创建 Chat Completion」的字段清单里,标着 optional 的是 prompt_tokens_detailscompletion_tokens_details 这两个父对象;父对象里面的 cached_tokensreasoning_tokens 反倒是不带 optional 标记的 int。Responses 页的 input_tokens_details 连 optional 标记都没有。也就是说,可能整个不出现的是那层容器,而不是容器里的数值字段——防御性代码应该先确认 details 对象存在,再往里取值,而不是拿到 details 之后再对 cached_tokens 做一次判空。至于顶层那个 cached_tokens,它只出现在指南页的示例 JSON 里,API 参考页的 usage 字段清单里根本没有列这一项,所以它有没有、什么时候有,文档本身就说不清楚,代码里更要按「取不到是常态」来写。

顺带一提,Anthropic 格式的 Messages 接口那一页,响应说明只写了 usage 至少包含 input_tokensoutput_tokens,缓存相关字段官方文档里没有找到相关说明——如果你走的是那条兼容路径,别默认能读到同样的字段。

什么内容会进缓存

官方列的可缓存内容是四类,范围比「只有纯文本」要宽:

  • 对话信息:完整的对话数组都会进缓存系统,包含 System Prompt、User Message 和 Assistant Message;
  • 图片信息:用户消息里的图片也会进缓存,但要保证前后用的是相同的图片;
  • 视频信息:用户消息里的视频同样可以进缓存,前后也必须是同一个视频;
  • 工具调用信息及其结果:对话里的工具调用信息和调用结果一起参与缓存。

工具调用那条对 Agent 类应用特别有用——多步 Agent 的对话历史里塞满了 tool call 和 tool result,这些内容在下一轮里是一字不变的前缀,正好是缓存最擅长的形态。图片和视频那两条的限定条件要读准:官方说的是「相同的图片/视频」才行,同一张图换个 URL、重新编一次 base64 是不是还算同一份,官方文档里没有明确说明,稳妥做法是在业务侧固定住图片的传入方式。

计费上会发生什么

命中的那部分 Token 不是免费,而是按对应模型费用的一个较低比例计费——官方在指南正文和常见问题里都强调了这一点,具体比例和各模型单价以官方定价页为准,本文不列数字。反过来看,官方定价明细页把输入价格拆成了「缓存未命中」和「缓存命中」两列,也就是说缓存命中率直接决定你的输入侧账单落在哪一列上,这是个结构性的计费设计,不是临时优惠。

要估自己的月成本,顺序是:先用 usage 里的 prompt_tokens 和命中长度算出未命中输入、命中输入、输出三部分的量,再各自乘官方定价页上对应的单价。多模态输入官方另有把图片换算成 Token 的口径,也在计费页上。想在调用前就估长度,平台提供了专门的接口:Chat Completion 格式用 POST /v1/token/count,传 model 和 messages,返回 data.total_tokens;Anthropic 格式用 POST /v1/messages/count_tokens,返回 input_tokens。Anthropic 格式那一节官方写明了「估算 Messages API 输入 token 数量,不生成模型回复」;Chat Completion 格式那一节没有写这句话,但从字段说明看,它的响应体里也只有 data.total_tokens 这一个计数。拿这两个端点去判断「我的固定前缀到底够不够最小缓存单元」,比自己按字数估算靠谱。成本侧的长期监控习惯可以参考API 成本监控怎么做

没命中的排查顺序

官方给了三条排查思路,顺序本身就有讲究:

  1. 确保要缓存的那部分内容在每次调用中都始终保持一致;
  2. 检查两次请求间隔是不是太长,导致缓存已经失效;
  3. 验证输入是否达到了最小 Token 门槛。

第一条被官方排在整个排查顺序的最前面,也和最佳实践那一节的第一条(静态内容放开头、动态内容放结尾)说的是同一件事。System Prompt 里带了当前时间戳、带了随机排序的示例、带了用户昵称,看着都是「几乎一样」,对前缀匹配来说就是第一个字符之后全断。把这类动态量统统挪到 Prompt 尾部,这次改造不涉及任何请求参数,动的只是 messages 数组里内容的排列顺序。

第二条对应前面说的 LRU 逐出:低频调用的场景本来就很难维持住缓存,官方的建议是对较长的 Prompt 尽量放在系统流量非高峰期跑,以减少被逐出的次数。这条建议在批处理类任务上可操作,在实时业务上基本没得选,心里有数即可。

第三条用上面的 token 计数接口验证一次就够,属于一次性排除项。

官方明确回答过的几个边界

常见问题一节里有四问四答,直接决定了你能怎么用它:

  • 缓存会不会影响推理效果:不会,官方说明每次生成都会使用完整的 Prompt 进行推理,缓存省的是重复计算,不是把上下文截短了;
  • 要不要为缓存额外付费:不需要额外付费,命中部分是按较低比例减免后计费,比例见官方定价页;
  • 能不能手动清除缓存:目前不提供手动清除缓存的能力,官方给的变通办法是修改 Prompt 让请求不命中缓存;
  • 能不能保证始终命中:官方明确表示目前不提供保证始终命中的 Prompt 缓存,有这类诉求需要联系官方沟通场景。

第三条和第四条合起来看,含义是这套缓存对使用者是不可控的:你既不能清,也不能钉住。所以任何依赖「缓存一定在」的成本测算都是虚的,做预算时应该按未命中价算上限,把命中当成节省而不是当成基线。

最后:优化动作只有两个

一个是排布——静态在前、动态在后,前缀越长越稳越好;另一个是监控——官方最佳实践里写得很清楚,要盯着不同 Prompt 的 Cached Token 与 Prompt Token 的比重和命中率,用这个比值反过来指导 Prompt 结构。这两件事都不需要改任何请求参数,改的是你怎么组织 messages 数组。想系统性地往上抬这个比值,可以再看缓存命中率怎么优化

动手顺序建议跟着官方文档自身的编排走:先查模型在不在支持范围内,再去调 Prompt 结构。反过来做,前面所有排布优化都不会有任何回报,而 cached_tokens 一直是零这件事本身,是不会主动告诉你原因的。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。