这一部分将指导您设置Weaviate VectorStore,以存储文档嵌入并执行相似度搜索。

Weaviate是什么?

链接:https://weaviate.io/ [Weaviate] 是一个开源向量数据库。它允许您存储数据对象和来自您最喜爱的机器学习模型的向量嵌入,并且可以无缝扩展到数十亿个数据对象。它提供了存储文档嵌入、内容和元数据的工具,并可以通过这些嵌入进行搜索,包括元数据过滤。

先决条件

  1. 使用`EmbeddingClient`实例来计算文档嵌入。有多种选项可用:

    • "`Transformers Embedding` - 在你的本地环境中计算嵌入。请按照ONNX Transformers嵌入指南操作。"

    • OpenAI Embedding` - 使用OpenAI嵌入端点。您需要在OpenAI Signup处创建一个账户,并在API Keys生成api-key令牌。

    • 您也可以使用`Azure OpenAI嵌入`或者`PostgresML嵌入客户端`。

  2. Weaviate cluster`。您可以在Docker容器中本地设置一个集群,或者创建一个Weaviate Cloud Service。对于后者,您需要创建一个Weaviate账户,设置一个集群,并从dashboard details获取您的访问API密钥。

在启动时,如果尚未配置,WeaviateVectorStore 会创建所需的 SpringAiWeaviate 对象模式。

依赖项

将这些依赖项添加到您的项目中:

  • 嵌入式客户端引导启动器,计算嵌入所必需的。

  • 将 '''Transformers Embedding (Local)''' 按照ONNX Transformers Embedding的指导进行操作。

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

或者使用OpenAI(云服务)

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

你需要提供你的OpenAI API密钥。像这样将其设置为环境变量:

export SPRING_AI_OPENAI_API_KEY='Your_OpenAI_API_Key'
  • 添加Weaviate VectorStore依赖项

<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-weaviate-store</artifactId>
</dependency>
Tip
参考依赖管理部分,在您的构建文件中添加Spring AI BOM。

使用方法

创建一个连接到本地Weaviate集群的WeaviateVectorStore实例:

@Bean
public VectorStore vectorStore(EmbeddingClient embeddingClient) {
  WeaviateVectorStoreConfig config = WeaviateVectorStoreConfig.builder()
     .withScheme("http")
     .withHost("localhost:8080")
     // Define the metadata fields to be used
     // in the similarity search filters.
     .withFilterableMetadataFields(List.of(
        MetadataField.text("country"),
        MetadataField.number("year"),
        MetadataField.bool("active")))
     // Consistency level can be: ONE, QUORUM, or ALL.
     .withConsistencyLevel(ConsistentLevel.ONE)
     .build();

return new WeaviateVectorStore(config, embeddingClient);
}

你必须明确列出在过滤表达式中使用的任何元数据键的所有元数据字段名称和类型(BOOLEANTEXT`或`NUMBER)。 上面的 withFilterableMetadataKeys 注册了可过滤的元数据字段:country 的类型为 TEXTyear 的类型为 NUMBER,以及 active 的类型为 BOOLEAN。 如果可过滤的元数据字段扩展了新的条目,你必须重新上传/更新带有此元数据的文档。 您可以使用以下Weaviate链接:https://weaviate.io/developers/weaviate/api/graphql/filters#special-cases【系统元数据】字段无需显式定义:id_creationTimeUnix_lastUpdateTimeUnix

然后在你的主代码中,创建一些文档:

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", "active", true, "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", "active", false, "year", 2023)));

现在将文档添加到您的向量存储中:

vectorStore.add(List.of(document));

最后,检索与查询相似的文档:

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

如果一切顺利,你应该会找回包含文本“Spring AI rocks!!”的文档。

元数据过滤

您也可以利用通用、可移植的链接:https://docs.spring.io/spring-ai/reference/api/vectordbs.html#_metadata_filters[元数据过滤器] 与 WeaviateVectorStore 一起使用。

例如,你可以使用文本表达式语言:

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()));

便携式过滤表达式会自动转换为专有的Weaviate链接:https://weaviate.io/developers/weaviate/api/graphql/filters[where filters]。例如,以下的便携式过滤表达式:

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

被转换为Weaviate GraphQL链接:https://weaviate.io/developers/weaviate/api/graphql/filters[where过滤表达式]:

operator:And
   operands:
      [{
         operator:Or
         operands:
            [{
               path:["meta_country"]
               operator:Equal
               valueText:"UK"
            },
            {
               path:["meta_country"]
               operator:Equal
               valueText:"NL"
            }]
      },
      {
         path:["meta_year"]
         operator:GreaterThanEqual
         valueNumber:2020
      }]

在Docker容器中运行Weaviate集群

在Docker容器中启动Weaviate:

docker run -it --rm --name weaviate -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true -e PERSISTENCE_DATA_PATH=/var/lib/weaviate -e QUERY_DEFAULTS_LIMIT=25 -e DEFAULT_VECTORIZER_MODULE=none -e CLUSTER_HOSTNAME=node1 -p 8080:8080 semitechnologies/weaviate:1.22.4

http://localhost:8080/v1 启动一个Weaviate集群,使用的协议是http,主机地址是localhost:8080,apiKey=""。然后按照使用说明进行操作。