LiteLLM 与 Redis 响应缓存机制:从精确哈希匹配到模型底层 KV-Cache 边界

LiteLLM 与 Redis 响应缓存机制:从精确哈希匹配到模型底层 KV-Cache 边界

在大语言模型(LLM)网关与中间件的架构设计中,缓存是降低调用成本与响应延迟的核心手段。很多刚接触 LiteLLM 或相关网关方案的工程师容易产生一种误解,认为在网关层挂载 Redis 就能实现类似大模型服务商那样的"部分 Token 命中打折"效果。

实际上,网关层缓存与模型推理层缓存工作在完全不同的系统层次。LiteLLM 配合 Redis 实现的是基于请求特征的精确响应缓存(Exact Response Cache) ,而像 Google Gemini、OpenAI 或私有部署 vLLM 中的"部分 Token 缓存",依靠的是模型显存中的 KV-Cache 前缀复用(Prefix Caching)

本文深入梳理 LiteLLM 与 Redis 的缓存交互流程、Key/Value 内部数据结构、跨模型隔离逻辑,并详细剖析网关层与推理层在缓存机制上的物理边界。


1. LiteLLM + Redis 响应缓存的核心工作流

LiteLLM Proxy 作为 API 网关,本身是一个基于 Python/FastAPI 的无状态中间件。当我们在 config.yaml 中配置 type: redis 并启用 cache: true 时,LiteLLM 会接管所有 Redis 连接池与读写生命周期,无需编写额外的应用层读写代码。

1.1 请求处理生命周期

整个调用与缓存拦截的数据流向如下图所示:
#mermaid-svg-m2iPKq2bq4o4McLJ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-m2iPKq2bq4o4McLJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-m2iPKq2bq4o4McLJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-m2iPKq2bq4o4McLJ .error-icon{fill:#552222;}#mermaid-svg-m2iPKq2bq4o4McLJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-m2iPKq2bq4o4McLJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-m2iPKq2bq4o4McLJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-m2iPKq2bq4o4McLJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-m2iPKq2bq4o4McLJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-m2iPKq2bq4o4McLJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-m2iPKq2bq4o4McLJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-m2iPKq2bq4o4McLJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-m2iPKq2bq4o4McLJ .marker.cross{stroke:#333333;}#mermaid-svg-m2iPKq2bq4o4McLJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-m2iPKq2bq4o4McLJ p{margin:0;}#mermaid-svg-m2iPKq2bq4o4McLJ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-m2iPKq2bq4o4McLJ .cluster-label text{fill:#333;}#mermaid-svg-m2iPKq2bq4o4McLJ .cluster-label span{color:#333;}#mermaid-svg-m2iPKq2bq4o4McLJ .cluster-label span p{background-color:transparent;}#mermaid-svg-m2iPKq2bq4o4McLJ .label text,#mermaid-svg-m2iPKq2bq4o4McLJ span{fill:#333;color:#333;}#mermaid-svg-m2iPKq2bq4o4McLJ .node rect,#mermaid-svg-m2iPKq2bq4o4McLJ .node circle,#mermaid-svg-m2iPKq2bq4o4McLJ .node ellipse,#mermaid-svg-m2iPKq2bq4o4McLJ .node polygon,#mermaid-svg-m2iPKq2bq4o4McLJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-m2iPKq2bq4o4McLJ .rough-node .label text,#mermaid-svg-m2iPKq2bq4o4McLJ .node .label text,#mermaid-svg-m2iPKq2bq4o4McLJ .image-shape .label,#mermaid-svg-m2iPKq2bq4o4McLJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-m2iPKq2bq4o4McLJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-m2iPKq2bq4o4McLJ .rough-node .label,#mermaid-svg-m2iPKq2bq4o4McLJ .node .label,#mermaid-svg-m2iPKq2bq4o4McLJ .image-shape .label,#mermaid-svg-m2iPKq2bq4o4McLJ .icon-shape .label{text-align:center;}#mermaid-svg-m2iPKq2bq4o4McLJ .node.clickable{cursor:pointer;}#mermaid-svg-m2iPKq2bq4o4McLJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-m2iPKq2bq4o4McLJ .arrowheadPath{fill:#333333;}#mermaid-svg-m2iPKq2bq4o4McLJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-m2iPKq2bq4o4McLJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-m2iPKq2bq4o4McLJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-m2iPKq2bq4o4McLJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-m2iPKq2bq4o4McLJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-m2iPKq2bq4o4McLJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-m2iPKq2bq4o4McLJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-m2iPKq2bq4o4McLJ .cluster text{fill:#333;}#mermaid-svg-m2iPKq2bq4o4McLJ .cluster span{color:#333;}#mermaid-svg-m2iPKq2bq4o4McLJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-m2iPKq2bq4o4McLJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-m2iPKq2bq4o4McLJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-m2iPKq2bq4o4McLJ .icon-shape,#mermaid-svg-m2iPKq2bq4o4McLJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-m2iPKq2bq4o4McLJ .icon-shape p,#mermaid-svg-m2iPKq2bq4o4McLJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-m2iPKq2bq4o4McLJ .icon-shape .label rect,#mermaid-svg-m2iPKq2bq4o4McLJ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-m2iPKq2bq4o4McLJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-m2iPKq2bq4o4McLJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-m2iPKq2bq4o4McLJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1. POST /v1/chat/completions
2. 提取参数并计算 Hash Key
3. GET
4a. Cache Hit (命中)
直接返回反序列化 ModelResponse (延迟 < 10ms)
4b. Cache Miss (未命中)
5. 发起实际网络调用
6. 返回流式/完整响应
7. SETEX
8. 返回响应给客户端
客户端 (Codex / OpenCode / Web)
LiteLLM Proxy 网关
Cache Key 生成器
Redis 缓存集群
上游 LLM (Gemini / Claude / DeepSeek)

  1. 拦截请求:客户端发起请求到达 LiteLLM Proxy。
  2. 生成指纹:LiteLLM 提取影响模型生成结果的全部请求字段,计算出确定性的字符串 Hash Key。
  3. 前置查询 :在向上游 API 发送网络请求之前,先向 Redis 执行 GET 查询。
  4. 命中直接返回
    • Cache Hit :从 Redis 读取缓存的 JSON 字符串,反序列化为标准的 ModelResponse 对象直接返回。耗时从秒级降低至毫秒级(通常仅受内网网络 RTT 影响),且不产生任何上游 Token 费用与 API 速率配额消耗。
    • Cache Miss:正常向上游模型提供商(如 Google AI Studio、OpenAI 等)发起网络调用。
  5. 异步回写:上游模型生成完毕后,LiteLLM 将完整的响应结构体序列化后写入 Redis,并附加配置的 TTL(生存时间)。

2. 缓存数据的底层存储结构:Key 与 Value

要弄清楚为什么缓存不能跨模型混用、为什么多一个空格都无法命中,必须拆解 LiteLLM 在 Redis 中实际存储的键值结构。

2.1 Cache Key 的构造逻辑(输入特征哈希)

LiteLLM 采用严格的输入特征提取算法。一个典型的 Cache Key 由以下要素共同决定:

text 复制代码
Cache Key = Hash(
    model_name,
    messages_array,
    temperature,
    top_p,
    max_tokens,
    tools_definitions,
    tool_choice,
    response_format,
    extra_body_params
)

关键约束规则:

  • 消息内容敏感messages 列表中的 systemuserassistant 角色顺序、文本内容(包括空格、标点符号、换行符)必须 100% 字符一致。"Hello""Hello " 会生成不同的哈希值。
  • 模型名称隔离 :模型名称是 Key 的最高优先级命名空间。即使 Prompt 完全一样,发送给 gemini-3.7-flashgpt-5.6-luna 会生成完全隔离的 Key,绝对不会发生跨模型串用。
  • 超参数敏感 :若请求 A 设置 temperature: 0.2,请求 B 设置 temperature: 0.7,两者会被视为不同请求分别计算。

2.2 Cache Value 的存储形态(完整序列化响应)

写入 Redis 的 Value 并不是单纯的文本字符串,而是上游模型返回的完整 OpenAI 规范 JSON 对象(经序列化存储):

json 复制代码
{
  "id": "chatcmpl-8f2a1b9c8d",
  "object": "chat.completion",
  "created": 1787412481,
  "model": "gemini-3.7-flash",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "这是大模型生成的完整回答内容...",
        "tool_calls": null
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 156,
    "completion_tokens": 84,
    "total_tokens": 240
  }
}

正因为 Value 保存了包含 choicesusagefinish_reason 在内的完整数据结构,LiteLLM 在命中缓存时才能对各类 SDK、CLI 工具(如 Codex、OpenCode)保持透明兼容。


3. 为什么 LiteLLM 网关无法实现"部分 Token 增量缓存"?

在日常工程交流中,经常有人问:"如果我的前 10 万字文档相同,只有最后提了一个新问题,LiteLLM 能不能只缓存前 10 万字,剩下的让模型补全?"

答案是:在网关层不可能做到。 这是由计算架构的物理边界决定的。
#mermaid-svg-1llOycR6v8j9MQDr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1llOycR6v8j9MQDr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1llOycR6v8j9MQDr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1llOycR6v8j9MQDr .error-icon{fill:#552222;}#mermaid-svg-1llOycR6v8j9MQDr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1llOycR6v8j9MQDr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1llOycR6v8j9MQDr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1llOycR6v8j9MQDr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1llOycR6v8j9MQDr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1llOycR6v8j9MQDr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1llOycR6v8j9MQDr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1llOycR6v8j9MQDr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1llOycR6v8j9MQDr .marker.cross{stroke:#333333;}#mermaid-svg-1llOycR6v8j9MQDr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1llOycR6v8j9MQDr p{margin:0;}#mermaid-svg-1llOycR6v8j9MQDr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1llOycR6v8j9MQDr .cluster-label text{fill:#333;}#mermaid-svg-1llOycR6v8j9MQDr .cluster-label span{color:#333;}#mermaid-svg-1llOycR6v8j9MQDr .cluster-label span p{background-color:transparent;}#mermaid-svg-1llOycR6v8j9MQDr .label text,#mermaid-svg-1llOycR6v8j9MQDr span{fill:#333;color:#333;}#mermaid-svg-1llOycR6v8j9MQDr .node rect,#mermaid-svg-1llOycR6v8j9MQDr .node circle,#mermaid-svg-1llOycR6v8j9MQDr .node ellipse,#mermaid-svg-1llOycR6v8j9MQDr .node polygon,#mermaid-svg-1llOycR6v8j9MQDr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1llOycR6v8j9MQDr .rough-node .label text,#mermaid-svg-1llOycR6v8j9MQDr .node .label text,#mermaid-svg-1llOycR6v8j9MQDr .image-shape .label,#mermaid-svg-1llOycR6v8j9MQDr .icon-shape .label{text-anchor:middle;}#mermaid-svg-1llOycR6v8j9MQDr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1llOycR6v8j9MQDr .rough-node .label,#mermaid-svg-1llOycR6v8j9MQDr .node .label,#mermaid-svg-1llOycR6v8j9MQDr .image-shape .label,#mermaid-svg-1llOycR6v8j9MQDr .icon-shape .label{text-align:center;}#mermaid-svg-1llOycR6v8j9MQDr .node.clickable{cursor:pointer;}#mermaid-svg-1llOycR6v8j9MQDr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1llOycR6v8j9MQDr .arrowheadPath{fill:#333333;}#mermaid-svg-1llOycR6v8j9MQDr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1llOycR6v8j9MQDr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1llOycR6v8j9MQDr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1llOycR6v8j9MQDr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1llOycR6v8j9MQDr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1llOycR6v8j9MQDr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1llOycR6v8j9MQDr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1llOycR6v8j9MQDr .cluster text{fill:#333;}#mermaid-svg-1llOycR6v8j9MQDr .cluster span{color:#333;}#mermaid-svg-1llOycR6v8j9MQDr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1llOycR6v8j9MQDr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1llOycR6v8j9MQDr rect.text{fill:none;stroke-width:0;}#mermaid-svg-1llOycR6v8j9MQDr .icon-shape,#mermaid-svg-1llOycR6v8j9MQDr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1llOycR6v8j9MQDr .icon-shape p,#mermaid-svg-1llOycR6v8j9MQDr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1llOycR6v8j9MQDr .icon-shape .label rect,#mermaid-svg-1llOycR6v8j9MQDr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1llOycR6v8j9MQDr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1llOycR6v8j9MQDr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1llOycR6v8j9MQDr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 物理边界: 网关无法执行注意力计算
推理层 (Google TPU / vLLM / GPU 集群)
加载百亿/千亿参数权重
KV-Cache 显存池 (Radix Tree)
执行 Transformer 矩阵运算
能做: 前缀向量复用、增量 Token 解码
网关层 (LiteLLM Proxy)
无状态 CPU 服务
无神经网络模型权重
无 GPU/TPU 显存计算能力
只能做: 文本哈希、路由转发、整包拦截

3.1 网关层与推理层的本质差异

  1. 缺少模型权重:LiteLLM 只是一个运行在通用 CPU 上的 API 代理,它手中没有神经网络参数。
  2. 生成依赖全量注意力计算:在大语言模型的 Transformer 结构中,生成新 Token 需要让新输入与历史上下文中的每一个 Token 进行注意力(Attention)权重计算。
  3. 文本缓存无法替代显存状态:把前 10 万字以文本形式存在 Redis 里对后续生成没有任何直接数学帮助。上游 GPU 要生成后续内容,依然必须将这 10 万字重新做一次词嵌入(Embedding)并计算每一层的 Key/Value 矩阵。

因此,网关层只能做整包级别的精确匹配或基于向量检索的语义缓存(Semantic Cache),无法直接分担大模型的局部生成计算。


4. 现代 LLM 的部分 Token 缓存原理:显存 KV-Cache 前缀复用

既然网关层做不到,那 Google Gemini、Anthropic Claude 以及开源推理框架 vLLM、SGLang 是如何在底层实现"部分 Token 命中并降价 75%~80%"的?

核心在于推理引擎显存级别的 KV-Cache 前缀复用(Prefix Caching / Radix Attention)

4.1 传统推理的算力浪费

在自回归生成过程中,每个 Token 在经过 Transformer 的每一层注意力计算时,都会生成对应的 Key 向量与 Value 向量(合称 KV-Cache)。

如果没有前缀缓存:

  • 第一次请求:输入 10 万 Token 背景 + 问题 A。GPU 计算 10 万 Token 的 KV 矩阵并输出回答。
  • 第二次请求:输入相同的 10 万 Token 背景 + 问题 B。GPU 必须把这 10 万 Token 从头再做一遍完整的矩阵乘法运算。

这两次计算中,针对 10 万背景 Token 的矩阵运算完全是重复且昂贵的。

4.2 前缀树显存索引(Radix Tree Prefix Caching)

现代推理集群将显存中的 KV-Cache 组织成一棵前缀树(Radix Tree):
#mermaid-svg-gXSI0EoBsG69HeC4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gXSI0EoBsG69HeC4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gXSI0EoBsG69HeC4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gXSI0EoBsG69HeC4 .error-icon{fill:#552222;}#mermaid-svg-gXSI0EoBsG69HeC4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gXSI0EoBsG69HeC4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gXSI0EoBsG69HeC4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gXSI0EoBsG69HeC4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gXSI0EoBsG69HeC4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gXSI0EoBsG69HeC4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gXSI0EoBsG69HeC4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gXSI0EoBsG69HeC4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gXSI0EoBsG69HeC4 .marker.cross{stroke:#333333;}#mermaid-svg-gXSI0EoBsG69HeC4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gXSI0EoBsG69HeC4 p{margin:0;}#mermaid-svg-gXSI0EoBsG69HeC4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gXSI0EoBsG69HeC4 .cluster-label text{fill:#333;}#mermaid-svg-gXSI0EoBsG69HeC4 .cluster-label span{color:#333;}#mermaid-svg-gXSI0EoBsG69HeC4 .cluster-label span p{background-color:transparent;}#mermaid-svg-gXSI0EoBsG69HeC4 .label text,#mermaid-svg-gXSI0EoBsG69HeC4 span{fill:#333;color:#333;}#mermaid-svg-gXSI0EoBsG69HeC4 .node rect,#mermaid-svg-gXSI0EoBsG69HeC4 .node circle,#mermaid-svg-gXSI0EoBsG69HeC4 .node ellipse,#mermaid-svg-gXSI0EoBsG69HeC4 .node polygon,#mermaid-svg-gXSI0EoBsG69HeC4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gXSI0EoBsG69HeC4 .rough-node .label text,#mermaid-svg-gXSI0EoBsG69HeC4 .node .label text,#mermaid-svg-gXSI0EoBsG69HeC4 .image-shape .label,#mermaid-svg-gXSI0EoBsG69HeC4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-gXSI0EoBsG69HeC4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gXSI0EoBsG69HeC4 .rough-node .label,#mermaid-svg-gXSI0EoBsG69HeC4 .node .label,#mermaid-svg-gXSI0EoBsG69HeC4 .image-shape .label,#mermaid-svg-gXSI0EoBsG69HeC4 .icon-shape .label{text-align:center;}#mermaid-svg-gXSI0EoBsG69HeC4 .node.clickable{cursor:pointer;}#mermaid-svg-gXSI0EoBsG69HeC4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gXSI0EoBsG69HeC4 .arrowheadPath{fill:#333333;}#mermaid-svg-gXSI0EoBsG69HeC4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gXSI0EoBsG69HeC4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gXSI0EoBsG69HeC4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gXSI0EoBsG69HeC4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gXSI0EoBsG69HeC4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gXSI0EoBsG69HeC4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gXSI0EoBsG69HeC4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gXSI0EoBsG69HeC4 .cluster text{fill:#333;}#mermaid-svg-gXSI0EoBsG69HeC4 .cluster span{color:#333;}#mermaid-svg-gXSI0EoBsG69HeC4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gXSI0EoBsG69HeC4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gXSI0EoBsG69HeC4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-gXSI0EoBsG69HeC4 .icon-shape,#mermaid-svg-gXSI0EoBsG69HeC4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gXSI0EoBsG69HeC4 .icon-shape p,#mermaid-svg-gXSI0EoBsG69HeC4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gXSI0EoBsG69HeC4 .icon-shape .label rect,#mermaid-svg-gXSI0EoBsG69HeC4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gXSI0EoBsG69HeC4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gXSI0EoBsG69HeC4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gXSI0EoBsG69HeC4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 显存 KV-Cache 根节点

前缀块: 100K 共享代码库/文档

已固化在 GPU 显存中的 Key/Value 矩阵

分支 A: 问题 1

仅计算新增 50 Tokens

分支 B: 问题 2

仅计算新增 80 Tokens

当新请求到达推理引擎时:

  1. 前缀匹配:调度器在显存树中比对 Token 序列,发现前 10 万个 Token 与显存中已有的 KV 块完全一致。
  2. 跳过预填充计算(Skip Prefill FLOPs) :GPU/TPU 直接复用显存中现成的 Key/Value 向量,跳过这 10 万 Token 的前向传播矩阵运算(节省 90% 以上的浮点运算量)。
  3. 仅计算增量:模型只需要对末尾新追加的几十个 Token 进行注意力计算并开始解码输出。

4.3 为什么服务商可以大幅降价?

因为模型服务商(如 Google)实际消耗的算力大幅降低,所以能直接体现在账单策略上:

  • Google Gemini:当上下文匹配自动缓存时,命中部分的输入单价通常只有未命中单价的 20%~25%(直接打 2~2.5 折),首字延迟(TTFT)大幅缩短。
  • Gemini 显式缓存(Explicit Context Caching):通过 API 显式创建长期驻留的 Cache 句柄,可针对固定的大型代码库或数据集按存储小时付费,每次调用的 Token 费用降至极低。

5. 企业级双层缓存架构实践

理解了两种缓存的机制与边界后,在企业级生产环境或私有网关中,最佳实践是采用双层联动架构
#mermaid-svg-4rAMnAycMnKBzKBT{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4rAMnAycMnKBzKBT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4rAMnAycMnKBzKBT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4rAMnAycMnKBzKBT .error-icon{fill:#552222;}#mermaid-svg-4rAMnAycMnKBzKBT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4rAMnAycMnKBzKBT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4rAMnAycMnKBzKBT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4rAMnAycMnKBzKBT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4rAMnAycMnKBzKBT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4rAMnAycMnKBzKBT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4rAMnAycMnKBzKBT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4rAMnAycMnKBzKBT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4rAMnAycMnKBzKBT .marker.cross{stroke:#333333;}#mermaid-svg-4rAMnAycMnKBzKBT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4rAMnAycMnKBzKBT p{margin:0;}#mermaid-svg-4rAMnAycMnKBzKBT .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4rAMnAycMnKBzKBT .cluster-label text{fill:#333;}#mermaid-svg-4rAMnAycMnKBzKBT .cluster-label span{color:#333;}#mermaid-svg-4rAMnAycMnKBzKBT .cluster-label span p{background-color:transparent;}#mermaid-svg-4rAMnAycMnKBzKBT .label text,#mermaid-svg-4rAMnAycMnKBzKBT span{fill:#333;color:#333;}#mermaid-svg-4rAMnAycMnKBzKBT .node rect,#mermaid-svg-4rAMnAycMnKBzKBT .node circle,#mermaid-svg-4rAMnAycMnKBzKBT .node ellipse,#mermaid-svg-4rAMnAycMnKBzKBT .node polygon,#mermaid-svg-4rAMnAycMnKBzKBT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4rAMnAycMnKBzKBT .rough-node .label text,#mermaid-svg-4rAMnAycMnKBzKBT .node .label text,#mermaid-svg-4rAMnAycMnKBzKBT .image-shape .label,#mermaid-svg-4rAMnAycMnKBzKBT .icon-shape .label{text-anchor:middle;}#mermaid-svg-4rAMnAycMnKBzKBT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4rAMnAycMnKBzKBT .rough-node .label,#mermaid-svg-4rAMnAycMnKBzKBT .node .label,#mermaid-svg-4rAMnAycMnKBzKBT .image-shape .label,#mermaid-svg-4rAMnAycMnKBzKBT .icon-shape .label{text-align:center;}#mermaid-svg-4rAMnAycMnKBzKBT .node.clickable{cursor:pointer;}#mermaid-svg-4rAMnAycMnKBzKBT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4rAMnAycMnKBzKBT .arrowheadPath{fill:#333333;}#mermaid-svg-4rAMnAycMnKBzKBT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4rAMnAycMnKBzKBT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4rAMnAycMnKBzKBT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4rAMnAycMnKBzKBT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4rAMnAycMnKBzKBT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4rAMnAycMnKBzKBT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4rAMnAycMnKBzKBT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4rAMnAycMnKBzKBT .cluster text{fill:#333;}#mermaid-svg-4rAMnAycMnKBzKBT .cluster span{color:#333;}#mermaid-svg-4rAMnAycMnKBzKBT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4rAMnAycMnKBzKBT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4rAMnAycMnKBzKBT rect.text{fill:none;stroke-width:0;}#mermaid-svg-4rAMnAycMnKBzKBT .icon-shape,#mermaid-svg-4rAMnAycMnKBzKBT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4rAMnAycMnKBzKBT .icon-shape p,#mermaid-svg-4rAMnAycMnKBzKBT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4rAMnAycMnKBzKBT .icon-shape .label rect,#mermaid-svg-4rAMnAycMnKBzKBT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4rAMnAycMnKBzKBT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4rAMnAycMnKBzKBT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4rAMnAycMnKBzKBT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 推理层计算
第 1 层: 网关精确响应缓存 (Redis)
100% 相同请求
请求有变动 (未命中)
共享长前缀
全新内容
业务端请求 (CI/CD / Agent / Web)
网关层: LiteLLM + Redis
直接拦截秒回 (0 费用, 延迟 < 10ms)
第 2 层: 推理端前缀缓存 (Google / vLLM)
命中显存 KV-Cache (输入费用打 2 折, 延迟大幅缩短)
全量计算正常计费

5.1 协同优势

  1. 第一层(网关 Redis)过滤死循环与机械重复
    • 拦截完全相同的自动化检查、固定代码分析、重复运行的单元测试、心跳检测等。
    • 实现真正的 0 耗时与 0 费用。
  2. 第二层(模型推理端 KV-Cache)加速多轮交互与代理循环
    • 当 Coding Agent(如 Codex、OpenCode)在多轮对话中不断追加修改指令时,尽管整包请求在变动,但前面累积的大段代码与对话历史会在 Google/vLLM 显存中持续命中前缀缓存。
    • 显著降低长上下文 Agent 任务的累计 Token 开销。

6. 总结

  • LiteLLM + Redis 属于请求/响应级别的精确哈希缓存,Key 严格绑定全部输入参数与模型名称,不支持跨模型复用,也无法代替神经网络完成局部增量生成。
  • 现代 LLM 的 Token 缓存 属于显存级别的 KV-Cache 前缀复用,依赖推理引擎与硬件显存,专门解决长上下文多轮请求下的计算浪费与成本问题。
  • 两者并不冲突,在网关层配置 Redis 拦截完全重复流量,在模型层利用服务商或 vLLM 的 Prefix Caching 消化长前缀计算,是当前大模型工程落地中最稳健的组合方案。
相关推荐
名字还没想好☜4 小时前
Next.js 用 cookies()/headers() 读请求信息:动态渲染触发、缓存失效与在 Server Action 里读写 cookie
前端·javascript·缓存·react·next.js·app router
lv__pf5 小时前
redis缓存数据库进阶
数据库·redis·缓存
草莓熊Lotso5 小时前
【Redis 初阶】Hash 类型深度解析:结构化数据存储的最优解
linux·网络·数据库·redis·tcp/ip·缓存·哈希算法
kyle~7 小时前
计算机系统 --- 缓存一致性
开发语言·c++·缓存·计算机系统
2602_9599609218 小时前
谢飞机面试大厂:Spring Boot、JVM、Redis、Kafka、微服务与音视频搜索场景求生实录
java·jvm·spring boot·redis·面试题
深念Y19 小时前
SSD 寿命洁癖:编译过程不入盘的原则与实践
缓存·io·内存·编译·ssd·读取·写入
智购科技无人售货机厂家19 小时前
2026自动售货机实时库存管理系统:从Redis缓存到持久化的数据架构演进~YH
redis·缓存·架构
晓晓_za89866819 小时前
Geo 优化源码蒸馏词机制:地域词库构建与匹配逻辑详解
运维·tcp/ip·spring·缓存·ci/cd
nvd1120 小时前
LiteLLM 如何使用 Redis:从部署位置到精确响应缓存
redis·缓存·gateway