第208题缓存会造成什么错误1. 核心结论在 Agent 或 LLM 系统中缓存能够降低 latency 和 cost但会额外引入一层状态。缓存相关问题主要可以归纳为五类Stale Cache返回过期结果Wrong-key / Cross-tenant Reuse错误请求命中同一个缓存Semantic False Hit语义相似但实际答案不同Cache Poisoning错误或恶意内容被缓存并持续传播Cache Stampede热点缓存失效后大量请求同时回源因此设计缓存时我会同时控制Cache Key TTL Version Tenant/Permission Invalidation Concurrency并针对不同缓存层分别设计策略。2. 首先区分 Agent 系统中的几种缓存2.1 Prompt / Prefix Cache这一层复用模型已经计算过的公共 Prompt 前缀例如System Prompt Tool Definitions Static Context如果后续请求拥有相同前缀就可以复用前缀计算。这一类缓存主要影响Token CostPrefill LatencyCache Hit Rate。以 OpenAI Prompt Caching 为例缓存命中依赖 Prompt 前缀匹配。因此Prompt 顺序变化Tool Schema 变化System Prompt 变化都可能导致 Cache Miss。这一层通常不会直接把上一次完整答案返回给下一次请求所以它和 Response Cache 的错误模式需要分开分析。2.2 Exact Response Cache这一层直接缓存Request → Final Response例如Key: 如何重置密码 Value: 进入账户设置...下一次相同请求直接返回已有答案可以完全跳过 LLM。这种方式节省的成本最大但对 Cache Key 的正确性要求也最高。2.3 Semantic CacheSemantic Cache 进一步允许怎么重置密码命中如何修改我的登录密码通常先计算 Query Embeddingqfembed(x) qf_{\text{embed}}(x)qfembed​(x)然后与已有缓存 Query 比较sim(q,qi) sim(q,q_i)sim(q,qi​)如果sim(q,qi)τ sim(q,q_i)\tausim(q,qi​)τ就直接返回对应缓存答案。它能够提高命中率但会产生一个新的问题语义相似不能自动保证任务等价。2.4 RAG / Tool / Data CacheAgent 还经常缓存Retrieval ResultEmbeddingSearch ResultDatabase QueryTool ResultAPI ResponseUser ProfilePermission Result。这一类缓存主要面临源数据已经变化但缓存没有同步变化导致的状态一致性问题。3. 第一类错误Stale Cache最典型的问题是缓存陈旧。例如上午缓存漏洞状态 未修复下午漏洞已经修复漏洞状态 已修复Agent 仍然命中旧缓存漏洞状态 未修复这就是 Stale Cache。RFC 9111 对 HTTP Cache 也明确区分 Fresh Response 和 Stale Response并规定了缓存过期和重新验证机制。Agent 场景中更危险的陈旧状态包括用户权限已经撤销防火墙规则已经修改知识库已经更新Ticket 状态已经变化软件版本已经升级威胁情报已经更新System Prompt 已经换版本模型已经升级。因此 TTL 不能统一设置。例如静态产品说明 TTL 24h可能合理。但权限状态 安全告警 实时资产状态可能需要很短 TTL甚至直接绕过缓存读取 Source of Truth。4. 第二类错误Cache Key 不完整这通常是 Agent 系统里更危险的问题。假设系统只使用hash(user_query)作为 Cache Key。用户 A 问我的服务器有哪些高危漏洞系统缓存CVE-X CVE-Y用户 B 随后提出相同问题。如果 Cache Key 没有 Tenant 信息用户B ↓ 相同Query ↓ Cache Hit ↓ 返回用户A的数据就形成跨租户数据泄漏。因此一个生产级 Response Cache Key 至少需要考虑KH(request,tenant,permission,model,prompt,tools,dataVersion) KH( request, tenant, permission, model, prompt, tools, dataVersion )KH(request,tenant,permission,model,prompt,tools,dataVersion)实际可以包含tenant_id user_scope authorization_version normalized_query model_id model_version system_prompt_version tool_schema_version retrieval_index_version locale其中任何能够改变最终答案的变量都应该进入Cache Key或者进入Cache Eligibility Decision5. 权限不能只在写入缓存时检查这是一个容易出现的漏洞。假设管理员查询公司所有高危漏洞并把结果缓存。普通员工随后查询相似问题。如果系统直接读取管理员生成的 Cache EntryAdmin Permission ↓ Cached Response ↓ Normal User权限边界已经被缓存绕过。因此需要Authorization ↓ Cache Lookup而且 Cache Entry 本身也应该绑定Tenant Role Scope ACL Version当权限发生变化时相应缓存需要Invalidate或者通过新的权限版本自然形成 Cache Miss。6. 第三类错误Semantic Cache False HitSemantic Cache 的主要风险是Embedding 很接近业务约束不同。例如“删除测试环境数据库”和“删除生产环境数据库”语义上高度相似。但两个操作的安全级别完全不同。再例如“张三有哪些权限”和“李四有哪些权限”句子结构高度相似答案完全依赖具体实体。因此 Semantic Cache 不能只依赖cosine similarity cosine\ similaritycosinesimilarity更合理的判断是Semantic Similarity Hard Metadata Filter例如先限制tenant A locale zh-CN model_version V3 permission_scope security_read knowledge_version 2026-08-31然后再计算语义距离。Redis 官方 Semantic Cache 文档也明确提出应结合TenantLocaleModel VersionSafety Flags等 metadata boundary。另外还需要调节相似度阈值τ\tauττ↑ \tau \uparrowτ↑通常意味着False Hit ↓ Hit Rate ↓而τ↓ \tau \downarrowτ↓通常意味着Hit Rate ↑ False Hit ↑最终阈值应该通过真实数据验证。7. 第四类错误Cache Poisoning如果错误内容或恶意内容进入共享缓存它会持续影响后续请求。例如攻击者构造一个请求使系统产生错误安全建议随后这条结果被写入Shared Cache之后其他用户只要命中相同 Key就会继续收到错误内容。形成一次错误 ↓ Cache Write ↓ 大量 Cache Hit ↓ 错误被持续放大这就是 Cache Poisoning 的核心风险。OWASP 对 Web Cache Poisoning 的描述也指出共享缓存能够把一次恶意响应的影响扩散给后续用户。在 LLM Agent 中缓存写入之前最好检查输出是否通过安全策略数据来源是否可信Tool Execution 是否成功Response 是否完整是否来自 fallback是否发生 timeout是否包含敏感信息。特别需要避免缓存Error Response Partial Response Timeout Result Unauthorized Response Temporary Failure否则临时故障可能被固化成持续故障。8. 第五类错误Cache Stampede假设一个热门 KeyK_hot每秒有10000 requests正常情况下10000 requests ↓ Cache ↓ 1 个缓存结果数据库或 LLM 几乎没有压力。如果这个 Key 在某个瞬间过期K_hot expires大量请求会同时发现Cache Miss然后一起调用 LLM 查询数据库 调用外部 API可能形成Cache Expire ↓ 10000 Cache Miss ↓ 10000 Origin Requests ↓ Origin Overload这就是 Cache Stampede也常被称为缓存击穿或 Thundering Herd。Redis 官方 Cache-Aside 文档明确描述了热门 Key 同时过期导致多个进程一起回源的问题。9. Cache Stampede 怎么解决常见做法是 Single-flight 或 Per-key Lock。第一个请求发现Cache Miss获得Lock(K)然后只有这个请求真正回源LLM / DB / API其他请求Wait等第一个请求完成缓存更新后Cache Hit形成Request 1 ↓ Acquire Lock ↓ Origin ↓ Write Cache Request 2...N ↓ Wait ↓ Read Cache这个锁还必须具有Timeout Owner Token Lease否则负责更新缓存的 Worker 崩溃后可能造成永久阻塞。对于大量 Key 同时过期还可以给 TTL 增加随机抖动TTLTϵ TTLT\epsilonTTLTϵ其中ϵ∼Random(−δ,δ) \epsilon\sim Random(-\delta,\delta)ϵ∼Random(−δ,δ)避免所有缓存同一时间失效。10. 第六类问题缓存和 Source of Truth 不一致Cache-Aside 常见流程是Read: Cache ↓ miss Database ↓ Write Cache而更新时Write Database ↓ Invalidate Cache其中存在一致性窗口。例如DB V2 Cache V1某些请求仍然可能读到V1Microsoft Azure Cache-Aside 文档明确指出这一模式无法天然保证 Cache 与 Data Store 的强一致性。因此需要先定义业务能容忍多少陈旧Staleness Budget例如新闻推荐几分钟可能可以接受银行余额通常要求更严格权限撤销安全场景通常不能依赖长TTL对于强一致需求可以直接 bypass cache写入时同步 invalidation使用 versioned key使用 write-through使用事件驱动失效。11. Versioned Cache 比单纯 TTL 更可靠例如当前model_version v4 prompt_version p17 knowledge_version k23Cache Key 可以构造成agent:v4:p17:k23:query_hash当 Prompt 升级到p18新的请求自动进入agent:v4:p18:k23:query_hash旧缓存不会继续命中。这种方法特别适合模型升级System Prompt 升级Tool Schema 改动RAG Index 重建Embedding Model 更换。可以降低复杂的批量删除需求。12. 缓存故障还会影响模型评测假设比较Model A和Model B但 Model B 的测试请求大量命中了旧的Model A Response Cache那么最终测到的结果就失去意义。因此实验和线上灰度需要把model_version prompt_version experiment_id加入 Cache Namespace。A/B Test 也需要隔离experiment_A experiment_B避免两个实验组互相污染。13. Agent 系统中我会怎样设计缓存可以采用分层缓存Request ↓ Authorization ↓ Cache Eligibility Check ↓ Exact Cache ↓ miss Semantic Cache ↓ miss Agent / RAG / Tool Execution ↓ Output Validation ↓ Cache Write其中 Cache Key 至少绑定Tenant User Scope Model Version Prompt Version Tool Version Knowledge Version Request缓存条目记录created_at expires_at source_version model_version prompt_version tenant permission_scope quality_status这样发生错误时能够追踪这条答案为什么被缓存、来自哪个模型、哪个 Prompt 和哪个数据版本。14. 哪些内容我通常不会缓存以下数据需要非常谨慎实时权限状态高风险审批结果一次性 Token密码和 Secret动态安全策略高时效威胁情报不确定是否包含敏感信息的模型输出执行失败结果部分完成的 Agent Task。缓存带来的收益需要与错误成本一起评估。如果一次错误复用可能造成严重安全影响绕过缓存通常更加合理。15. 怎么验证缓存设计我会主动构造下面几组测试。15.1 Stale Test先缓存Document Version V1然后把源数据更新为V2验证系统是否按照定义的时间或事件Invalidation / Refresh15.2 Cross-tenant Test让Tenant A Tenant B发送完全相同 Query。验证A Response无法被B命中。15.3 Permission Change Test用户原来有admin随后降权为viewer验证旧缓存无法绕过新的 ACL。15.4 Semantic False-hit Test构造表面高度相似但答案不同的问题例如删除测试环境资源 删除生产环境资源检查 Semantic Cache 是否错误复用。15.5 Stampede Test人为让一个热门 Key 同时过期N 1000 concurrent requests观察Origin Request Count理想状态下不会接近1000而是通过 Single-flight 或 Request Coalescing 显著降低回源数量。15.6 Poisoning Test主动写入错误答案恶意答案部分失败答案Unauthorized Response。验证这些结果是否能够进入共享缓存并影响正常用户。16. 应该监控什么指标缓存层至少需要监控Cache Hit Rate Cache Miss Rate Semantic False-hit Rate Stale Response Rate Cross-tenant Violation Origin Request Rate Cache Fill Latency Eviction Rate Invalidation Delay Stampede Amplification同时继续监控整个 AgentTask Success Latency Token Cost Safety Violation因为极高的 Hit Rate 本身没有价值。例如Hit Rate 95%但Semantic False-hit 10%这个缓存方案显然不可接受。17. 面试时可以压缩成下面这段Agent 中缓存主要会产生五类错误。第一类是陈旧数据。知识库、权限、模型或工具状态已经变化但缓存仍然返回旧结果所以要用 TTL、事件失效和版本化 Key 控制 freshness。第二类是 Cache Key 不完整。如果 Key 没有包含 tenant、权限、模型版本、Prompt 版本和数据版本就可能出现跨用户、跨模型或跨实验复用安全系统里尤其可能造成数据泄漏。第三类是 Semantic Cache False Hit。两个问题 embedding 很相似但实体、时间、权限或环境不同答案可能完全不同所以语义相似度还需要结合 tenant、locale、model version、permission 等硬 metadata filter。第四类是 Cache Poisoning。错误或恶意结果一旦进入共享缓存会被后续请求持续放大所以缓存写入前也要做输出和权限验证。第五类是 Cache Stampede。热点 Key 同时过期后大量请求会一起回源可能把数据库、工具服务或 LLM 网关压垮。我会使用 single-flight、per-key lock、TTL jitter、回源限流和熔断控制。最终我会用 stale、跨租户、权限变更、semantic false hit、热点同时过期和 poisoning 六类故障注入测试验证缓存设计。核心原则是缓存命中必须同时满足内容等价、权限等价和版本等价。18. 来源RFC 9111 — HTTP Caching定义 Fresh/Stale Response、Cache Key、Vary 和 Revalidation 等缓存基础语义。Microsoft Azure Architecture Center — Cache-Aside Pattern说明缓存与 Source of Truth 的一致性问题、TTL、失效策略以及 Semantic Cache 的适用边界。Microsoft Azure Architecture Center — Caching Guidance说明缓存写入后的数据一致性、陈旧数据和分布式缓存设计问题。Redis Documentation — Cache-Aside说明热门缓存 Key 同时过期后产生 Cache Stampede 的机制。Redis Documentation — Semantic Cache说明 Semantic Cache 的相似度阈值以及 tenant、locale、model version、safety flags 等 metadata boundary。OpenAI — Prompt Caching说明 Prompt Cache 通过复用重复 Prompt 前缀计算降低 latency 和 input cost并依赖前缀匹配。OWASP — Cache Poisoning说明恶意或错误内容进入共享缓存后可以被持续传播给后续用户。