跳到主要内容

19 篇博文 含有标签「prompt-caching」

查看所有标签

Prompt 缓存悬崖:一次系统提示词修改如何重置你的整个集群成本

· 阅读需 11 分钟
Tian Pan
Software Engineer

一切都没坏。这正是让人困惑的地方。没有部署失败,没有延迟报警,错误率也没有上升。有人合并了一个只有一行的 PR,在系统提示词(system prompt)末尾添加了一句话——一个新工具的描述、一条政策提醒,或者是“今天的日期是”的页眉——结果第二天早上,推理账单就高出了三到五倍。流量平稳,模型没变,代码也完全按照预期运行。

改变的是那一行代码放错了位置,导致你集群中所有的缓存前缀(cached prefix)瞬间失效。你的缓存命中率在一个请求周期内从 90% 降到了零,原本几乎免费的每个 token 开始按全价计费。这就是 Prompt 缓存悬崖(prompt-cache cliff),它是生产环境下 LLM 系统中最昂贵的故障模式,而且没人会对它进行威胁建模,因为它看起来根本不像故障。

当时钟成为工具:Agent、时区以及那个只在午夜发生的 Bug

· 阅读需 10 分钟
Tian Pan
Software Engineer

询问大型语言模型现在几点,你得到的回答虽然语气自信,但几乎肯定是不准确的。这并非因为模型坏了,而是因为它的内部没有时钟。Transformer 是一种无状态的文本补全引擎:它将 token 映射到 token。在整个流水线中,没有任何地方会接收到“现在是 14:32 UTC”这样的信号。模型感知不到当前时刻 —— 这是你必须在每一轮对话中主动提供给它的东西,否则它就会从陈旧的训练数据中臆造一个时间。

这种无声的失败往往在最糟糕的时刻浮出面。你的智能体认为现在是星期一,因为会话是在星期一开启的,于是它在星期二、星期三依然坚信这一点,直到它为一个已经过去的日子设定了“明天早上”的提醒。它利用数小时前就已冻结的 now 来分析“过去 24 小时”的日志。它在转换跨时区的会议时间时,因为误判了夏令时的边界而导致一小时的偏差。这些在传统意义上都不像是“幻觉”。其输出流畅、合理且逻辑自洽,只是它锚定在了一个不再存在的时刻。

服务商在 API 边界遵守但在缓存处违反的数据驻留契约

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的驻留审计追踪了来自租户流量的每一个出站请求,观察它在法兰克福的一个主机名上终止,并签了字。审计对它所测量的一切都是正确的。但它也看错了层级。请求确实去了欧盟。但满足该请求的字节——即服务商哈希并从最近可用节点提取的缓存前缀——却存放在 us-east-1。你的区域端点向你承诺了一个目的地。而缓存什么也没承诺,因为缓存是一个不同的产品,受不同的 SLA 约束,是为成本而非合规而设计的。

客户的审计员发现了它。不是你的。另一个供应商的事件报告提到 Prompt 缓存的放置与推理区域是解耦的,于是客户的 GRC 团队提出了那个显而易见的后续问题:我们的前缀去了哪里?修补这一差距的合同修正案花了 90 天。续约被暂停了。根据他们拿到的文档,编写集成的团队并没有做错任何事。

KV Cache 驱逐:供应商称其为“缓存压力”,而你的账单则称其为“双倍前缀费用”

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的应用程序开启了一个包含 4 万 token 系统提示词和完整工具库的长对话。第一轮对话按写入费率为前缀付费,且提供商的 KV 缓存(KV cache)开始预热。第二轮对话在 90 秒后到来。你假设这会命中缓存。有时确实如此。但有时,同样的 4 万 token 会再次以未缓存的价格出现在你的账单上,而你的代码在第一轮和第二轮之间没有任何改动。

改变的是别人的流量。KV 缓存是共享基础设施。你的租户被分配到一个推理节点上,而在你的两轮对话之间的 90 秒内,该节点接纳了足够多的其他租户,从而将你的前缀从内存中驱逐。提供商的控制台会将其描述为“缓存压力(cache pressure)”。你的财务团队会将其描述为一项翻倍的支出项。这两种描述都是准确的,但原因都不在你的代码里。

KV 缓存预热 Cron 任务只在蓝环境运行而从未进入绿环境,原因竟是主机绑定从未迁移

· 阅读需 12 分钟
Tian Pan
Software Engineer

事故复盘将十二天前的一次部署确定为支出增加 3.6 倍的原因,而当时在场的参与者中,没有一个人在变更发布时参与其中。部署过程非常常规:蓝绿切换,流量按计划转移到绿色环境,蓝色环境停用,流水线变绿,发布工程师关闭了工单。生产环境的 SLO 都没有触发。应用层的告警也没有响起。系统运行得完全符合设计。

原本的设计是一个每五分钟运行一次的 Cron 任务,它每五分钟针对稳定的系统提示词前缀 (system-prompt prefix) 预热提供商的 Prompt 缓存。这种预热为团队在冷启动时带来了 91% 的缓存命中率,并在每个会话的第一次请求中获得了大约 4 倍的成本优势。该 Cron 任务是一年前首次引入蓝绿模式时编写的,其主机选择器 (host selector) 被固定在蓝色池 (blue pool),以避免在重叠窗口期间运行两次预热。当绿色环境变成活跃环境而蓝色环境消失时,该 Cron 任务失去了它的主机,并从“每五分钟运行一次”悄无声息地转变为“永不运行”。随着提供商缓存的 TTL 使预热的前缀过期,缓存命中率在接下来的 36 小时内逐渐下降。成本仪表盘计算的是每日窗口内的平均单次请求成本,平滑了趋势,直到下一个计费周期让问题变得显而易见。

那个脱敏了用户提问却遗漏了提示词缓存的 PII 脱敏器

· 阅读需 12 分钟
Tian Pan
Software Engineer

一次客户审计发现,在 Redis 集群中存放了长达 11 个月的逐字记录的用户 PII,而数据驻留团队中没人知道这个集群的存在。系统并未遭到破坏。没有攻击者入侵。这些数据是推理团队为了性能优化而构建并命名为“Prompt 缓存”的服务故意写入在那里的。分析路径上的脱敏工具在此期间运行得非常完美。只是脱敏工具根本没在那条路径上。

尽管如此,违规行为是真实的。根据 GDPR,保留时间超过合同约定的 30 天就已经足够;数据无需泄露即可触发第 33 条规定的通知义务。数据驻留团队的清单列出了每一个日志、每一个仓库、每一个队列——但唯独漏掉了这个缓存,因为在组织架构图中,这个缓存位于推理团队的一侧。每个人都信任的隐私边界直接顺着分析流水线向下延伸,却在大模型(LLM)栈开始的地方止步了。

云厂商负载均衡器悄然忽略的会话亲和性

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的仪表盘显示缓存命中率为 71%。你的财务伙伴很满意。你的 p50 延迟也表现正常。然而,一个来自长时间运行的智能体(agent)会话的客户支持工单传了过来:第 14 轮对话花了 11 秒才产生首个 token,第 15 轮花了 8 秒,第 16 轮花了 9 秒。你调出链路数据(trace)。每一轮对话报告的 cache_read_input_tokens 值都是 0。系统提示词有 1.6 万个 token。用户认为智能体坏了,你认为你的供应商坏了。你们两个都不对。总体的命中率是一个幸存者统计数据 —— 它平均了那些容易命中缓存的短对话,并悄悄吸收了那些在会话中期崩溃为“首轮冷启动”的长对话。

这是任何供应商的复盘报告都不会向你描述的故障模式,因为从他们的遥测数据来看,系统正在按设计运行。负载均衡器正在做出它被要求做出的路由决策。缓存正按照它被要求遵循的时间表进行填充和置换。你传递的提示 —— prompt_cache_key、会话 ID、用户 ID,或者你序列化到该字段中的任何字符串 —— 始终都只是建议性的,而“建议性”意味着“在方便时会被忽略”。在负载压力下、发生扩缩容事件时、上游节点(pod)正在排空时,或者亲和性感知层饱和时,你的提示会悄无声息地降级为均匀的路由决策。请求落在一个冷启动的节点上。原本可以以亚毫秒级成本提供服务的前缀 KV 张量就在 16 英尺外的兄弟机架上,却无法访问。你的对话再次支付了全额前缀成本,而你仪表盘上的标题数字纹丝不动,因为另外 2000 个只有一轮的对话都正常命中了缓存。

使所有 Prompt 缓存前缀失效的分词器升级

· 阅读需 10 分钟
Tian Pan
Software Engineer

发布说明只有两行。“改进了多语言分词(Tokenization)。模型输出无破坏性变更。”一共不到二十个字。你的评估(Evals)确认了这一点:相同的提示词,相同的生成内容,相同的评分。你的平台团队在周五下午批准了升级。到了周二早上,你的缓存命中率从 80% 下降到 4%,每日推理费用翻了两番,而凌晨 6 点把你叫醒的轮值工程师在你的代码里找不到任何一行改动。

你的代码确实没有任何改动。但服务商发布了一个新的分词器,它对某个 Unicode 字符的一个字节划分与旧版本不同。你系统中每个缓存的前缀现在都是基于一个已不再存在的 Token 序列生成的指纹。模型的表现完全一致 —— 这确实是事实。但发布说明中未曾提及的缓存层,却为此付出了全额代价。

缓存击穿:这次冲击的是你的模型提供商,而不是数据库

· 阅读需 11 分钟
Tian Pan
Software Engineer

传呼机在 UTC 时间 14:02 响了。不是因为延迟,也不是因为错误——而是因为开销。费用仪表盘显示出一条垂直线:三分钟的输入 Token 计费大约是过去一小时平均水平的九倍,然后又恢复了正常。没有发布回归版本。没有新租户上线。流量精确到分钟来看都是平稳的。唯一改变的是,一个单一的 Prompt 前缀——集群中每个 Agent 共享的 14K Token 系统消息——在提供商端悄悄过期了,一千个 Worker 全都在同一个 200ms 的窗口内认定,自己就是那个需要将其写回的人。

这就是缓存雪崩(Cache Stampede)。这是自 2003 年 memcached 发布以来,运维人员一直在写事故复盘报告的那个老问题。2026 年的新变化在于,发生雪崩的缓存不再属于你。它存在于你的模型提供商内部,你无法检查其状态,而且每一次未命中(Miss)消耗的是真金白银,而不仅仅是几次额外的数据库查询。数据库工程师在二十年前就学会通过抖动(Jitter)来化解的同步 Bug,已经悄然出现在了一个没人想过要防御的账单细目中。

当源数据已更改,你的 Prompt 缓存仍在提供旧的工具执行结果

· 阅读需 11 分钟
Tian Pan
Software Engineer

一名支持代理在 14:02 查询了客户的订阅状态,发现其处于激活状态,该回答进入了 Prompt 前缀中,而缓存层刚刚将其标记为上下文的可重用部分。在 14:14,计费系统取消了该订阅。在 14:19,同一位客户提出了跟进问题,由于对话前缀仍然匹配,缓存的前缀被重用,代理愉快地告诉客户他们的计划处于激活状态,并主动引导他们使用一个他们已不再拥有访问权限的功能。下游系统是正确的。模型与上下文保持了一致。但用户被缓存命中(Cache Hit)欺骗了。

这是 Prompt 缓存为原本对数据陈旧度(Staleness)保持诚实的系统引入的失效模式。在引入缓存之前,工具调用是对单一事实源(Source of Truth)的请求,并遵循该源所声明的任何新鲜度契约。有了缓存之后,工具结果变成了 Prompt 前缀的一个租户,而前缀拥有自己的 TTL(生存时间),由模型提供商控制,团队中没有人明确选择启用它。

被你的个性化层悄悄杀掉的 Prompt 缓存

· 阅读需 12 分钟
Tian Pan
Software Engineer

产品团队发布了个性化功能。智能体(Agent)现在会直呼用户姓名,根据用户的偏好调整回答长度,了解用户在医疗行业工作,并尊重用户在提及日期时所处的时区。用户满意度的提升是真实且可衡量的——A/B 测试显示点赞率提升了四个百分点,随后功能全量上线。三周后,财务部门指出推理成本大约翻了三倍,而 AI 团队中没人能立即解释原因。

解释就在系统提示词(System Prompt)构建器中一行被埋没的代码修改里。每个用户的上下文——姓名、偏好的回答长度、行业、时区——都被添加到了系统提示词的开头,以便模型在每一轮对话中都能看到。这使得从第一个 Token 开始,每个用户的 Prompt 都是独一无二的。你的供应商提供的 Prompt 缓存——原本能以标准价格的十分之一服务大约 90% 的输入 Token——失效了。延迟几乎没有波动,所以性能仪表盘(Performance Dashboard)依然显示绿色。直到月底,计费仪表盘才反映出这一情况。

悄无声息击穿提示缓存的那次模型迁移

· 阅读需 11 分钟
Tian Pan
Software Engineer

迁移看上去很干净。评估已经针对新模型版本重新校准。Judge 提示词重新调校过。两周的影子流量显示行为对齐在容差范围内。p50 和 p99 延迟都在预算之内。周四下午的上线评审签字通过,团队各回各家。

到了周五早上,推理账单是平时的 3 倍。评估分数依旧没问题。延迟依旧没问题。上线评审上没有人想到要对缓存命中率做埋点,因为前缀根本没变 —— 系统提示词逐字节相同,工具定义逐字节相同,对话框架逐字节相同。变的是请求体里的模型版本,而供应商的前缀缓存键是 (前缀字节 + 模型版本)。切换之后的每一个请求都打到了一个冷缓存上。预热曲线靠自然流量花了六周才恢复,在此期间团队为每个请求的每一个 token 都支付了完整的未命中价格。