Files
higress/plugins/wasm-go/extensions/ai-cache/README.md
2025-03-29 20:11:48 +08:00

15 KiB
Raw Blame History

简介


title: AI 缓存 keywords: [higress,ai cache] description: AI 缓存插件配置参考

Note

需要数据面的proxy wasm版本大于等于0.2.100 编译时需要带上版本的tag例如tinygo build -o main.wasm -scheduler=none -target=wasi -gc=custom -tags="custommalloc nottinygc_finalizer proxy_wasm_version_0_2_100" ./

功能说明

LLM 结果缓存插件,默认配置方式可以直接用于 openai 协议的结果缓存,同时支持流式和非流式响应的缓存。

提示

携带请求头x-higress-skip-ai-cache: on时,当前请求将不会使用缓存中的内容,而是直接转发给后端服务,同时也不会缓存该请求返回响应的内容

运行属性

插件执行阶段:认证阶段 插件执行优先级:10

配置说明

配置分为 3 个部分向量数据库vector文本向量化接口embedding缓存数据库cache同时也提供了细粒度的 LLM 请求/响应提取参数配置等。

配置说明

本插件同时支持基于向量数据库的语义化缓存和基于字符串匹配的缓存方法,如果同时配置了向量数据库和缓存数据库,优先使用缓存数据库,未命中场景下使用向量数据库能力。

Note: 向量数据库(vector) 和 缓存数据库(cache) 不能同时为空,否则本插件无法提供缓存服务。

Name Type Requirement Default Description
vector string optional "" 向量存储服务提供者类型,例如 dashvector
embedding string optional "" 请求文本向量化服务类型,例如 dashscope
cache string optional "" 缓存服务类型,例如 redis
cacheKeyStrategy string optional "lastQuestion" 决定如何根据历史问题生成缓存键的策略。可选值: "lastQuestion" (使用最后一个问题), "allQuestions" (拼接所有问题) 或 "disabled" (禁用缓存)
enableSemanticCache bool optional true 是否启用语义化缓存, 若不启用则使用字符串匹配的方式来查找缓存此时需要配置cache服务

根据是否需要启用语义缓存,可以只配置组件的组合为:

  1. cache: 仅启用字符串匹配缓存
  2. vector (+ embedding): 启用语义化缓存, 其中若 vector 未提供字符串表征服务,则需要自行配置 embedding 服务
  3. vector (+ embedding) + cache: 启用语义化缓存并用缓存服务存储LLM响应以加速

注意若不配置相关组件,则可以忽略相应组件的required字段。

向量数据库服务vector

Name Type Requirement Default Description
vector.type string required "" 向量存储服务提供者类型,例如 dashvector
vector.serviceName string required "" 向量存储服务名称
vector.serviceHost string required "" 向量存储服务域名
vector.servicePort int64 optional 443 向量存储服务端口
vector.apiKey string optional "" 向量存储服务 API Key
vector.topK int optional 1 返回TopK结果默认为 1
vector.timeout uint32 optional 10000 请求向量存储服务的超时时间单位为毫秒。默认值是10000即10秒
vector.collectionID string optional "" 向量存储服务 Collection ID
vector.threshold float64 optional 1000 向量相似度度量阈值
vector.thresholdRelation string optional lt 相似度度量方式有 Cosine, DotProduct, Euclidean 等,前两者值越大相似度越高,后者值越小相似度越高。对于 CosineDotProduct 选择 gt,对于 Euclidean 则选择 lt。默认为 lt,所有条件包括 lt (less than小于)、lte (less than or equal to小等于)、gt (greater than大于)、gte (greater than or equal to大等于)

文本向量化服务embedding

Name Type Requirement Default Description
embedding.type string required "" 请求文本向量化服务类型,例如 dashscope
embedding.serviceName string required "" 请求文本向量化服务名称
embedding.serviceHost string optional "" 请求文本向量化服务域名
embedding.servicePort int64 optional 443 请求文本向量化服务端口
embedding.apiKey string optional "" 请求文本向量化服务的 API Key
embedding.timeout uint32 optional 10000 请求文本向量化服务的超时时间单位为毫秒。默认值是10000即10秒
embedding.model string optional "" 请求文本向量化服务的模型名称

缓存服务cache

cache.type string required "" 缓存服务类型,例如 redis
cache.serviceName string required "" 缓存服务名称
cache.serviceHost string required "" 缓存服务域名
cache.servicePort int64 optional 6379 缓存服务端口
cache.username string optional "" 缓存服务用户名
cache.password string optional "" 缓存服务密码
cache.timeout uint32 optional 10000 缓存服务的超时时间单位为毫秒。默认值是10000即10秒
cache.cacheTTL int optional 0 缓存过期时间,单位为秒。默认值是 0即 永不过期
cache.cacheKeyPrefix string optional "higress-ai-cache:" 缓存 Key 的前缀,默认值为 "higress-ai-cache:"
cache.database int optional 0 使用的数据库id仅限redis例如配置为1对应SELECT 1

其他配置

Name Type Requirement Default Description
cacheKeyFrom string optional "messages.@reverse.0.content" 从请求 Body 中基于 GJSON PATH 语法提取字符串
cacheValueFrom string optional "choices.0.message.content" 从响应 Body 中基于 GJSON PATH 语法提取字符串
cacheStreamValueFrom string optional "choices.0.delta.content" 从流式响应 Body 中基于 GJSON PATH 语法提取字符串
cacheToolCallsFrom string optional "choices.0.delta.content.tool_calls" 从请求 Body 中基于 GJSON PATH 语法提取字符串
responseTemplate string optional {"id":"ai-cache.hit","choices":[{"index":0,"message":{"role":"assistant","content":%s},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}} 返回 HTTP 响应的模版,用 %s 标记需要被 cache value 替换的部分
streamResponseTemplate string optional data:{"id":"ai-cache.hit","choices":[{"index":0,"delta":{"role":"assistant","content":%s},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}\n\ndata:[DONE]\n\n 返回流式 HTTP 响应的模版,用 %s 标记需要被 cache value 替换的部分

文本向量化提供商特有配置

Azure OpenAI

Azure OpenAI 所对应的 embedding.typeazure。它需要提前创建Azure OpenAI 账户,然后您需要在Azure AI Foundry中挑选一个模型并将其部署,点击您部署好的模型,您可以在终结点中看到目标 URI 以及密钥。请将 URI 中的 host 填入embedding.serviceHost,密钥填入apiKey

一个完整的 URI 示例为 https://YOUR_RESOURCE_NAME.openai.azure.com/openai/deployments/YOUR_DEPLOYMENT_NAME/embeddings?api-version=2024-10-21您需要将YOUR_RESOURCE_NAME.openai.azure.com填入embedding.serviceHost

它特有的配置字段如下:

名称 数据类型 填写要求 默认值 描述 填写值
embedding.apiVersion string 必填 - api版本 获取到的URI中api-version的值

需要注意的是您必须要指定embedding.serviceHost,如YOUR_RESOURCE_NAME.openai.azure.com。模型默认使用了text-embedding-ada-002,如需其他模型,请在embedding.model中进行指定。

Cohere

Cohere 所对应的 embedding.typecohere。它并无特有的配置字段。需要提前创建 API Key,并将其填入embedding.apiKey

OpenAI

OpenAI 所对应的 embedding.typeopenai。它并无特有的配置字段。需要提前创建 API Key,并将其填入embedding.apiKey,一个 API Key 的示例为 sk-xxxxxxx

Ollama

Ollama 所对应的 embedding.typeollama。它并无特有的配置字段。

Hugging Face

Hugging Face 所对应的 embedding.typehuggingface。它并无特有的配置字段。需要提前创建 hf_token,并将其填入embedding.apiKey,一个 hf_token 的示例为 hf_xxxxxxx

embedding.model默认指定为sentence-transformers/all-MiniLM-L6-v2

Textln

Textln 所对应的 embedding.typetextln。它需要提前获取app-idsecret-code

它特有的配置字段如下:

名称 数据类型 填写要求 默认值 描述 填写值
embedding.textinAppId string 必填 - 应用 ID 获取的 app-id
embedding.textinSecretCode string 必填 - 调用 API 所需 Secret 获取的 secret-code
embedding.textinMatryoshkaDim int 必填 - 返回的单个向量长度

讯飞星火

讯飞星火 所对应的 embedding.typexfyun。它需要提前创建应用,获取APPIDAPISecretAPIKey,并将APIKey填入embedding.apiKey中。

它特有的配置字段如下:

名称 数据类型 填写要求 默认值 描述 填写值
embedding.appId string 必填 - 应用 ID 获取的 APPID
embedding.apiSecret string 必填 - 调用 API 所需 Secret 获取的 APISecret

向量数据库提供商特有配置

Chroma

Chroma 所对应的 vector.typechroma。它并无特有的配置字段。需要提前创建 Collection并填写 Collection ID 至配置项 vector.collectionID,一个 Collection ID 的示例为 52bbb8b3-724c-477b-a4ce-d5b578214612

DashVector

DashVector 所对应的 vector.typedashvector。它并无特有的配置字段。需要提前创建 Collection并填写 Collection 名称 至配置项 vector.collectionID

ElasticSearch

ElasticSearch 所对应的 vector.typeelasticsearch。需要提前创建 Index 并填写 Index Name 至配置项 vector.collectionID

当前依赖于 KNN 方法,请保证 ES 版本支持 KNN,当前已在 8.16 版本测试。

它特有的配置字段如下:

名称 数据类型 填写要求 默认值 描述
vector.esUsername string 非必填 - ElasticSearch 用户名
vector.esPassword string 非必填 - ElasticSearch 密码

vector.esUsernamevector.esPassword 用于 Basic 认证。同时也支持 Api Key 认证,当填写了 vector.apiKey 时,则启用 Api Key 认证,如果使用 SaaS 版本需要填写 encoded 的值。

Milvus

Milvus 所对应的 vector.typemilvus。它并无特有的配置字段。需要提前创建 Collection并填写 Collection Name 至配置项 vector.collectionID

Pinecone

Pinecone 所对应的 vector.typepinecone。它并无特有的配置字段。需要提前创建 Index并填写 Index 访问域名至 vector.serviceHost

Pinecone 中的 Namespace 参数通过插件的 vector.collectionID 进行配置,如果不填写 vector.collectionID,则默认为 Default Namespace。

Qdrant

Qdrant 所对应的 vector.typeqdrant。它并无特有的配置字段。需要提前创建 Collection并填写 Collection Name 至配置项 vector.collectionID

Weaviate

Weaviate 所对应的 vector.typeweaviate。它并无特有的配置字段。 需要提前创建 Collection并填写 Collection Name 至配置项 vector.collectionID

需要注意的是 Weaviate 会设置首字母自动大写,在填写配置 collectionID 的时候需要将首字母设置为大写。

如果使用 SaaS 需要填写 vector.serviceHost 参数。

配置示例

基础配置

embedding:
  type: dashscope
  serviceName: my_dashscope.dns
  apiKey: [Your Key]

vector:
  type: dashvector
  serviceName: my_dashvector.dns
  collectionID: [Your Collection ID]
  serviceDomain: [Your domain]
  apiKey: [Your key]

cache:
  type: redis
  serviceName: my_redis.dns
  servicePort: 6379
  timeout: 100

旧版本配置兼容

redis:
  serviceName: my_redis.dns
  servicePort: 6379
  timeout: 100
  database: 1

进阶用法

当前默认的缓存 key 是基于 GJSON PATH 的表达式:messages.@reverse.0.content 提取,含义是把 messages 数组反转后取第一项的 content

GJSON PATH 支持条件判断语法,例如希望取最后一个 role 为 user 的 content 作为 key可以写成 messages.@reverse.#(role=="user").content

如果希望将所有 role 为 user 的 content 拼成一个数组作为 key可以写成messages.@reverse.#(role=="user")#.content

还可以支持管道语法,例如希望取到数第二个 role 为 user 的 content 作为 key可以写成messages.@reverse.#(role=="user")#.content|1

更多用法可以参考官方文档,可以使用 GJSON Playground 进行语法测试。

常见问题

  1. 如果返回的错误为 error status returned by host: bad argument,请检查serviceName是否正确包含了服务的类型后缀(.dns等)。