概览
GoModel 内置两层响应缓存,适用于以下端点上的流式和非流式请求:/v1/chat/completions/v1/responses/v1/messages/v1/embeddings/v1/systemone(以及 Kev 的/permute和/separate)
text/event-stream 原样重放这些字节。
精确匹配缓存返回逐字节相同的响应,并带有:
/v1/embeddings 只参与精确缓存。嵌入必须表示所请求的确切文本,因此为仅仅相似的输入重放向量,会得到一个错误的答案,而不是一个等价的答案。嵌入请求也从不使用流式传输,因此只缓存 JSON 响应。System One 决策同理:相似的状态并不意味着相同的决策。启用精确缓存
将响应缓存指向 Redis:REDIS_URLREDIS_KEY_RESPONSESREDIS_TTL_RESPONSES
启用语义缓存
添加一个semantic 配置块,并指定嵌入提供商和向量存储:
qdrantpgvectorpineconeweaviate
Cache-Control: no-cache 或 Cache-Control: no-store 可以针对单个请求绕过缓存。插件也可以在其决策中使用 NoStore,使某个响应不进入两层缓存;将请求特定数据恢复到回复中的护栏就是这样做的,以确保恢复后的文本绝不会被重放给其他调用方。/v1/responses 上的 background: true 请求同样会绕过两层缓存:它的 queued 响应体携带一个只属于某个调用方响应的 id。
有关语义缓存的完整设计和存储选项,请参阅 ADR-0006。
精确缓存键的组成
精确缓存会对以下内容计算哈希:- 请求路径
- 用于执行的已解析工作流上下文,具体为执行模式、提供商类型和解析后的模型
- 请求解析到的护栏链,涵盖提示词、响应和流三个阶段
- 最终的请求体
提供商提示词缓存规划
在路由解析出具体的提供商和模型之后,如果稳定前缀达到该提供商的最小长度,且客户端尚未提供缓存指令,GoModel 会添加一个缓存计划:- OpenAI 会收到一个稳定的
prompt_cache_key;支持显式缓存的模型还会收到一个断点和显式缓存模式。 - Anthropic 会收到顶层的自动临时缓存(ephemeral caching)。
- Amazon Bedrock Converse 会在稳定前缀之后收到一个缓存点。
- 原生 Gemini AI Studio 会创建并复用一个五分钟有效的缓存内容对象,并按前缀和稳定凭据合并并发创建。
true),无效值会在启动时输出警告。
user_path 行为
对于精确缓存,user_path 本身不会被加入缓存键。
这是有意为之。如果两个请求最终具有相同的路径、解析后的工作流和最终请求体,即使它们来自不同的 user_path 值,也可以共用同一个精确缓存条目。
如果您需要按租户或路径区分缓存行为,请使用带作用域的工作流,或以其他方式使该作用域的最终请求有所不同。仅靠
user_path 并不能作为精确缓存的分区键。- 在带作用域的工作流中禁用缓存
- 为不同的
user_path值使用不同的带作用域工作流 - 加入特定于作用域的上下文,使最终请求体有所不同
通过故障转移返回的响应不会被缓存
当请求由某个故障转移目标而不是路由最初选择的目标应答时,该响应不会被存储。精确缓存键是根据故障转移之前的解析结果计算的,因此如果存储备用目标的应答,在主目标恢复后,这个应答会以主目标的缓存键被返回。 实际影响是:如果某个虚拟模型的第一个目标长期不可用,在其不可用期间,该虚拟模型将不再积累缓存条目。每个未命中的请求都会故障转移并获得新的响应,而这些响应都不会被存储。故障之前写入的条目在 TTL 过期前会继续提供服务:缓存查找在分发之前进行,因此命中时直接返回,不会触及任何目标。如果某个目标将在一段时间内不可用,请调整链的顺序(或将虚拟模型指向健康的目标),使应答请求的响应重新可被缓存。 同一目标内的重试不受影响:只有在切换到其他目标之后产生的响应,才会被排除在两层缓存之外。缓存分析
当启用了响应缓存和用量追踪时,Admin API 会在以下位置提供仅包含缓存数据的概览:user_path,以及值为 exact 或 semantic 的 cache_type。用量端点(/admin/usage/* 和 /v1/usage)默认不包含这些条目,使总量和成本反映的是提供商支出;传入 cache_mode=all 可包含它们,传入 cache_mode=cached 则只查看命中条目。/admin/usage/sessions 是例外:会话的请求数和 Token 总数始终包含缓存命中,而其成本字段仍只统计提供商支出。