14.3 AI 系统缓存:Key、权限、版本与失效
同一句“本月还剩多少补给”,在北境和南境账户下含义不同;上午和晚上答案也会变化。若语义缓存只比较 embedding,相似度再高,也可能把别人的结果或过时库存直接返回。
缓存优化的是重复计算,不改变正确性边界。能否复用取决于所有会影响结果的输入:身份、权限、数据版本、模型、prompt、工具和时间,而不只是 query 文本。
本课目标
- 区分 prefix/KV、retrieval、exact response 和 semantic response cache;
- 为缓存键建立 correctness contract;
- 设计事件失效、TTL、版本 namespace 和删除传播;
- 处理 stampede、负缓存、部分失败与多区域一致性;
- 用陈旧率、错误复用率和单位成功成本评价缓存。
1. 四类缓存复用的不是同一种东西
| 类型 | 复用对象 | 仍会执行 | 主要风险 |
|---|---|---|---|
| Prefix/KV cache | 相同 token prefix 的模型中间状态 | 后续 decode | 版本/租户混用、显存占用 |
| Retrieval cache | query/filter 对应候选文档 | rerank/generation | ACL、索引更新、删除 |
| Exact response cache | 完全相同规范请求的结果 | 通常直接返回 | key 不完整、随机性、过期 |
| Semantic response cache | “足够相近”请求的结果 | 通常直接返回 | 意图、实体、权限和时效误判 |
Cache-Augmented Generation 有时指把预加载知识放进模型上下文或复用长前缀,并不是所有“带缓存的生成”。先说明实际复用层,再讨论一致性。
2. Cache Key 是正确性声明
Exact response key 可从 canonical request 构造:
tenant / principal or authorization scope
task and normalized user input
conversation/state version
model/tokenizer/template/prompt/adapter revisions
sampling and output schema
retriever/index/document snapshot
tool data/version or freshness token
safety/policy/locale versions不是每项都要原样写入 key,可以由一个 deployment/content version 汇总;但系统必须证明漏掉的因素不会改变可见结果。
不要把 bearer token 直接放进 key 或日志。使用稳定的 authorization-scope identifier,并确保它在权限变化时更新/失效。
3. 随机生成的缓存语义
当 temperature/sampling 非确定时,response cache 会把一次样本固定下来。这可能符合“同请求给稳定答复”的产品要求,也可能破坏多样性或评测假设。
明确:
- cache 是保存最终文本、结构化业务结果还是候选集合;
- 命中是否跳过 safety/authorization checks;
- 用户是否期待重新生成;
- seed/sampling config 是否进入 key;
- cached response 是否还需重新验证当前政策和引用。
高风险事实和外部状态优先缓存可验证的中间数据,而不是整段自然语言答案。
4. Semantic Hit 需要第二道判定
Embedding distance 只反映表示空间相近,不证明两个请求可共享答案。危险差别包括:
- “能不能删除账户”与“帮我删除账户”;
- “A 用户余额”与“B 用户余额”;
- “去年政策”与“当前政策”;
- “药物适用人群”与“我能否服用”;
- 否定词、数字、地区和版本差异。
语义缓存流程可先 ANN 找候选,再检查 task、entities、time scope、authorization、knowledge version 和风险等级。对于 side effects、个体化建议、实时数据和高风险领域,默认不直接复用最终答案。
Threshold 没有通用值。用 query pairs 标注 safe-to-reuse,而不是普通“语义相似”,测 false-hit cost 和关键 slices。
5. TTL 只是最后一道保险
TTL 适合限制最长陈旧时间,不能及时处理权限撤销、文档删除和紧急政策更新。优先建立 event-driven invalidation:
document v7 revoked
→ publish invalidation(document_id=v7)
→ retrieval entries evict
→ response entries tagged with v7 evict
→ regional replicas acknowledge
→ audit lag / failuresCache entry 保存 dependency tags:document IDs/versions、index、policy、model、tool data snapshot。倒排 dependency index 帮助定向失效;难以精确追踪时,切换 version namespace 让旧 key 不再命中。
删除要求覆盖 cache、replicas、snapshots 和 logs。备份可采用短保留和恢复后重放 deletion ledger。
6. 权限检查不能被 Cache Hit 绕过
两种安全方式:
- key 绑定 authorization scope,权限变化使 scope version 改变;
- 命中后仍按当前 principal 对缓存结果的资源依赖重新授权。
共享 public cache 只存已明确公开、无个体化内容的结果。多租户 cache 使用 namespace、配额和访问审计;加密保护存储/传输,但不能修复错误 key 导致的逻辑泄露。
Negative cache 也会泄露资源是否存在,或在权限恢复后继续返回“不存在”。对 403/404 的 key、TTL 和对外语义谨慎设计。
7. Stampede 与请求合并
热门 key 到期时,大量请求同时穿透到昂贵模型,造成过载:
- single-flight/request coalescing:同 key 只允许一个填充者;
- stale-while-revalidate:仅对允许陈旧的内容返回旧值并后台刷新;
- jittered TTL:避免同批 key 同时过期;
- refresh-ahead:预测热点提前刷新;
- bounded fill concurrency 与 admission control;
- failure negative caching,但使用短 TTL 和错误分类。
填充失败不能把错误页或 partial stream 当成功缓存。Entry 只有在 generation、schema、citation 和 safety checks 完成后原子发布。
8. 流式响应与部分结果
Streaming 时客户端可能中途取消,模型也可能在最后输出 invalid JSON。不要边生成边把未完成文本写入共享 cache。
可将流写入 request-local buffer,验证完成后提交;超大结果用临时 object + atomic manifest。Cache metadata 记录 finish reason、validation status 和 content hash。Canceled、timeout、policy-blocked 与 truncated outputs 默认不进入正常命中空间。
9. 多区域与容灾
跨区域 cache replication 会引入 invalidation lag。定义可接受 staleness,监控各区域 applied version;权限和安全撤销应走高优先级通道,必要时关闭命中而不是继续读旧副本。
Region failover 时新区域可能只有旧 cache 或不同 model/index version。恢复策略应先校验 namespace/deployment identity,不要为了降低冷启动延迟混用不兼容 entry。
10. 评价缓存不能只看命中率
核心指标:
- exact/semantic/prefix/retrieval hit rate;
- saved prefill tokens、saved model/tool calls;
- false semantic hit / wrong-scope hit;
- stale answer/citation rate;
- invalidation propagation latency 和 failure;
- hit/miss quality、safety、latency 分布;
- stampede/coalescing rate;
- cache memory/storage 与 unit successful-task cost;
- deletion/ACL test pass rate。
命中率上升而陈旧或错误复用增加不是优化。A/B 时按请求配对或稳定分桶,并检查高风险 slices。
常见误区
- 问题相似就能共用答案:身份、实体、时间和动作可能不同。
- TTL 能解决缓存一致性:紧急删除与权限撤销需要主动失效。
- 命中 cache 就不用再鉴权:那会把缓存变成越权通道。
- 缓存最终文本最省钱所以最好:权威数据变化时错误复用成本更高。
- 命中率越高越好:还要看错误命中、新鲜度和单位成功成本。
练习
- 为“查询当前库存”写完整 exact cache key。
- 构造十对语义相近但不应复用答案的 query。
- 设计文档撤回到多区域 cache 完成失效的事件链。
- 为流式 JSON response 设计 atomic cache fill。
- 建立包含 false-hit cost 的语义缓存上线门槛。
小结
AI 缓存的正确性由 key、权限、依赖版本和失效机制共同决定。Prefix cache 复用计算,retrieval cache 复用候选,response cache 复用结果;semantic response cache 风险最高,需要额外的意图与作用域判定。
最后一课把推理、路由、RAG、工具、缓存和评测连成一条可发布、可降级、可回滚的生产链路。