MiniMax 的 Prompt 缓存怎么用:命中条件与字段怎么查

2026-08-25

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

MiniMax 的 Prompt 缓存是「被动缓存」:官方文档写得很明确,它自动识别重复的上下文内容,无需更改接口调用方式。也就是说你不加任何参数它也在工作,你要做的不是「打开它」,而是三件事——把 prompt 排成它认得出的形状、确认输入量过得了它的最小门槛、从 usage 字段里读出到底命中了多少。另外还有一个很容易踩的分界:MiniMax 文档里有两套缓存,一套是这里说的自动 Prompt 缓存,另一套是走 Anthropic 兼容接口、要显式写 cache_control 的「主动缓存」。两者的过期方式、写入是否额外计费、支持的模型范围都不一样,把主动缓存那一页的规则往自动缓存上套,是最常见的误判来源。

先分清:MiniMax 有两种缓存,你现在用的是哪种

官方在 Prompt 缓存那一页里直接给出了命名口径:自动识别重复上下文、不用改调用方式的那种叫自动缓存(也就是被动缓存);而在 Anthropic API 中使用的、需要显式设置参数的缓存模式,官方称之为主动缓存。这两个词是官方自己定的,不是社区叫法,读文档的时候看到「主动/被动」不要以为是同一件事的两种说法。

文档末尾那张 Cache 对比表把差别列得很清楚,其中有三条差异值得单独拎出来:

  • 使用方式:被动缓存是自动识别重复内容并缓存;主动缓存要在 API 里显式设置 cache_control
  • 计费方式:两者命中缓存的 token 都按优惠价格计费,但被动缓存写入缓存的部分无额外计费,主动缓存首次写入缓存的 token 需要额外计费。这条差异的实际含义是:如果你的前缀复用次数不多,主动缓存的写入成本可能吃掉一部分收益,而被动缓存在这一点上没有这个顾虑。
  • 缓存过期:被动缓存是根据系统负载自动调整过期时间,主动缓存则是一个固定的过期时长、持续使用会自动续期(具体时长以官方文档当前版本为准)。

「根据系统负载自动调整过期时间」这句话的分量比看上去大。它意味着被动缓存的存活时间不是一个你可以写进程序里的常量,你没法按「几分钟内一定还在」来设计调度节奏,只能按「命中了就赚到、没命中也别崩」来写代码。想要一个可预期的过期语义,那要走的是主动缓存那条路。

还有一条容易被忽略的:官方对比表里两种缓存的支持模型并不是同一份名单——被动缓存那一列里有 MiniMax-M3,主动缓存那一列里没有;反过来主动缓存那一列多了更早的 M2 系列。所以「我换个模型再显式加个 cache_control 就行了」这个假设不一定成立,名单请以官方文档当前版本为准。

命中条件:前缀匹配,加一道最小输入量门槛

官方在「注意事项」里只给了两条,但这两条基本决定了你能不能命中。

第一条是输入量门槛。 缓存只对输入 token 数量达到官方门槛及以上的 API 调用生效,具体数值官方文档里写了,这里不复述(以官方文档当前版本为准)。它的实际后果是:短问答类的请求,就算你每次都带同一段系统提示词,也可能整体没到门槛,从头到尾一次都不会命中。所以看到 usage 里缓存 token 一直是 0 的时候,先别怀疑功能坏了,先看看自己的请求是不是根本就太短了。

第二条是前缀匹配。 官方的原话是缓存采用前缀匹配的方式,以「工具定义-系统提示词-历史对话内容」为顺序构建,任意模块内容的变更,都可能会影响缓存的效果

这句话要拆成两层理解。第一层是顺序:三块内容有先后关系,工具定义在最前,系统提示词次之,历史对话内容在后。第二层是「前缀」这个词的含义:匹配是从头开始往后比的,前面的内容一旦变了,后面所有内容跟着一起失效——哪怕后面那部分你一个字都没动。

于是就有了实践里最反直觉的一条:在工具清单里加一个新工具,代价不只是多出来的那点工具定义 token,而是整段系统提示词和历史对话的缓存可能一起作废。 因为工具定义排在最前面,它变了,后面的前缀就对不上了。同理,如果你在系统提示词里塞了当前时间戳、请求 ID、用户昵称这类每次都不一样的东西,那这段前缀基本永远命中不了。

官方给的最佳实践:静态在前,动态在后

文档的「最佳实践」只有两条,第一条是:在对话的开头部分放置静态的或重复的内容(包括工具定义、系统提示词、历史对话内容),把动态的用户信息放在对话的最后,以最大程度利用 cache。

这条建议配合前缀匹配规则看就很好理解了——你唯一能控制的变量是「变化点出现在多靠后的位置」。变化点越靠后,前面能被复用的前缀就越长。所以工程上真正该做的是给 prompt 做一次分层体检:把每一段内容按「多久变一次」排序,永远不变的放最前,一天变一次的放中间,每次请求都变的放最后。很多人写 prompt 是按人类阅读的逻辑顺序排的,那个顺序对缓存往往是最差的。

官方点名的三类适用场景也印证了这个思路:系统提示词复用(多轮对话中系统提示词通常保持不变)、固定的工具清单(一类任务里用的工具往往是固定的)、多轮对话历史(复杂对话中历史消息包含大量重复信息)。三类的共同点都是「有一大段东西在多次请求之间原样不动」。

怎么确认真的命中了:两套 SDK 读的不是同一个字段

最佳实践的第二条是:通过 API 返回的 usage tokens 数量来监测缓存性能,定期分析以优化使用策略。这句话很容易一带而过,但它其实是这整套机制里唯一的可观测入口——被动缓存没有开关、没有回执、没有单独的状态码,你只能从 usage 里看。

麻烦在于,MiniMax 同时提供 OpenAI 兼容和 Anthropic 兼容两套接口,这两套返回的缓存字段名完全不同,文档里是分两个 Tab 给的:

  • Anthropic 兼容那一路,示例里读的是 response.usage.cache_read_input_tokens,响应 usage 里还同时有 cache_creation_input_tokensinput_tokensoutput_tokens
  • OpenAI 兼容那一路,示例里读的是 usage.prompt_tokens_details.cached_tokens,同级还有 prompt_tokenscompletion_tokenstotal_tokens

官方的 OpenAI 示例甚至专门写成了 response.usage.prompt_tokens_details.cached_tokens if hasattr(response.usage, 'prompt_tokens_details') else 0 这种带兜底的形式,说明这个字段在 SDK 对象上并不总是存在。如果你的成本统计代码是从别家平台照搬过来的,很可能取字段的路径就是错的,取不到又被兜底成 0,最后得出「MiniMax 缓存不生效」的结论——但真实原因只是字段名对不上。

顺带说一句,官方 OpenAI 示例里还带了一个 extra_body={"reasoning_split": True} 的参数,注释写的是把思考内容分离到 reasoning_details 字段。这个跟缓存没关系,别把它当成开缓存的开关。

两套接口的环境变量也不一样:Anthropic 那一路配的是 ANTHROPIC_BASE_URLANTHROPIC_API_KEY,OpenAI 那一路配的是 OPENAI_BASE_URLOPENAI_API_KEY。另外这一页对 base url 的写法本身有个细节值得注意:说明文字给的是国内用 https://api.minimaxi.com/v1、国际用 https://api.minimax.io/v1,而 Anthropic Tab 下面那行 export 示例写的是 https://api.minimaxi.com/anthropic。也就是说 Anthropic 兼容那一路的路径后缀跟 OpenAI 那一路不是同一个,照着上面那句说明去配 Anthropic SDK 大概率会走偏,以代码示例里那一行为准。想把整条接入链路走完的,可以配合看用 Anthropic SDK 接入 MiniMax 的官方接法

计费口径:命中的 token 便宜了,但没有从输入量里消失

计费部分官方给的是三条差异化规则:缓存命中的 token 按优惠价格计费,新增的输入 token 按标准输入价格计费,输出 token 按标准输出价格计费。单价一律看官方的按量计费价格页,这里不列。

真正需要记住的是另一句,它藏在计费示例后面,很容易被跳过:对 MiniMax-M3,请求输入 tokens 超过官方规定的分界时适用长上下文价格,而输入 tokens 是包含缓存命中 tokens 的。

这句话的后果是:缓存命中只改变了这部分 token 的单价档位,没有把它们从「输入总量」里扣掉。所以一个长前缀的请求,哪怕前缀全部命中缓存,它在判断是否进入长上下文价格档时,仍然按包含缓存命中在内的完整输入量来算。如果你原本的估算逻辑是「命中的部分不算输入量,那我的请求就永远进不了长上下文档」,那这个估算会在账单上出偏差。这也是为什么成本模型不能只盯着命中率,还得盯着输入总量本身的分布,思路可以参考提示缓存计费结构的通用拆法API 成本监控的三层结构

别把主动缓存的规则套到自动缓存上

这是本文开头就点过、但值得再说一遍的坑。MiniMax 的 Anthropic 主动缓存页里有一批很具体的规则,比如缓存前缀按 toolssystemmessages 的顺序创建、每一级的更改会使该级及所有后续级别失效、系统在每个显式缓存断点之前只会往前检查有限个内容块、一次调用能生效的 cache_control 数量有上限且超出时只保留靠后的若干个(具体数值以官方文档当前版本为准)。

这些规则是写在主动缓存那一页上的,前提是你用了显式的 cache_control 断点。自动的 Prompt 缓存那一页并没有给出断点、回溯窗口、断点数量上限这些概念——它给的就是前缀匹配和最小输入量门槛两条。把「断点数量上限」之类的说法安到自动缓存头上去解释「为什么没命中」,方向从一开始就错了。

同样地,主动缓存的字段口径是 cache_creation_input_tokens + cache_read_input_tokens + input_tokens 三者相加等于总输入 token,其中 input_tokens 指的是最后一个缓存断点之后的部分。这个「断点之后」的定义只在有显式断点的语境下成立。

排查顺序:从便宜到贵

缓存 token 一直是 0 的时候,按这个顺序查,能少走弯路:

  1. 看请求够不够长。输入 token 没到官方门槛,缓存根本不参与,这一条排在最前面是因为它最省事。
  2. 看字段取对了没。OpenAI 兼容和 Anthropic 兼容两套的缓存字段名不一样,取错了会静默变成 0。
  3. 看前缀有没有被污染。系统提示词或工具定义里有没有混进时间戳、随机 ID、每次都变的用户上下文;工具清单最近有没有增删过——工具定义排在最前,它一动,后面全塌。
  4. 看动态内容的位置。用户输入是不是被放到了前面而不是最后。
  5. 看间隔。被动缓存的过期时间由系统负载自动调整,两次请求隔得久了本来就可能失效,这个不归你控制。
  6. 确认模型在支持名单里。两种缓存的支持模型不是同一份名单,换模型之前先回官方文档核一眼。

最后提醒一句边界:本文所有结论都来自 MiniMax 官方文档的 Prompt 缓存页与 Anthropic 主动缓存页,我们没有跑过这些接口,也不对响应速度、命中率的实际表现做任何描述。文档里没写的东西——比如被动缓存在多长时间内一定还在、缓存是否按 API Key 隔离——官方文档里没有找到相关说明,请不要凭其他平台的经验去补。跨平台迁移时这类隐含假设最容易带错,可以先过一遍换厂商前的迁移检查清单

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