跳到主要内容

语义缓存

语义缓存让 AISIX 在新请求与先前请求含义相同、措辞不同时也能返回缓存的响应。它是响应缓存的扩展:精确匹配层始终先被检查,语义层负责处理精确层未命中的请求。

在本指南中,你将为缓存策略添加语义配置块,验证精确命中与语义命中,并清空缓存条目。你还将了解跨网关实例共享语义条目所需的 Redis 版本要求。

语义缓存的工作原理

配置了 semantic 块的缓存策略会对每个符合条件的请求依次运行两个匹配层:

  1. **精确层。**首先查找请求指纹——模型别名、规范化后的 messages、采样参数以及其他影响响应的选项。完全相同的重复请求在此命中,无需任何 embedding 调用。
  2. **语义层。**精确层未命中时,AISIX 使用策略配置的 embedding 模型将请求的消息文本向量化,并与已存储的条目比较。相似度达到或超过阈值的最近条目会被返回;否则请求继续发往上游,响应连同其向量一起被存储。

只有 messages 内容参与相似度匹配。模型别名、采样参数以及其他指纹字段仍必须精确一致——换了 temperature 的同义改写请求不会复用条目。消息中包含图片、音频或工具结果的请求永远不会做相似度匹配,它们只使用精确层。

语义命中也不会刷新条目:条目与精确条目一样按策略 TTL 过期。

Embedding 失败时放行

语义匹配是一种优化,绝不是一道闸门。如果 embedding 调用失败或超时,请求会不经缓存直接发往上游,失败会计入缓存指标。如果 embedding 模型被删除或配置错误,策略会记录一条警告并继续只提供精确匹配。

准备工作

开始之前,请准备以下内容:

  • 一套可用的响应缓存环境:缓存策略管理路径(AISIX Cloud 或声明式资源文件)、模型别名和调用方 API Key。
  • 同一环境中的一个 embedding 模型。在 AISIX Cloud 中这是 kind 为 embedding 的模型;在资源文件中则是带 embedding 块的模型条目。它负责将请求文本向量化以做相似度比较;其 dimensions 值固定了该策略条目的向量维度。
  • 使用 Redis 后端的策略还需要支持向量检索的 Redis 部署——见使用 Redis 共享语义条目

导出共用的连接变量:

export AISIX_PROXY="YOUR_AISIX_GATEWAY_URL"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export AISIX_MODEL="gpt-4o-mini"

配置语义缓存策略

semantic 块在缓存策略上启用相似度层。阈值为必填项:它是条目被返回所需的最小余弦相似度,取值 [0, 1],越高越严格。低于约 0.9 时返回错误答案的风险明显上升;0.92 是一个不错的起点。

AISIX Cloud

导出控制面连接信息:

export AISIX_CP="YOUR_AISIX_CLOUD_ADMIN_API_BASE_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"

查询 embedding 模型的 ID,然后创建带 semantic 块的策略。Admin API 通过资源 ID 引用 embedding 模型:

export EMBED_MODEL_ID=$(curl -sS "$AISIX_CP/environments/$ENV_ID/models" \
-H "Authorization: Bearer $AISIX_TOKEN" |
jq -r '.data[] | select(.kind == "embedding") | .id' | head -1)

curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/cache_policies" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF | jq
{
"name": "semantic-chat-cache",
"enabled": true,
"backend": "memory",
"applies_to": "model:${AISIX_MODEL}",
"ttl_seconds": 3600,
"semantic": {
"embedding_model_id": "${EMBED_MODEL_ID}",
"threshold": 0.92
}
}
EOF

同样的配置也可以在 AISIX Cloud 控制台的缓存策略页面管理:启用语义匹配、选择 embedding 模型并调整阈值。

之后若想在不重建策略的情况下关闭语义层,在 PATCH 请求中发送 "semantic": null;省略该字段则保持配置不变。

开源 AISIX 网关

在资源文件中,语义块通过 display_name 引用 embedding 模型:

resources.yaml
models:
- display_name: text-embedder
provider: openai
model_name: text-embedding-3-small
provider_key: openai-prod
embedding:
dimensions: 1536

cache_policies:
- name: semantic-chat-cache
enabled: true
backend: memory
applies_to: "model:gpt-4o-mini"
ttl_seconds: 3600
semantic:
embedding_model: text-embedder
threshold: 0.92

校验完整的资源文件,然后重载网关。

可选语义参数

字段默认值行为
max_entries1000memory 后端下每个策略存储条目的上限(1–10000),最旧的条目先被淘汰。共享后端按 TTL 控制规模并忽略此值。
embedding_timeout_msembedding 调用的单次超时。超时后请求不经缓存直接发往上游。

验证语义命中

先发送一个请求,然后用不同的措辞重复同一个意思。响应头会区分两个匹配层:

curl -sSi -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
--data '{"model": "'"$AISIX_MODEL"'", "messages": [{"role": "user", "content": "How do I reset my password?"}]}'

第一个请求报告未命中并存储响应:

x-aisix-cache: miss

重复完全相同的请求,它命中精确层:

x-aisix-cache: hit
x-aisix-cache-layer: exact

现在改写提示词:

curl -sSi -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
--data '{"model": "'"$AISIX_MODEL"'", "messages": [{"role": "user", "content": "What are the steps to reset a password?"}]}'

如果相似度超过阈值,响应来自语义层,不产生上游调用:

x-aisix-cache: hit
x-aisix-cache-layer: semantic
x-aisix-cache-similarity: 0.9714

x-aisix-cache-similarity 报告匹配条目的余弦相似度。如果改写反而未命中,请谨慎调低阈值,或确认两个请求使用了完全相同的采样参数。

语义命中还会把新措辞回填到精确层,因此重复同一改写会直接命中精确层。

调优阈值

0.92 起步,用真实流量调整:

  • 返回了错误答案(不同的问题被当成同一个):把阈值向 0.970.99 调高。
  • 同义改写未命中(同一个问题重复走上游):逐步调低并观察质量。开放式流量避免低于 0.9
  • 合适的取值取决于 embedding 模型。更换 embedding 模型后需要重新调优——不同模型的分数不可比。更换 embedding 模型同时会使既有语义条目失效,因为不同模型产生的向量无法比较。

x-aisix-cache-similarity 响应头做校准:发送已知等价和已知不同的提示词对,观察它们的分数。

选择共享范围

策略的 scope 决定谁可以共享缓存条目,对两个匹配层同时生效:

Scope行为
api_key默认值。条目仅对写入它的调用方 API Key 可见——一个调用方的回答绝不会回放给另一个调用方。
env环境内所有调用方 API Key 共享条目。

除非所有调用方等价,否则保持默认的 api_key。语义匹配让跨调用方复用比精确匹配风险更高:对另一个用户问题的同义改写,可能命中为那个用户的上下文生成的响应。只有 FAQ、文档问答这类共享知识型流量——跨调用方复用正是其目的——才选择 env

按请求绕过缓存

调用方可以用标准的 Cache-Control 请求指令为单个请求跳过缓存,无需改动策略——见按请求绕过缓存no-cache 跳过两个匹配层并刷新存储的条目;no-store 还会抑制写入。

清空缓存条目

清空操作会使策略存储的所有条目失效——两个匹配层、所有网关实例——而不删除策略本身:

curl -sS -X POST \
"$AISIX_CP/environments/$ENV_ID/cache_policies/$CACHE_POLICY_ID/purge" \
-H "Authorization: Bearer $AISIX_TOKEN" | jq

响应返回 purge_generation 递增后的策略。更新后的配置一经传播,网关就把更早代次的条目视为已删除;存储空间在后台回收。控制台在每个策略行上以清空按钮提供同一操作。

资源文件部署方式下,在策略条目上添加 purge_generation 字段并在每次清空时递增:

resources.yaml
cache_policies:
- name: semantic-chat-cache
# ...
purge_generation: 1

使用 Redis 共享语义条目

memory 后端下每个网关实例维护自己的条目。要跨实例共享两个缓存层,按使用 Redis 共享缓存条目的说明使用 backend: redis 加上网关的 cache.redis 启动配置。

语义层对 Redis 有额外要求:

  • Redis 8 或更高版本(或带 search 模块的 Redis Stack 部署)。网关把向量存进向量索引并运行 KNN 相似度查询。
  • **singlesentinel 模式。**语义条目不支持 Redis Cluster。

网关启动时会探测 Redis 部署是否支持向量检索。探测失败——旧版 Redis、缺少模块或 cluster 模式——时,该后端上的策略继续只提供精确匹配并记录一条警告。精确层共享不受影响,仅相似度层被禁用。

精确层与语义层在 Redis 上保持一致:条目存储在同一键空间下,清空代次同时作用于两层,TTL 与策略一致。

可观测性

缓存行为在三个层面可见:

  • 响应头x-aisix-cachehit / miss / bypass)、x-aisix-cache-layer(命中时为 exact / semantic)、x-aisix-cache-similarity(仅语义命中)。见响应头与错误码
  • Prometheus 指标aisix_cache_requests_total 按策略统计结果(hit_exact / hit_semantic / miss / bypass),aisix_cache_semantic_* 系列跟踪 embedding 延迟与失败模式。命中率查询见指标参考
  • 用量事件:缓存响应把命中层记录在 cache_hit_layer,语义命中的相似度记录在 cache_similarity,导出的记录可以据此归因节省的上游调用。

后续步骤

你已经启用语义缓存并验证了按层归因的缓存命中。接下来:

  • 回顾响应缓存中的后端选择、applies_to 作用域以及仍然约束语义匹配的精确层指纹规则。
  • 通过指标参考观察语义命中率,并在扩大策略范围之前调优阈值。