Redis

本節將引導您設定 RedisVectorStore 以儲存文件嵌入 (document embeddings) 並執行相似性搜尋。

Redis 是一個開放原始碼 (BSD 授權)、記憶體內資料結構儲存,可用作資料庫、快取、訊息代理和串流引擎。Redis 提供資料結構,例如字串、雜湊、列表、集合、具有範圍查詢的排序集合、位元圖、HyperLogLogs、地理空間索引和串流。

Redis Search and Query 擴展了 Redis OSS 的核心功能,並允許您將 Redis 用作向量資料庫

  • 在雜湊或 JSON 文件中儲存向量和相關的元數據

  • 檢索向量

  • 執行向量搜尋

先決條件

  1. Redis Stack 實例

  2. EmbeddingModel 實例,用於計算文件嵌入。有多種選項可用

    • 如果需要,EmbeddingModel 的 API 金鑰,用於生成 RedisVectorStore 儲存的嵌入。

自動配置

Spring AI 為 Redis 向量儲存 (Vector Store) 提供 Spring Boot 自動配置。若要啟用它,請將以下相依性新增至您專案的 Maven pom.xml 檔案

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-redis-store-spring-boot-starter</artifactId>
</dependency>

或新增至您的 Gradle build.gradle 建置檔案。

dependencies {
    implementation 'org.springframework.ai:spring-ai-redis-store-spring-boot-starter'
}
請參考相依性管理章節,將 Spring AI BOM 新增至您的建置檔案。
請參考儲存庫 (Repositories) 章節,將 Milestone 和/或 Snapshot 儲存庫新增至您的建置檔案。

向量儲存實作可以為您初始化必要的 schema,但您必須選擇加入,方法是在適當的建構子中指定 initializeSchema 布林值,或在 application.properties 檔案中設定 …​initialize-schema=true

這是一個重大變更!在 Spring AI 的早期版本中,此 schema 初始化是預設發生的。

此外,您將需要一個已配置的 EmbeddingModel Bean。請參考 EmbeddingModel 章節以取得更多資訊。

以下是所需 Bean 的範例

@Bean
public EmbeddingModel embeddingModel() {
    // Can be any other EmbeddingModel implementation.
    return new OpenAiEmbeddingModel(new OpenAiApi(System.getenv("SPRING_AI_OPENAI_API_KEY")));
}

若要連接到 Redis,您需要提供您實例的存取詳細資訊。可以透過 Spring Boot 的 application.properties 提供簡單的配置,

spring.ai.vectorstore.redis.uri=<your redis instance uri>
spring.ai.vectorstore.redis.index=<your index name>
spring.ai.vectorstore.redis.prefix=<your prefix>

# API key if needed, e.g. OpenAI
spring.ai.openai.api.key=<api-key>

請查看 配置參數 列表,以了解向量儲存的預設值和配置選項。

現在您可以在您的應用程式中自動注入 (Auto-wire) Redis 向量儲存並使用它

@Autowired VectorStore vectorStore;

// ...

List <Document> documents = List.of(
    new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
    new Document("The World is Big and Salvation Lurks Around the Corner"),
    new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));

// Add the documents to Redis
vectorStore.add(documents);

// Retrieve documents similar to a query
List<Document> results = this.vectorStore.similaritySearch(SearchRequest.query("Spring").withTopK(5));

配置屬性

您可以在您的 Spring Boot 配置中使用以下屬性來自訂 Redis 向量儲存。

屬性 描述 預設值

spring.ai.vectorstore.redis.uri

伺服器連線 URI

redis://127.0.0.1:6379

spring.ai.vectorstore.redis.index

索引名稱

default-index

spring.ai.vectorstore.redis.initialize-schema

是否初始化所需的 schema

false

spring.ai.vectorstore.redis.prefix

前綴

default

元數據過濾

您也可以將通用的、可移植的 元數據篩選器 與 RedisVectorStore 一起使用。

例如,您可以使用文字表達式語言

vectorStore.similaritySearch(
   SearchRequest
      .query("The World")
      .withTopK(TOP_K)
      .withSimilarityThreshold(SIMILARITY_THRESHOLD)
      .withFilterExpression("country in ['UK', 'NL'] && year >= 2020"));

或以程式設計方式使用表達式 DSL

FilterExpressionBuilder b = new FilterExpressionBuilder();

vectorStore.similaritySearch(
   SearchRequest
      .query("The World")
      .withTopK(TOP_K)
      .withSimilarityThreshold(SIMILARITY_THRESHOLD)
      .withFilterExpression(b.and(
         b.in("country", "UK", "NL"),
         b.gte("year", 2020)).build()));

可移植的篩選表達式會自動轉換為 Redis 搜尋查詢。例如,以下可移植的篩選表達式

country in ['UK', 'NL'] && year >= 2020

會轉換為 Redis 查詢

@country:{UK | NL} @year:[2020 inf]

手動配置

如果您不想使用自動配置,您可以手動配置 Redis 向量儲存。新增 Redis 向量儲存和 Jedis 相依性

<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-redis-store</artifactId>
</dependency>

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>5.1.0</version>
</dependency>
請參考相依性管理章節,將 Spring AI BOM 新增至您的建置檔案。

然後,在您的 Spring 配置中建立 RedisVectorStore Bean

@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
  RedisVectorStoreConfig config = RedisVectorStoreConfig.builder()
     .withURI("redis://127.0.0.1:6379")
     // Define the metadata fields to be used
     // in the similarity search filters.
     .withMetadataFields(
        MetadataField.tag("country"),
        MetadataField.numeric("year"))
     .build();

  return new RedisVectorStore(config, embeddingModel);
}

RedisVectorStore 建立為 Bean 會更方便且是較佳的方式。但是,如果您決定手動建立它,則必須在設定屬性之後和使用用戶端之前呼叫 RedisVectorStore#afterPropertiesSet()

您必須明確列出所有元數據欄位名稱和類型 (TAGTEXTNUMERIC),用於篩選表達式中的任何元數據欄位。上面的 withMetadataFields 註冊了可篩選的元數據欄位:類型為 TAGcountry,類型為 NUMERICyear

然後在您的主要程式碼中,建立一些文件

List<Document> documents = List.of(
   new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("country", "UK", "year", 2020)),
   new Document("The World is Big and Salvation Lurks Around the Corner", Map.of()),
   new Document("You walk forward facing the past and you turn back toward the future.", Map.of("country", "NL", "year", 2023)));

現在將文件新增至您的向量儲存

vectorStore.add(documents);

最後,檢索與查詢相似的文件

List<Document> results = vectorStore.similaritySearch(
   SearchRequest
      .query("Spring")
      .withTopK(5));

如果一切順利,您應該會檢索到包含文字 "Spring AI rocks!!" 的文件。