跳到主要内容

Semantic Cache(语义缓存)

Aidy 内置了语义缓存能力,通过静态配置 plugins.semantic_cache.* 与 route 级 plugin_config.semantic_cache 配置。

启用条件

Semantic Cache 插件只有在同时满足以下条件时,才会被挂进请求链路:

  1. 静态配置 plugins.semantic_cache.enable = true
  2. 静态配置中已提供完整运行所需参数:embedding_service_urlembedding_modelredis
  3. 当前 route 配置了 plugin_config.semantic_cache

如果以上任一条件不满足,Semantic Cache 不会进入当前 route 的请求链路。

另外,Semantic Cache 当前只挂在 chat 的 forward hook 上。因此即使路由启用了语义缓存,embeddings、models、options 与 unknown 请求也不会进入该插件。

链路位置

Semantic Cache 会优先于以下中间件执行:

  • upstream-ratelimit
  • egress-policy
  • guard
  • consumer
  • perf

也就是说,命中缓存时,请求会直接在网关内返回,不再继续进入后续上游调用链路。

静态配置

静态配置用于提供 embedding 服务与 Redis 向量存储能力,对应 plugins.semantic_cache.*。完整字段说明见 静态配置

其中最关键的字段是:

  • enable
  • embedding_service_url
  • embedding_model
  • embedding_api_key
  • embedding_dimensions
  • embedding_timeout_ms
  • redis
  • verbose_log

路由配置

route 级配置用于指定特定 route 的语义缓存策略,使用以下 proto:

常用字段说明:

  • cache_ttl_seconds:缓存存活时间,单位秒
  • similarity_threshold:向量距离阈值;越小代表要求越相近
  • distance_metric:距离度量方式,当前仅支持 cosine
  • message_countback:从末尾回看多少条消息参与 embedding
  • include_roles:哪些 role 会参与 embedding 文本构造
  • include_instructions:是否把 instructions 纳入 embedding 文本
  • include_tools_signature:是否把 tools 签名纳入缓存命名空间
  • isolate_by_model:是否按请求 model 隔离缓存命名空间

运行时行为

插件进入链路后,会按以下顺序工作:

  1. 根据请求内容构造 embedding 文本
  2. 调用 embedding 服务生成向量
  3. 在 Redis 向量索引中按命名空间检索最相近条目
  4. 命中时直接返回缓存响应
  5. 未命中时继续请求后续链路;若最终响应为 2xx,则将响应写入缓存

当前缓存命名空间格式为:

sc:{tenant}:{route}:{model}:{tools_hash}

其中:

  • tenantroute 始终参与隔离
  • model 是否参与隔离由 isolate_by_model 决定
  • tools_hash 是否参与隔离由 include_tools_signature 决定

命中 / 未命中 / 绕过

Semantic Cache 会把处理结果写入响应头与请求日志。

hit

  • 返回响应头 X-Semantic-Cache-Status: Hit
  • 同时返回 X-Semantic-Cache-KeyX-Semantic-Cache-Distance
  • 网关直接返回缓存响应,不再继续调用后续插件和上游

miss

  • 返回响应头 X-Semantic-Cache-Status: Miss
  • 请求继续进入后续链路
  • 若最终响应是 2xx 且可序列化为内部 ResponseIR,则写入缓存

bypass

以下情况会绕过语义缓存逻辑:

  • embedding 文本为空
  • embedding 服务调用失败
  • Redis 向量检索失败
  • 插件运行时依赖未正确初始化

绕过时会记录 status=bypass,并按情况附带 bypass_reasonerror

请求日志

ext_fields.semantic_cache 使用以下 proto:

常见字段包括:

  • statushit / miss / bypass
  • bypass_reason:例如 embedding_text_emptyembedding_failedsearch_failednot_configured
  • cache_key:命中时缓存条目 ID
  • distance:命中时向量检索距离
  • namespace:本次检索使用的缓存命名空间
  • embedding_tokens:embedding 服务消耗的 token 数
  • embedding_latency_ms:embedding 调用耗时
  • search_latency_ms:Redis 向量检索耗时
  • error:失败或异常时的错误信息

这些字段会汇总到请求日志的 ext_fields.semantic_cache 中;对应索引说明见 日志扩展字段