#AI#大模型#DevOps

Prompt 前缀缓存正确性:版本键、租户隔离与命中验收

命中率上升不代表缓存正确。本文为托管与自建前缀缓存定义作用域、内容身份、授权 epoch、命中复核和跨租户负向测试。

本文要点

  • 主题聚焦:AI、大模型、DevOps
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年3月9日·更新于 2026年7月20日

Prompt Caching 深度 解释稳定前缀与命中优化,本篇只讨论“这次命中是否有资格被接受”。LLM 缓存策略 还包含结果和语义缓存,它们能直接返回答案;前缀缓存只复用 prefill 计算,不应改变采样语义。KV Cache 准入与淘汰 管显存块承诺,本控制则管块或托管 cached content 的内容身份、版本和租户边界。

记忆摘要可以成为前缀输入,但 记忆压缩血缘 的 artifact ID、source epoch 和权限必须进入缓存身份;“摘要文字恰好一样”不能绕过其有效性。Prompt 工程负责写什么,本篇不通过改措辞修复隔离。

先声明缓存作用域,再计算身份

每个前缀只能是 PUBLIC、TENANT 或 PRINCIPAL。PUBLIC 要求所有来源都经过公开数据清单批准,不能因内容不含明显姓名就自动判定;默认是租户作用域。网关从可信认证上下文取得 scope,规范渲染消息与工具定义,再计算内容 digest。租户 namespace 用服务端密钥按 RFC 2104 HMAC 派生,日志只记录短摘要,不暴露原始 ID。

json
{
  "cacheObject": "pc-01J2ZE",
  "scope": "TENANT",
  "namespace": "hmac-sha256:49a1...",
  "contentDigest": "sha256:f861...",
  "modelDigest": "sha256:8d02...",
  "tokenizerDigest": "sha256:2f4a...",
  "runtimeDigest": "sha256:590c...",
  "adapterDigest": "sha256:19bb...",
  "promptBundleDigest": "sha256:80c1...",
  "toolsetDigest": "sha256:91c4...",
  "policyRevision": 18,
  "authorizationEpoch": 42,
  "cacheEpoch": 7
}

模型、tokenizer、runtime、adapter、聊天模板、工具 schema 和会改变 token 序列或注意力计算的参数都属于身份。安全策略和授权 epoch 即使不改变文本也必须参与接受判断。动态时间、request ID 与用户问题放在可缓存前缀之后不是安全控制;若前缀本身含私有资料,仍只能在对应作用域复用。

Google Gemini 的 context caching 文档说明显式缓存内容的创建与使用,vLLM 的 Automatic Prefix Caching 文档说明按已计算前缀块复用计算。两者的 API 和生命周期不同,所以应用 registry 保存的是自己的期望合同,不把供应商 cache name 或运行时 block hash 当作授权凭据。

命中时重新做廉价接受判定

请求先完成授权和版本解析,得到 expected tuple,再查询缓存。对象必须匹配 namespace、全部 digest、policy、authorization epoch 与 cache epoch;任何字段不符都当 miss。在物理 KV 参与计算前,请求还要从与授权 epoch 更新共用的线性一致 gate 取得 CacheUsePermit,绑定 request、cache object、epoch 与 fence并登记 in-flight;撤权 CAS 推进 epoch并关闭旧 permit,与并发获取只能一方成功。异步清理不承担即时拒绝。MCP 多租户隔离 的可信上下文传播必须贯穿网关、队列和 worker。

物理 lookup 必须在块参与计算前隔离,而不是命中后才由应用补验。所有 TENANT/PRINCIPAL 请求强制把 HMAC namespace、cacheEpoch 与 runtime digest 注入首块 hash/cache salt,后续链式块继承该根;运行时若不支持请求级 salt,就使用租户隔离池或禁用私有前缀缓存。只有经过清单批准的 PUBLIC 前缀可使用共享 salt。物理块仍需强摘要并验证 token 序列或不可碰撞身份,不能用短 hash 命中后不比较;共享块不可变,以引用计数或代际 fence 释放。公共共享还要评估命中时延侧信道,高敏感部署可完全关闭跨租户物理复用。

缓存接受后仍运行正常输出校验与工具授权。前缀缓存不是结果缓存,冷请求与热请求在固定模型参数下应满足同一业务断言;命中不能恢复已撤销工具,也不能跳过本轮权限过滤。

用交换租户和碰撞替身做负向测试

建立 A、B 两个租户,分别使用字节相同的公共模板、不同私有文档和相同用户问题。先让 A 预热,再由 B 请求,注入遗漏物理 salt、错误 namespace、旧 authorization epoch、相同短 hash、adapter/tokenizer 切换、策略撤销、并发淘汰和 worker 重启。断言私有请求在 lookup 前因 salt 或隔离池分开;测试运行时再替换 hash 函数强制造碰撞,确认完整身份比较仍拒绝错误块。

再把 A 的缓存句柄、对象名和异步任务 ID 交给 B,所有入口都从认证上下文限定 scope。把撤权插在 lookup 与 permit 获取之间,断言撤权或 KV 使用只能一方通过;已登记计算由撤销流程等待、取消或隔离,旧 worker 无 permit 不能继续。热、冷输出比较 required claims、引用、工具集合和 schema,不逐字要求随机生成一致。

指标包括按作用域的命中与节省 prefill、版本不匹配 miss、授权 epoch 拒绝、跨作用域尝试、热冷断言分叉、旧代可见对象和清理时延。标签不放原始租户或 Prompt;跨作用域接受、错误版本接受和旧代实际使用必须为零,不能被高命中率抵消。

上线先只观测候选命中,再启用单租户作用域,最后才评估明确批准的公共前缀。事故回滚单调推进 cacheEpoch,停止公共共享并旁路缓存;必要时按 namespace 清理,但正确性不依赖清理立刻完成。恢复时用新 epoch 重新预热,不能重新启用旧对象。性能会暂时下降,回答与授权语义必须保持不变,这才是缓存可安全关闭的验收标准。

延伸阅读

Related

相关推荐