ai-cache
ai-cache 插件会缓存 LLM 服务的响应, 使重复请求直接从缓存返回,而不再次调用上游模型。这可以降低重复提示词的响应延迟,并减少上游 Token 用量。
该插件支持精确匹配缓存:仅当规范化后的请求与此前缓存的某个请求完全相同时,才会复用其响应。它还可以启用语义缓存层,在精确匹配未命中后通过 RediSearch 比较提示词向量嵌入。
按请求格式处理
插件会将检测到的不同请求格式保存在不同的缓存条目中。
网关会先检查 URI 特定规则,再检查仅基于请求体的规则,以识别请求格式:
- Bedrock Converse 要求 URI 以
/converse结尾且包含messages数组。 - Anthropic Messages 要求 URI 以
/v1/messages结尾。 - Responses API 要求 URI 以
/v1/responses结尾且包含input字段。 - Chat Completions 使用
messages数组。 - 当前面的规则均不匹配时,Embeddings 使用
input。 - 当前面的规则均不匹配时,其他非空 JSON 对象使用透传格式。
| 请求格式 | 精确匹配缓存 | 语义缓存 |
|---|---|---|
| Bedrock Converse | 支持 | 绕过 |
| Anthropic Messages | 支持 | 绕过 |
| Responses API | 支持 | 绕过 |
| Chat Completions | 支持 | 支持 |
| Embeddings | 支持 | 绕过 |
| 其他 JSON(透传) | 支持 | 绕过 |
精确匹配缓存自 API7 企业版 3.9.16 或 3.10.2 起可用,并将从 APISIX 3.18.0 起可用。
语义缓存和流式响应缓存自 API7 企业版 3.9.16 或 3.10.3 起可用。
工作原理
ai-cache 插件必须与同一路由上的 ai-proxy 或 ai-proxy-multi 插件一起使用,因为它缓存的是这些插件所代理的 LLM 流量。
对于每个请求,插件会根据检测到的请求格式、请求体以及所选 AI 实例的配置计算缓存键。缓存键的作用域由 cache_key 配置。精确缓存条目存储在 Redis 中,并具有可配置的存活时间。
对于 Chat Completions 请求,语义缓存会在精确缓存未命中后运行。插件对配置的提示词窗口生成向量嵌入,并在 RediSearch 向量索引中查询足够相似的缓存响应。
插件会将 X-AI-Cache-Status 响应头设置为以下值之一:
HIT:找到有效的缓存响应并直接返回,不调用上游。X-AI-Cache-Age头会以秒为单位报告该缓存条目的存活时长。语义命中还会返回X-AI-Cache-Similarity。MISS:未找到缓存响应。请求被代理到上游,且大小在max_cache_body_size以内的成功响应(HTTP 200)会被缓存以供后续请求使用。BYPASS:此请求跳过缓存,例如因为它匹配了某条bypass_on规则、未选中任何 AI 实例,或响应无法安全捕获。
完整的 SSE 流式响应可以被缓存,并使用其流式 content type 重放。使用其他帧格式的流(例如 Bedrock ConverseStream 的 AWS 事件 流格式)会绕过缓存。
示例
以下示例使用 OpenAI 作为上游 LLM 服务,并使用一个 Redis 实例来存储缓存。在开始之前,请创建一个 OpenAI 账号 和 API Key,并确保网关能够访问到一个 Redis 实例。你可以选择将密钥保存到环境变量中:
export OPENAI_API_KEY=YOUR_OPENAI_API_KEY # 替换为你的 API Key
如果你使用其他模型服务提供方,请参考该提供方的文档获取 API Key。
缓存 LLM 响应
以下示例演示如何将 ai-cache 与 ai-proxy 配合配置,使重复的相同请求由 Redis 提供响应。
- Admin API
- ADC
- Ingress Controller
创建一个使用 ai-proxy 代理到 OpenAI、并使用 ai-cache 缓存响应的路由:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
--data-binary @- <<EOF
{
"id": "ai-cache-route",
"uri": "/anything",
"methods": ["POST"],
"plugins": {
"ai-proxy": {
"provider": "openai",
"auth": {
"header": {
"Authorization": "Bearer $OPENAI_API_KEY"
}
},
"options": {
"model": "gpt-4"
}
},
"ai-cache": {
"redis_host": "127.0.0.1",
"redis_port": 6379,
"exact": {
"ttl": 3600
}
}
}
}
EOF
❶ 在 Authorization 请求头中以 Bearer Token 形式附带 OpenAI API Key。
❷ 指定模型名称。
❸ 将缓存指向你的 Redis 实例。
❹ 将每个响应缓存一小时。
创建一个配置了 ai-proxy 和 ai-cache 插件的路由,如下所示:
services:
- name: ai-cache-service
routes:
- name: ai-cache-route
uris:
- /anything
methods:
- POST
plugins:
ai-proxy:
provider: openai
auth:
header:
Authorization: "Bearer ${OPENAI_API_KEY}"
options:
model: gpt-4
ai-cache:
redis_host: 127.0.0.1
redis_port: 6379
exact:
ttl: 3600
将配置 同步到网关:
adc sync -f adc.yaml
❶ 将服务提供方指定为 openai。
❷ 在 Authorization 请求头中以 Bearer Token 形式附带 OpenAI API Key。
❸ 指定模型名称。
❹ 将缓存指向你的 Redis 实例。
创建一个配置了 ai-proxy 和 ai-cache 插件的路由,如下所示:
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: ai-cache-plugin-config
spec:
plugins:
- name: ai-proxy
config:
provider: openai
auth:
header:
Authorization: "Bearer YOUR_OPENAI_API_KEY"
options:
model: gpt-4
- name: ai-cache
config:
redis_host: 127.0.0.1
redis_port: 6379
exact:
ttl: 3600
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: ai-cache-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
method: POST
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: ai-cache-plugin-config
将配置应用到集群:
kubectl apply -f ai-cache-ic.yaml
❶ 在 Authorization 请求头中以 Bearer Token 形式附带 OpenAI API Key。
❷ 指定模型名称。
❸ 将缓存指向你的 Redis 实例。
向路由发送请求:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "user", "content": "What is 1+1?" }
]
}'
第一个请求是缓存未命中,会被代理到 OpenAI。你应该收到 HTTP/1.1 200 OK 响应,其中包含以下响应头:
X-AI-Cache-Status: MISS
再次发送相同的请求。这一次响应直接从缓存返回,不会调用上游,并包含缓存状态和存活时长响应头:
X-AI-Cache-Status: HIT
X-AI-Cache-Age: 2