长文场景选模型平台要看哪几件事:缓存、长上下文与超限
数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。
**长文场景(文档问答、长对话 Agent、大段代码库分析)选平台,真正决定成本的不是单价表,而是四个机制细节:缓存是自动生效还是要你显式声明、命中条件有多苛刻、缓存命中的 token 会不会仍然把你顶进长上下文计费档、以及超限时是报错还是被截断。**其中最反直觉的一条是:xAI 在缓存计费一节、MiniMax 在针对 MiniMax-M3 的说明里,都写明了判断是否适用长上下文价格时,缓存命中的 token 也要计入总输入 token——也就是说缓存帮你省了钱,但没帮你降档。这一条如果在估算模型里漏掉,长文业务的月成本会系统性算少。下面按你实际选型时该问的顺序,逐条对照六家官方文档。
一、缓存是自动的,还是要你显式声明
这决定了你的代码要不要为某一家单独改。
智谱 GLM 的上下文缓存文档写的是「隐式缓存,智能识别重复的上下文内容,无需手动配置」,命中量看响应里的 usage.prompt_tokens_details.cached_tokens。但它的计费说明带了一个很容易被忽略的限定:该缓存计费仅适用于标准 API 计费,不包括资源包和 GLM Coding Plan 套餐。你如果是拿编程套餐在跑长文任务,这一节的计费逻辑对你不成立。
Kimi 的 Context Caching 写得更彻底:对所有模型请求自动启用,官方列了三个「无需」——无需手动创建、无需引用缓存 ID、无需管理 TTL,缓存生命周期由系统自动管理。
MiniMax 是唯一把两种缓存做成一张对比表并列摆出来的:被动缓存(自动识别重复内容并缓存)和 Anthropic 主动缓存(在 API 中显式设置 cache_control)。两者的差异不只是写法。计费上,两者命中缓存的 token 都按优惠价格计费,区别在写入侧:被动缓存写入的部分无额外计费,主动缓存首次写入缓存的 token 需要额外计费(具体单价以及它与标准输入价的相对关系,请以官方定价页为准)。过期策略上,被动缓存的过期时间根据系统负载自动调整,主动缓存是固定过期时长、持续使用会自动续期(具体时长以官方文档为准)。
支持模型的清单也不一样,而且差异正好卡在最新一代上:官方对比表里,被动缓存一栏列的是 MiniMax-M3 与 M2.7、M2.5、M2.1 系列,主动缓存一栏列的是 M2.7、M2.5、M2.1、M2 系列——主动缓存那一栏里没有 M3。所以「用 Anthropic 兼容侧显式声明 cache_control 来精细控制缓存」这个做法,对你想用的那个具体型号成不成立,得先回官方表里查一遍,不能默认全系通用。长文场景下这两组差异会直接改变你的调用节奏——主动缓存写入要额外花钱,就意味着「写了不用」是纯亏损。
顺带澄清一个常见误解:缓存是自动生效还是需要主动声明,取决于你有没有在请求里显式设置 cache_control,不取决于你打的是哪一套兼容端点。MiniMax 讲被动缓存那一页的代码示例里,同时给了 Anthropic SDK 和 OpenAI SDK 两个标签页——也就是说走 Anthropic 兼容侧照样能吃到自动的被动缓存。所以「打 OpenAI 端点就是自动缓存、打 Anthropic 端点就是主动缓存」这种二分法是错的,别照着它去分流量。
Gemini 同样是隐式与显式两套并存,隐式缓存对 2.5 及更新型号默认启用,命中后自动返还节省的费用。这里有个接口选型坑:Interactions API 只支持隐式缓存,要用显式缓存必须改用 generateContent API。
xAI 的 Grok 走自动前缀缓存,但官方额外建议设置 x-grok-conv-id 请求头(Responses API 对应请求体里的 prompt_cache_key),作用是把同一会话的请求路由到同一台服务器——因为缓存条目是按服务器存的。
阶跃星辰这一条要特别注意:官方文档明确列出了支持 Prompt 缓存的模型名单,并写着「其他模型暂时不支持 Prompt 缓存」。不是全系模型都有缓存,这在选型时属于硬约束。
二、命中条件:写法不同,指向的是同一件事
六家的措辞不一样,落到工程上是同一个要求——前缀必须稳定。
Grok 说得最直白:缓存从 messages 数组的开头开始匹配,系统检查开头有多少条消息与之前的请求完全一致,那一段就是可复用的前缀。任何对早期消息的编辑、删除、重排都会打断缓存,只能往后追加。对推理模型还有一条附加要求:必须把上一轮响应里的 reasoning_content 一起回传。官方在这条上用的是加粗的强制语气(must),并明确把「遗漏它」和缓存未命中直接挂钩,还专门另起一条讲要把加密的推理内容原样发回去。按官方描述的这套机制推下去,回传 reasoning_content 影响的不是模型这一轮能不能答对,而是前缀能不能对上、进而决定这段输入按哪个价格计费——这也是它容易被漏掉的原因。
MiniMax 把前缀的构成顺序写出来了:以「工具定义-系统提示词-历史对话内容」为顺序构建,任意模块内容的变更都可能影响缓存效果。这意味着你动态增删工具定义的代价,比你想象的大——工具清单在最前面,它一变,后面全废。
阶跃星辰补了缓存的淘汰策略:采用最近最少使用(LRU)逐出,系统请求高峰期不用的缓存更容易被逐出,低峰期则拥有更长的生命周期;官方由此给出的建议是较长的 Prompt 尽量放在非高峰期跑。GLM 那边的提法是「轻微的格式差异可能影响缓存效果」「缓存有合理的时效性,过期后会重新计算」。Gemini 官方给的提高命中率方法是把较大且常见的内容放在提示开头,并在短时间内发送具有相似前缀的请求。
还有一条共性:几家都设了最小 token 门槛。Kimi、阶跃星辰、MiniMax 各自在文档里写了输入长度不到某个门槛就不会命中或不会被缓存,Gemini 的隐式缓存也有最低输入 token 门槛且门槛因模型而异(具体数值以各家官方文档为准)。结论很简单:碎片化的小请求别指望缓存,缓存是给长前缀准备的。命中率具体怎么调,可以看六家缓存机制的横向对照和缓存计费的通用机制。
三、缓存命中了,档位不一定降
这是长文场景最该单独拎出来的一条。
xAI 文档在缓存计费那一节写着:当总 prompt token(包括缓存命中的 token)超过模型的长上下文门槛时,适用长上下文定价,缓存与非缓存 token 各自按对应的长上下文费率计。MiniMax 的说法一致,但要注意它的限定范围——官方原文是针对 MiniMax-M3 写的:请求输入 token 大于某个门槛时适用长上下文价格,输入 token 包含缓存命中 token(门槛数值以官方定价页为准)。这是一条挂在具体型号下的规则,不要直接当成 MiniMax 平台级的通用条款,换型号时得回官方页面重新确认。
需要说清楚的是,六家里只有 xAI 与 MiniMax 把这条规则写进了文档,GLM、Kimi、Gemini、阶跃星辰四家的文档里没有找到对应说明。所以别把它当成行业通行口径去套所有平台,而应该按各家自己的定价页逐一核。但只要你要用的平台确实是这么定的,它带来的后果就是:你不能拿「缓存之后的等效输入量」去判断自己落在哪个价格档。一个把整份手册塞进 system 消息、每轮只追加一句提问的文档问答应用,即使缓存命中率很高,仍然会一直待在长上下文档位里。
Gemini 这边还有一层结构性差异:官方 FAQ 把计费依据列为四项——输入 token 数、输出 token 数、缓存的 token 数、缓存 token 的存储时长。也就是说显式缓存的存储本身按时长计费,长上下文的主要优化手段是把上传的文件缓存起来、为存储付费换重复提问时的输入成本下降。对比一下就清楚了:MiniMax 的被动缓存写明写入部分无额外计费,只有命中的 token 按优惠价计;Gemini 这套里,存储时长本身就是一项独立的计费依据。两种结构做成本模型时不能套同一个公式,Gemini 这条要单独留一项,而且这项跟你的请求频率有关——缓存放着不问,时长照走。
四、发出去之前,能不能先把 token 数算准
长文场景里「这一发到底多少 token」不该靠估。六家都提供了独立的计数入口:
- Kimi:
POST /v1/tokenizers/estimate-token-count,传 model 和 messages - 智谱 GLM:
POST /paas/v4/tokenizer,官方说明的适用场景是文本长度评估、模型输入预估、对话上下文截断、费用计算 - 阶跃星辰:分成两个端点。Chat Completion 格式走
POST /v1/token/count,Messages 格式走的是另一个地址POST /v1/messages/count_tokens;官方还说明了用 Anthropic SDK 时把 base_url 设成https://api.stepfun.com,SDK 会自动拼上/v1/messages/count_tokens,不用手动带/v1。选错端点是这一条最容易踩的坑 - MiniMax:
POST /v1/responses/input_tokens,官方描述是「不真正调用模型生成,常用于在调用主接口前评估请求成本与是否触发上下文长度上限」 - xAI 的 Grok:
POST /v1/tokenize-text,请求体收model和text,返回一个 token 列表,每项带token_id、string_token和token_bytes。注意它收的是一段纯文本而不是 messages 数组,所以要算整轮对话的输入量,得自己先把消息拼成文本 - Gemini:token 计数方法为
GenerativeModel.count_tokens
这里顺带提醒一句:Grok 的常见问题专门列了一条「API 实际消耗的 prompt token 与控制台 Tokenizer 或 tokenize 端点算出的数不一致」,官方给的解释是推理端点会为处理请求额外加入一些预置 token,这部分也会计入总的 prompt token 消耗。所以计数接口的结果是个下限量级:判断「会不会撞上限」「大概落在哪一档」够用,拿它去逐笔对账则对不上。
再注意 MiniMax 那句官方描述里的第二个用途——判断是否触发上下文长度上限。这正是长文场景该有的前置动作:先算,再决定是发、是拆、还是先压缩。Kimi 的 token 预估接口怎么用有更细的说明。
五、超限时是怎么失败的
Kimi 的错误列表里,与长度相关的是两条 400 invalid_request_error:一条是 Input token length too long,官方给的原因是输入 token 超过模型最大上下文限制,处置是缩短输入或换用更大上下文的模型;另一条是 prompt tokens + max_tokens 超过模型规格,处置是减小 max_tokens 或换模型。第二条尤其容易被忽略——你为输出预留的预算也占上下文额度,长文请求里把 max_tokens 开得很大,是在自己挤自己。
阶跃星辰的错误码表里,除了常规的 400/401/429,还单列了一组组织额度错误码:402 insufficient_credit(组织 Credit 余额不足)、429 project_credit_limit_exceeded(项目达到当期 Credit 上限)、429 member_project_credit_limit_exceeded(成员在该项目内达到当期上限)。官方特意提示其中两种情况的错误码与速率限制相同,请以错误标识区分。长文任务单次消耗的 Credit 本来就比普通对话多,这三个额度类错误在这种业务里值得单独留一个处理分支:排查时先看错误标识,别把额度型 429 当成限流去做退避重试——退避再久,额度也不会自己回来。
Gemini 官方给 429 的处置里,除了等待重试和申请提额,还包含一条「降低高费用请求的速率,比如用更小的上下文窗口或更短的输出」——这是把长文本身当成限流成因来处理的思路。各家 429 的通用处理可以参考429 该怎么处理。
六、长对话撑不住时,有没有官方的压缩出口
Grok 提供了一个专门的上下文压缩接口 POST /v1/responses/compact:把要压缩的对话发过去,响应返回一个 compaction item,它可以代替整段历史对话,你把原始消息从客户端状态里丢掉,用这个 item 作为下次请求的开头,再追加新的用户消息。官方保留的信息包括系统提示词、附件、先前的推理内容和对话记录的压缩版本,丢掉的是冗长的工具输出和来回对话。
有两条官方说明必须一起记住:其一,encrypted_content 要当作不透明内容处理,不要解析或修改,可以存进自己的数据库、原样回传,它只有发回 xAI API 时才有意义;其二,官方明确列出的压缩前提之一是「当前窗口仍在模型上下文上限之内」——压缩只能缩小对话,救不了一个已经超限的请求。这条边界很重要,别把 compaction 当成超限兜底方案。
七、文档是塞进上下文,还是走检索
这一步的取舍,Kimi 和 Gemini 的官方文档都给了正面回答,而且都很克制。
Kimi 把 Context Caching 和 RAG 做了对照:研发成本上,Context Caching 相对较低,系统自动处理缓存、无需额外接入或调优;RAG 相对较高,需要 RAG 与 Embedding 结合并持续做业务定制化调优。成本降幅上,Context Caching 与业务特性高度相关,RAG 则与业务特性无关,但召回精度问题可能导致回答准确率下降。RAG 的额外优势是原始文本长度可以扩展到非常长。官方给的建议是:频繁查询固定内容(如 FAQ、文档问答)优先用 Context Caching;内容极长且查询方向不固定时,可以考虑 RAG。
Gemini 那边则给了一段关于长上下文检索能力边界的说明:「大海捞针」类评估是最基本的设置——只找一根针;要找多根针或特定信息时,准确率会变化,性能可能因上下文而变化很大。官方还直接点出检索准确率与费用之间存在固有权衡:要在单次查询上拿到很高的准确率,代价是每次都付全量输入 token 的费用;要检索大量条目并同时保持高准确率,可能得发很多次请求。官方 FAQ 给的三条实操结论是:把查询/问题放在提示的末尾(在所有其他上下文之后),不需要传给模型的 token 就别传,有一组要重复使用的相似上下文时用上下文缓存降本。
如果选「塞进上下文」这条路,Kimi 的文件问答给了完整机制:用 files.create(file=..., purpose="file-extract") 上传,再用 files.content(file_id=...) 取回抽取后的文本,然后把文件内容(官方在注释里特意强调是文件内容,不是文件 ID)作为一条 system 消息放进 messages;多个文件就是每个文件单独放进一条 system 提示词里,官方原话是「将每个文件单独放置在一个系统提示词 system prompt 中即可」。位置上,同一篇文档的示例代码注释里写了一句推荐:把上传函数返回的这批 messages 放置在 messages 列表的头部。这个建议正好和前面讲的前缀稳定策略对得上——文件内容既然是整轮对话里最长又最不变的那一段,放在最前面才能被当成可复用前缀。
如果选「走检索」,智谱在知识库侧提供了「上下文增强」检索:为每个知识切片自动生成一份上下文描述并与原始文本绑定、共同参与检索,官方列出这份描述通常包含来源信息、主题概括、关键实体、歧义消除和风格保持,用来解决切片脱离原文结构后丢失上下文的问题。
最后:把这几件事变成一次可执行的选型
按顺序过一遍就够了:先确认你要用的那个具体模型在目标平台上支不支持缓存(阶跃星辰这一条是硬门槛),再确认你的套餐形态适不适用缓存计费口径(GLM 的资源包与编程套餐不在此列),然后用各家的 token 计数接口把典型请求的输入量算出来、对照长上下文门槛判断落在哪一档——记得把缓存命中的 token 一起算进去,最后把超限与额度两类错误的处置分支写进代码。
最容易栽的坑是只盯着缓存命中率。命中率高只说明前缀设计得好,它既不改变你所处的计费档位,也不改变长上下文检索准确率与费用之间那个官方承认的权衡。真正该盯的是这三件事一起看:命中率、档位、以及每次追问实际新增了多少 token。