模型token缓存命中 vs 缓存未命中?
一、先说清楚缓存命中 vs 缓存未命中1.1 一句话说清楚大模型处理你的请求时主要成本在计算而不是“读取”。如果这次请求的前缀内容和之前某次请求一模一样平台就不用从头再算一遍而是复用之前保存下来的中间结果。缓存命中Cache Hit你的请求前缀已经被处理过并缓存了 → 直接复用 →便宜 快缓存未命中Cache Miss你的请求前缀没被处理过 → 从头计算 →贵 慢1.2 价格差距有多大用真实数据说话以DeepSeek V4 Flash为例平时价格类型百万Token价格备注输入缓存命中0.02元便宜到几乎可以忽略输入缓存未命中1元是命中价格的50倍输出2元输出无法缓存再看DeepSeek V4 Pro类型百万Token价格输入缓存命中0.025元输入缓存未命中3元输出6元差距有多大同样是100万Token的输入命中缓存只要2分钱没命中要3块钱——差了120倍。缓存命中的价格通常是未命中的十分之一到百分之一具体取决于模型和厂商。1.3 缓存命中 vs 未命中一张图看懂二、模型是怎么判断缓存是否命中的——命中逻辑架构2.1 核心原则精确前缀匹配Exact Prefix Match所有主流模型的缓存判断逻辑都遵循同一个核心原则缓存命中要求两次请求的“前缀”在字节级别完全一致。“完全一致”的意思是——哪怕多一个空格、改一个标点缓存都可能失效。2.2 三步判断流程整个缓存判断过程可以分为三步2.3 不同厂商的缓存实现差异OpenAI内存缓存 扩展缓存OpenAI的缓存机制自动开启所有API请求自动启用无需改代码触发条件提示词至少1024个Token才会触发缓存命中单位以128个Token为增量进行缓存命中缓存时长内存缓存5-10分钟不活跃即失效最长1小时扩展缓存最长24小时路由机制基于前缀哈希值路由到特定机器DeepSeek硬盘缓存全球首创DeepSeek采用硬盘缓存技术是全球第一家在大范围API服务中采用硬盘缓存的大模型厂商默认开启所有用户默认享受无需修改代码缓存落盘时机有三种请求边界落盘每次请求结束位置产生缓存单元公共前缀检测落盘多次请求检测到公共前缀时独立落盘固定Token间隔落盘长输入按固定间隔截取缓存匹配规则后续请求必须完整匹配缓存前缀单元才能命中查看命中返回的usage字段包含prompt_cache_hit_tokens和prompt_cache_miss_tokens阿里云显式缓存 vs 隐式缓存阿里云提供两种模式模式特点命中价格隐式缓存自动系统自动识别公共前缀无需配置输入单价的20%显式缓存手动主动创建缓存块确定性高输入单价的10%显式缓存需要主动添加cache_control标记{ role: system, content: [ {type: text, text: 这里放长文本..., cache_control: {type: ephemeral}} ] }2.4 为什么说“缓存命中的判断是精确匹配”来看DeepSeek官方文档的两个例子例1能命中第一次请求A B第二次请求A B C → 完整匹配 AB → ✅ 命中例2第一次不能命中但后续可以第一次请求A B第二次请求A C → 不能完整匹配 AB → ❌ 未命中→ 但系统检测到公共前缀 A把它缓存了第三次请求A D → 完整匹配 A → ✅ 命中关键洞察缓存是动态学习的。即使某次没命中系统也会从失败中提取公共前缀为后续请求创造命中机会。三、怎么判断你的请求是否命中了缓存3.1 查看API返回的usage字段大多数模型API会在返回中告诉你缓存命中情况。DeepSeek API返回示例{ usage: { prompt_tokens: 1500, prompt_cache_hit_tokens: 1200, // ← 命中了1200个Token prompt_cache_miss_tokens: 300, // ← 没命中300个Token completion_tokens: 200, total_tokens: 1700 } }计费公式费用 命中Token数 × 命中单价 未命中Token数 × 未命中单价 输出Token数 × 输出单价3.2 VSCode代码解析缓存命中情况import requests import json def call_with_cache_check(prompt, api_key, modeldeepseek-chat): 调用API并检查缓存命中情况 url https://api.deepseek.com/v1/chat/completions headers { Authorization: fBearer {api_key}, Content-Type: application/json } data { model: model, messages: [ {role: system, content: 你是一个乐于助人的助手}, {role: user, content: prompt} ] } response requests.post(url, headersheaders, jsondata) result response.json() # 提取缓存命中信息 usage result.get(usage, {}) hit_tokens usage.get(prompt_cache_hit_tokens, 0) miss_tokens usage.get(prompt_cache_miss_tokens, 0) total_prompt usage.get(prompt_tokens, 0) # 计算命中率 if total_prompt 0: hit_rate (hit_tokens / total_prompt) * 100 else: hit_rate 0 print(f 缓存命中统计:) print(f - 命中Token: {hit_tokens}) print(f - 未命中Token: {miss_tokens}) print(f - 总输入Token: {total_prompt}) print(f - 命中率: {hit_rate:.1f}%) # 估算费用以DeepSeek V4 Flash为例 hit_price 0.02 / 1_000_000 # 0.02元/百万Token miss_price 1.0 / 1_000_000 # 1元/百万Token cost hit_tokens * hit_price miss_tokens * miss_price print(f - 预估费用: {cost:.6f}元) return result # 使用示例 # 第一次调用构建缓存 result1 call_with_cache_check(中国的首都是哪里, your-api-key) # 第二次调用相同前缀应该命中缓存 result2 call_with_cache_check(中国的首都是哪里请详细介绍一下, your-api-key)代码解析prompt_cache_hit_tokens命中的Token数按低价计费prompt_cache_miss_tokens未命中的Token数按高价计费命中率 命中Token ÷ 总输入Token四、怎么提高缓存命中率——实战技巧4.1 黄金法则稳定的放前面变化的放后面这是最核心、最有效的一条原则❌ 错误做法动态内容在前[当前时间: 2026-07-07 10:30] [系统提示词] [用户问题]→ 时间每分每秒都在变 → 缓存永远失效✅ 正确做法稳定内容在前[系统提示词] [工具定义] [项目规则] [用户问题]→ 前三项长期不变 → 缓存持续命中对于Coding Agent来说请求结构通常是这样[tools] 工具定义 ← 长期稳定[system prompt] 系统提示 ← 长期稳定[project rules] 项目规则 ← 长期稳定[conversation history] ← 相对稳定追加内容[tool results] 工具结果 ← 每轮不同[new user message] 继续 ← 真正新增的只有这几个字越稳定越靠前缓存越管用越动态越靠前缓存越容易废。4.2 避免动态内容破坏缓存以下内容只要出现在请求前缀位置就会破坏缓存命中动态内容为什么破坏缓存当前时间戳每分每秒都在变随机Request ID每次请求都不同重排过的工具列表顺序一变前缀就变了动态拼接的System Prompt每次可能多一句话解决方案把这些动态内容放到请求的最后面不要放在开头。4.3 使用缓存KeyOpenAIOpenAI提供了prompt_cache_key参数可以手动控制路由# 相同cache_key的请求会被路由到同一台机器 response client.chat.completions.create( modelgpt-4o, messagesmessages, prompt_cache_keymy-app-v1 # ← 手动指定缓存Key )这样即使前缀略有不同只要prompt_cache_key相同请求也会被路由到同一台机器提高命中概率。4.4 多轮对话中保持上下文连贯在多轮对话中把历史对话放在前面新问题放在最后# ✅ 好的做法历史在前新问题在后 messages [ {role: system, content: system_prompt}, # 稳定 {role: user, content: 第一轮问题}, # 已固化 {role: assistant, content: 第一轮回答}, # 已固化 {role: user, content: 第二轮问题}, # 已固化 {role: assistant, content: 第二轮回答}, # 已固化 {role: user, content: 新问题} # ← 只有这个是新增的 ]前面的内容因为已经处理过并被缓存新增的只有最后一小段大部分Token都能命中缓存。五、总结一张表看懂全部维度缓存命中缓存未命中发生了什么复用之前计算好的中间结果从头开始计算价格极低通常为未命中的10%-20%正常价格速度快首Token延迟降低80%慢DeepSeek V4 Flash0.02元/百万Token1元/百万TokenDeepSeek V4 Pro0.025元/百万Token3元/百万Token判断方式请求前缀精确匹配缓存请求前缀没有匹配项命中条件稳定内容在前 动态内容在后动态内容破坏了前缀匹配小编建议检查API返回的usage字段看prompt_cache_hit_tokens和prompt_cache_miss_tokens知道自己到底命中率多少重排你的Prompt结构稳定内容放前面动态内容放后面避免在请求前缀插入时间戳、随机ID这些会让缓存完全失效多轮对话中保持历史上下文顺序新问题追加在最后善用缓存Key如有把相同类型的请求路由到同一台机器小编团队自主研发 大型文件翻译、润色文本链接https://blog.csdn.net/weixin_54524403/article/details/162078447?spm1011.2415.3001.10575sharefrommp_manage_linkhttps://blog.csdn.net/weixin_54524403/article/details/162078447?spm1011.2415.3001.10575sharefrommp_manage_link