跳到主要内容

响应缓存

响应缓存允许 AISIX 在后续请求拥有相同缓存键时,复用之前的非流式 Chat Completions 响应。它是网关侧响应缓存,不是服务提供方 prompt 缓存,也不是托管配置快照缓存。

本指南将创建缓存策略,使用 x-aisix-cache 响应头验证缓存未命中和命中行为,并介绍缓存作用域和后端设置的工作方式。

准备工作

请先准备以下内容:

  • 一个 Admin 和代理监听器都可用的自托管 AISIX 网关。
  • 网关 config.yaml 中的 Admin Key。
  • 一个可以发送非流式 Chat Completions 请求的模型别名和调用方 API Key。
  • 安装 jq,用于打印缓存策略创建响应并捕获返回的 ID。

响应缓存的工作方式

响应缓存使用两层配置:

层级配置来源控制内容
缓存后端可用性启动配置网关进程可以使用哪些存储后端。
缓存策略动态缓存策略资源哪些非流式 Chat Completions 请求可以使用缓存,以及使用哪个可用后端。

只有两层配置都匹配时,响应才会被缓存。启动配置让后端可用,匹配的缓存策略为该请求选择后端。

AISIX 只缓存完全匹配的非流式 Chat Completions 响应。流式响应和其它代理 API 族不会使用该响应缓存路径。

配置缓存后端

AISIX 总会构建进程内内存缓存。当一个或多个缓存策略需要在多个网关实例之间共享缓存条目时,请添加 Redis 启动配置。

通过启动配置设置 Redis:

config.yaml
cache:
redis:
mode: single
url: redis://127.0.0.1:6379/

关于 AISIX 如何加载 config.yaml 并应用环境变量覆盖,参见配置文件

cache.backend 启动字段是旧版兼容设置,不再为所有请求选择一个全局缓存。如果设置 cache.backend: redis,AISIX 仍然要求存在 cache.redis 配置块;未配置 Redis 时启动会失败。

配置缓存策略

设置示例请求要使用的值:

export AISIX_ADMIN_KEY="admin-local-only-change-me"
export AISIX_API_KEY="sk-demo-caller"
export AISIX_MODEL="gpt-4o-mini"
export CACHE_PROMPT="cache-check-$(date +%s)"

为示例模型别名创建缓存策略,并保存响应:

CACHE_POLICY_RESPONSE=$(curl -sS -X POST "http://127.0.0.1:3001/admin/v1/cache_policies" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "default-chat-cache",
"enabled": true,
"backend": "memory",
"applies_to": "model:'"${AISIX_MODEL}"'",
"ttl_seconds": 3600
}')

打印响应并复制返回的 ID:

printf '%s\n' "${CACHE_POLICY_RESPONSE}" | jq .
CACHE_POLICY_ID=$(printf '%s\n' "${CACHE_POLICY_RESPONSE}" | jq -r '.id // empty')

你应该会看到类似下面的响应:

{
"id": "8d86d1cf-4a46-4a71-b4ef-c01e51f77f21",
"value": {
"name": "default-chat-cache",
"enabled": true,
"backend": "memory",
"ttl_seconds": 3600,
"applies_to": "model:gpt-4o-mini"
},
"revision": 1
}

返回的 ID 后续会用于删除策略。

验证缓存行为

缓存策略配置完成后,发送重复请求,对比缓存未命中和命中行为。

首先,使用缓存提示词发送请求:

curl -sSi -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"messages": [{"role": "user", "content": "'"${CACHE_PROMPT}"'"}]
}'

第一次匹配请求应该包含以下响应头:

x-aisix-cache: miss

miss 表示 AISIX 调用了上游服务提供方,并把响应写入缓存。

使用相同请求体和模型别名重复请求:

curl -sSi -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"messages": [{"role": "user", "content": "'"${CACHE_PROMPT}"'"}]
}'

重复请求应该包含以下响应头:

x-aisix-cache: hit

hit 表示 AISIX 直接返回了缓存副本,没有调用上游服务提供方。

修改提示词,确认缓存键与请求体绑定:

curl -sSi -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"messages": [{"role": "user", "content": "'"${CACHE_PROMPT}"' different"}]
}'

变更后的请求应该返回缓存未命中。

测试完成后删除缓存策略:

curl -sS -X DELETE "http://127.0.0.1:3001/admin/v1/cache_policies/${CACHE_POLICY_ID}" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}"

删除策略会禁用该作用域的缓存。网关重启时,内存缓存条目会被丢弃。

缓存策略作用域

applies_to 字段控制哪些请求匹配缓存策略:

作用域
all所有符合条件的非流式 Chat Completions 请求。
model:<alias>使用调用方可见模型别名的请求。
api_key:<id>使用调用方 API Key 资源 ID 认证的请求。

对于多目标模型,缓存键使用调用方请求的别名,而不是处理未命中的目标模型。

建议先从较窄的策略开始,例如模型作用域或调用方 API Key 作用域策略。只有当环境中所有符合条件的 Chat Completions 请求都应该参与响应缓存时,才使用全局策略。

请避免使用不支持的匹配前缀。网关会把未知形式当作全局作用域处理,因此拼写错误可能让策略范围比预期更宽。

选择缓存后端

每个缓存策略上的 backend 字段用于选择匹配响应的存储位置:

后端行为
memory使用处理未命中的网关实例上的进程内缓存。
redis当启动时配置了 cache.redis,使用共享 Redis 缓存。

单实例部署或可以接受节点本地缓存条目的策略可以使用 memory。当多个网关实例需要为同一策略共享缓存响应时,请使用 Redis。

如果匹配策略选择 Redis,但网关进程启动时没有配置 cache.redis,AISIX 会禁用该策略匹配请求的缓存,不会静默回退到 memory。

cache.redis.mode 字段支持与限流后端相同的 Redis 连接模式:

config.yaml
cache:
redis:
mode: cluster
nodes:
- redis://10.0.0.1:6379/
- redis://10.0.0.2:6379/

单个 Redis 端点使用 single,Redis Cluster 种子节点使用 cluster,由 Sentinel 管理的主节点使用带有 sentinelsmaster_namesentinel。完整模式示例参见 Redis 连接模式

查看缓存行为

如果没有出现缓存响应头,请检查三个缓存条件是否都满足:所选后端可用、启用的缓存策略匹配请求、请求是非流式 Chat Completions 请求。

如果策略作用范围比预期更宽,请检查其作用域。未知匹配前缀会回退为全局作用域,因此请只使用上面列出的受支持匹配值。

下一步

你已经配置了响应缓存策略,并验证了未命中与命中行为。接下来继续阅读安全护栏,在服务提供方调用前后添加请求和响应检查。