指导和见解

多模型 API 网关中的快速缓存控制:稳定前缀、租户隔离和缓存命中分析

一种实用的网关架构,用于保护 OpenAI、Anthropic 和 Gemini 风格 API 的提示缓存命中率:稳定的提示区域、提供商指标标准化、租户隔离、计费归因和推出检查。

提示缓存很容易浪费。一个团队可能有一个包含 40,000 个令牌的系统提示、工具模式、策略块、存储库映射或代理内存,这些都应该是可重用的,然后不小心将时间戳、请求 ID、用户名、检索片段或随机工具排序放在提示顶部附近。提供商看到不同的前缀,缓存丢失,延迟增加,账单看起来很混乱。

在单一提供商应用程序中,您可以在应用程序模板内修复此问题。在多模型网关中,问题更大:每个提供商公开不同的缓存控制、令牌阈值、生存时间行为、使用字段和计费语义。网关需要一个可移植的控制平面模式来组装缓存安全提示、测量缓存行为、隔离租户和归因成本。

本文描述了一个参考架构。它不是客户案例研究,也不声称基准结果。以下事实来自提供商文件和公共研究;设计建议为网关级操作指导。

故障模式:缓存破坏提示组件

提示缓存通常会奖励重复的提示前缀。确切的机制因提供商而异,但实际含义是一致的:如果提示符的前面发生变化,重用就会受到影响。

常见的缓存破坏器包括:

  • 顶部的每个请求元数据:时间戳、跟踪 ID、会话 ID、部署 ID 或生成的请求标签。
  • 前缀中的用户特定数据:放置在可重用策略或工具块之前的名称、帐户属性、权限或私人偏好设置。
  • 工具序列化不稳定:工具架构以不确定的顺序发出,并且空格或生成的 ID 不断变化。
  • 过早检索片段:在稳定系统指令或共享存储库上下文之前插入 RAG 上下文。
  • 模板偏差:经常发布小的措辞更改,而无需进行版本控制或缓存诊断。

网关无法神奇地使不稳定的前缀可缓存,但它可以强制执行提示组装合同并使缓存未命中可见。

提供设计所需的事实

细节很重要,因为网关必须规范行为,而不能假装提供商是相同的。

  • OpenAI:OpenAI 已记录了先前计算的最长提示前缀的提示缓存。它从 1,024 个令牌开始,以 128 个令牌为增量增加,并在使用字段中公开缓存的令牌计数。 OpenAI 还指出,提示缓存通常会在 5-10 分钟不活动后被清除,并且总是在缓存最后一次使用后一小时内被删除。
  • 人性化:人性化提示缓存可以通过 cache_control 请求。其文档描述了通过提示组件(例如工具、系统内容和消息)进行缓存匹配,直到标记为缓存控制的块。 Anthropic 记录了一个临时缓存,包括 5 分钟的持续时间和 1 小时的选项(需额外付费)。
  • Gemini:Google Gemini 上下文缓存通过使用元数据(例如 total_cached_tokens)公开缓存命中令牌计数,其文档按模型列出了最小输入令牌计数。
  • 数据控制含义:OpenAI 的 API 数据控制文档指出,扩展提示缓存需要将键/值张量作为应用程序状态存储在 GPU 本地存储中。即使提供商维持隔离保证,网关也应将缓存行为视为敏感基础设施,而不是共享应用程序数据存储。
  • 研究信号:公共研究已经检验了网关式架构是否会引入绕过提供商级缓存隔离假设的提示缓存漏洞。这并不能证明特定网关容易受到攻击,但它支持保守的租户隔离设计。

建议:将缓存控制作为具有明确策略的网关功能来实施,而不是作为重复提示的意外副作用。

三区域即时组装合同

最重要的设计决策是在请求到达提供程序适配器之前将稳定内容和易失内容分开。

区域1:稳定前缀

稳定前缀是指在对同一应用程序、模型路由和提示模板版本的多次请求中预期保持相同的内容。示例包括:

  • 核心系统指令;
  • 安全和政策块;
  • 工具架构;
  • 静态产品文档;
  • 编码代理的存储库映射;
  • 修复了输出格式说明。

该区域应该是确定性的。网关应根据版本化模板、规范化 JSON 和稳定的排序规则来构建它。如果包含工具注册表,请按稳定工具 ID 对工具进行排序。如果包含 JSON 架构,请使用确定性键排序来序列化它们,并且不生成时间戳。

区域 2:半稳定租户或工作空间环境

半稳定区域的变化频率低于单个请求,但不全局共享。示例包括:

  • 覆盖特定于租户的政策;
  • 工作区级别的工具许可名单;
  • 客户特定术语;
  • 团队编码约定;
  • 长期存在的项目环境。

该区域的范围应限于租户、工作区或应用程序边界。它可能仍然是可缓存的,但网关永远不应该假设另一个租户可以安全地重用它。

区域 3:易失性后缀

易失性后缀是每个请求部分:

  • 用户留言;
  • 检索到此查询的片段;
  • 当前时间戳(如果确实需要);
  • 请求 ID 和跟踪元数据(如果包含在提示中);
  • 短期对话;
  • 运行时工具结果。

大多数由应用程序设计引起的缓存未命中是因为易失性后缀数据被意外放置在前缀中。网关端构建器应该使这变得困难。

实现模式:稳定前缀构建器

实用的网关实现可以公开提示组装接口,而不是从每个应用程序接受一个不透明的提示字符串。

<前><代码>{ "template_id": "代码代理-v3", “tenant_id”:“tenant_123”, "route": "编码长上下文", “稳定前缀”:{ “system_policy_version”:“2026-08-01”, "toolset_version": "工具-v12", “repo_context_version”:“repo-map-8491” }, “半稳定上下文”:{ “workspace_policy_version”:“workspace-44-v6” }, “易失性后缀”:{ "user_message": "解释一下为什么这个测试失败......", “retrieval_context_ids”:[“chunk_7”,“chunk_19”], “trace_id”:“not_inserted_into_prompt” } }

然后网关呈现提供商特定的请求。这为网关提供了执行规则的地方:

  • 拒绝稳定前缀字段中的时间戳;
  • 规范化工具架构;
  • 分别对每个区域进行哈希处理;
  • 在提供商支持的地方附加缓存控件;
  • 保留提示语义,同时稍后移动易失性材料;
  • 记录模板和前缀指纹以进行诊断。

对于仅发送原始消息的旧应用程序,网关仍然可以提供 lint 模式:检查消息顺序、计算前缀指纹并报告可能的缓存破坏者,而无需最初重写提示。

提供者适配器层:规范缓存使用而不隐藏差异

多模型网关不应向开发人员公开三个不相关的缓存报告。它也不应该如此积极地扁平化特定于提供商的经济,以至于发票变得无法解释。

创建一个规范化的缓存分类帐,其中包含以下字段:

<前><代码>{ "request_id": "req_abc", “tenant_id”:“tenant_123”, "app_id": "代码代理", "route": "编码长上下文", “提供商”:“提供商名称”, “型号”:“型号_id”, "template_id": "代码代理-v3", "stable_prefix_hash": "sha256:...", "semi_stable_hash": "sha256:...", “输入令牌总数”:58200, “input_tokens_uncached”:8200, “cache_write_tokens”:50000, “缓存读取令牌”:0, “输出令牌”:1300, "cache_ttl_class": "ephemeral_5m", “provider_cache_fields”:{ “raw_field_names”:“stored_or_redacted_provider_usage” } }

适配器将提供程序的使用情况映射到标准化类别:

  • 未缓存的输入令牌:在没有缓存读取折扣或缓存读取会计的情况下处理的令牌。
  • 缓存写入令牌:当提供商报告此区别时创建或刷新提供商端缓存条目的令牌。
  • 缓存读取令牌:从缓存提供的令牌或按提供商使用元数据计为缓存的令牌。
  • 输出令牌:生成的令牌,应与提示缓存经济学分开。
  • TTL 选项:提供商公开选择的选定缓存持续时间类别。

建议:将原始提供程序使用情况存储在经过编辑的、架构版本化的表单中以及规范化字段中。标准化对于仪表板很有用;当提供者语义发生变化时,原始字段对于协调是必要的。

缓存可观察性:解释未命中的仪表板

有用的缓存仪表板不仅仅是显示缓存令牌总数。它应该可以帮助团队回答:“哪个工作负载破坏了前缀,以及发生了什么变化?”

通过以下方式跟踪缓存指标:

  • 租户;
  • 工作区或应用;
  • 模型路线;
  • 提供商和模型;
  • 提示模板版本;
  • 稳定的前缀哈希;
  • 半稳定上下文哈希;
  • API 密钥或服务帐户(如果适用);
  • 时间窗口,特别是因为缓存 TTL 对于许多工作负载来说都很短。

有用的派生指标包括:

  • 缓存读取率:缓存的输入令牌除以符合缓存条件的输入令牌总数。
  • 前缀流失:每个模板版本每小时的不同稳定前缀哈希数。
  • 模板漂移:模板发布后缓存命中发生变化。
  • 冷启动成本:突发中第一个请求的缓存写入或未缓存输入支出。
  • 路线比较:同一逻辑工作负载下不同提供商路线的命中率。

不要默认存储原始提示以进行调试。首选哈希、区域长度、模板 ID、规范化警告和编辑差异。如果团队需要更深入的调试,则需要明确的访问控制和保留限制。

租户隔离策略:不要为跨租户重用而设计

最安全的网关假设很简单:可缓存行为应该是租户范围内的。即使两个租户共享相同的公共策略块,网关也不应该故意路由或调整流量以利用跨租户缓存重用。

保守政策包括:

  • 租户感知路由:使用租户、工作区和应用边界路由可缓存流量。
  • 禁止共享包含秘密的前缀:切勿将租户秘密、凭据、私人文档或用户特定数据放入可重用的共享前缀中。
  • 单独的前缀指纹:计算网关分类帐中包含的租户范围的指纹,即使呈现的文本相同。
  • 组织级控制:允许管理员针对敏感工作负载禁用提供程序缓存功能。
  • 提供商隔离不是转售的产品功能:将提供商缓存隔离视为基线保护,而不是构建跨客户缓存池的权限。

预测:随着长上下文代理变得越来越普遍,缓存行为将成为安全审查的一部分,而不仅仅是成本审查。可以证明租户范围的缓存策略的网关将更容易管理。

计费归属:单独的缓存读取、写入和普通令牌

如果所有输入标记都显示为一个数字,则提示缓存可能会使发票更难以理解。帐单应至少保留五个类别:

  1. 未缓存的输入令牌;
  2. 缓存写入令牌;
  3. 缓存读取令牌;
  4. 输出令牌;
  5. 提供商特定的 TTL 或缓存控制费用。

当一个提供商对缓存读取打折,另一个提供商对缓存写入收取不同的费用,以及另一个提供商公开更长的 TTL 选项时,这一点很重要。客户发票应该能够解释为什么具有相似总输入令牌的两个请求具有不同的成本。

对于内部退款,将缓存效果归因于发出请求的租户和应用程序。避免将缓存读取权益从一个租户分配给另一个租户。如果共享的内部平台团队拥有稳定的提示模板,请与租户发票分开报告模板级缓存性能。

缓存检查清单

在启用缓存强制之前,通过 lint 检查列表运行提示模板:

  • 稳定的系统指令出现在不稳定的用户输入之前。
  • 工具架构按稳定 ID 或名称排序。
  • JSON 是确定性序列化的。
  • 稳定前缀中不会出现时间戳、随机 ID、请求 ID 或跟踪 ID。
  • 共享的可重用块中不会出现特定于用户的机密。
  • RAG 代码段放置在可重用政策和工具部分之后,除非有故意不这样做的原因。
  • 提示模板具有明确的版本。
  • 模板发布可以与缓存命中率变化相关。
  • 提供程序缓存控件仅通过适配器代码使用,而不是分散的应用程序逻辑。
  • 原始提示日志记录默认处于禁用状态,或者受到严格的保留和访问规则的保护。

推出计划

1。更改提示之前先观察

首先收集现有流量的提供商使用字段和规范化缓存指标。计算前 N 个令牌或网关定义的提示区域的前缀指纹。目标是找到具有高前缀流失率的大容量、长上下文路由。

2。对工作负载进行分类

将流量分为几类:代理会话、编码助理、RAG、支持自动化、文档分析、批处理作业和简短聊天。提示缓存工作通常最关注长上下文和重复前缀的工作负载。低于提供商阈值的简短提示可能不会受益。

3。引入稳定前缀构建器

将一项工作负载从原始提示构造转移到基于区域的组装。保持呈现的提供者请求在语义上等效。不要将此更改与模型迁移、工具重新设计或主要提示重写结合起来,否则您将不知道是什么导致了指标更改。

4。金丝雀一条路线

为一个租户或内部应用程序的一小部分启用缓存控制。比较缓存读取率、前缀流失、第一个令牌的时间、错误率和成本类别。在提供商账单与网关账本核对之前,避免要求节省费用。

5。逐步执行

继金丝雀之后,将 lint 警告转变为策略检查。例如,首先对不稳定的工具顺序发出警告,然后拒绝在稳定前缀中包含易失性元数据的新模板版本。

权衡

  • 更高的缓存命中率与提示灵活性:稳定的前缀可以提高重用率,但团队可能需要稍后移动动态指令或重新设计模板。
  • 提供商原生缓存与可移植性:使用每个提供商的缓存控制可以提高经济效益,但阈值、TTL、字段和定价语义有所不同。
  • 可观察性与敏感日志记录:提示差异有助于调试失误,但哈希值和经过编辑的诊断是更安全的默认设置。
  • 租户隔离与最大重用:广泛的重用可能看起来很有吸引力,但租户范围内的行为更安全、更容易解释。
  • 更长的保留时间与成本和策略复杂性的比较:更长的 TTL 选项可以帮助代理会话,但可能会引入不同的定价和数据控制注意事项。

可行的结论

将提示缓存视为网关控制平面问题,而不是提供商复选框。实用的模式是:定义稳定、半稳定、不稳定提示区域;确定性地呈现它们;在一个接口后面调整特定于提供者的缓存控制;将缓存使用情况标准化到分类帐中;按租户、应用程序、路由和模板版本公开缓存命中诊断;并执行租户范围的假设。

第一个有用的步骤不是重写。将缓存可观察性添加到最长的提示中,识别前缀流失,并对导致最多失误的模板进行 lint 处理。一旦您能够解释缓存行为,就可以安全地对其进行优化。

相关阅读

FAQ

常见问题

网关是否应该自动重写提示以提高缓存命中率?
一开始不是。从 linting、指纹和诊断开始。自动重写可以改变模型行为,尤其是代理和工具使用提示。如果引入重写,请通过版本化模板、金丝雀和语义回归检查来实现。
如果文本相同,不同租户可以共享相同的缓存前缀吗?
保守的网关不应故意依赖跨租户缓存重用。将缓存行为视为租户范围内的路由、可观察性、计费和安全审查,即使提供商维护自己的隔离控制也是如此。
提示缓存命中率不佳的最常见原因是什么?
最常见的设计问题是将易失性内容放在提示的开头附近:时间戳、请求 ID、用户元数据、检索片段或不确定排序的工具模式。这些更改改变了缓存所依赖的前缀。
客户发票上应显示什么?
单独的未缓存输入令牌、缓存写入令牌、缓存读取令牌、输出令牌以及特定于提供者的缓存 TTL 或缓存控制费用。这使得更容易解释为什么相似的请求可能具有不同的成本。