Spring AI 学习之路 向量数据库(Redis Stack)

Spring AI 作为 Spring 生态系统中用于构建 AI 应用的框架,提供了与多种向量数据库的集成支持。本文将详细介绍如何在 Spring AI 项目中集成 Redis Stack 作为向量数据库,并演示如何将文档写入向量库以及进行向量相似度搜索。

准备环境

在开始之前,请确保您已经完成以下准备工作:
Java 开发环境: 安装 JDK 8 或更高版本。
Maven 构建工具: 用于管理项目依赖。
Docker: 安装并运行 Docker。
Spring Boot 项目: 创建一个新的 Spring Boot 项目,或者使用现有的项目。

安装Redis Stack

使用 Docker 安装 Redis Stack,安装命令如下:

docker run -d --name redis-stack --restart=always  -v redis-data:/data -p 6379:6379 -p 8001:8001 -e REDIS_ARGS="--requirepass 123456" redis/redis-stack:latest

-d: 在后台运行容器。
--name redis-stack: 为容器指定名称。
-p 6379:6379: 将容器的 6379 端口映射到主机的 6379 端口,用于 Redis 连接。
-p 8001:8001: 将容器的 8001 端口映射到主机的 8001 端口,用于访问 RedisInsight (Redis 的可视化管理工具)。
-v redis-data:/data: 将容器中的redis-data目录映射到服务器的data目录
redis/redis-stack:latest: 使用最新版本的 Redis Stack 镜像。

添加依赖

在您的 Spring Boot 项目中,添加以下依赖项以集成 Spring AI 和 Redis Stack:

		<dependency>
			<groupId>com.alibaba.cloud.ai</groupId>
			<artifactId>spring-ai-alibaba-starter</artifactId>
			<version>1.0.0-M5.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.ai</groupId>
			<artifactId>spring-ai-redis-store</artifactId>
			<version>${spring-ai.version}</version>
		</dependency>

		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.ai</groupId>
			<artifactId>spring-ai-tika-document-reader</artifactId>
			<version>${spring-ai.version}</version>
		</dependency>

配置连接信息

在 application.properties 或 application.yml 文件中配置 Redis 连接信息:

Spring:
 data:
    redis:
      host: 192.168.57.185
      port: 10033
      database: 0
      timeout: 10s
      lettuce:
        pool:
          # 连接池最大连接数
          max-active: 200
          # 连接池最大阻塞等待时间(使用负值表示没有限制)
          max-wait: -1ms
          # 连接池中的最大空闲连接
          max-idle: 10
          # 连接池中的最小空闲连接
          min-idle: 0
      repositories:
        enabled: false
      password: 123456

配置向量数据库

定义Redis Vector的配置类,以下是一个完整的 RedisVectorConfig 配置类的示例,以及如何在 Spring Boot 项目中集成它:

@Configuration
// 禁用SpringAI提供的RedisStack向量数据库的自动配置,会和Redis的配置冲突。
@EnableAutoConfiguration(exclude = {RedisVectorStoreAutoConfiguration.class})
// 读取RedisStack的配置信息
@EnableConfigurationProperties({RedisVectorStoreProperties.class})
@AllArgsConstructor
public class RedisVectorConfig {

    /**
     * 创建并配置JedisPooled实例
     * 该方法通过Spring的@Bean注解定义了一个Bean,使得Spring IoC容器可以管理该Bean的生命周期和依赖
     * JedisPooled是一个封装了Jedis连接池的类,用于高效地管理Redis连接
     *
     * @param redisConnectionDetails Redis连接详情,包含了连接Redis所需的信息,如主机、端口、用户名和密码
     * @return 返回一个配置好的JedisPooled实例,用于与Redis进行交互
     */
    @Bean
    public JedisPooled jedisPooled(RedisConnectionDetails redisConnectionDetails) {
        // 使用从redisConnectionDetails中提取的连接信息初始化JedisPooled实例
        // 包括主机、端口、用户名和密码,这些信息是连接Redis服务器所必需的
        return new JedisPooled(redisConnectionDetails.getStandalone().getHost(),
                redisConnectionDetails.getStandalone().getPort(),
                redisConnectionDetails.getUsername(),
                redisConnectionDetails.getPassword());
    }

    /**
     * 创建RedisStack向量数据库
     *
     * @param embeddingModel 嵌入模型
     * @param properties     redis-stack的配置信息
     * @return vectorStore 向量数据库
     */
    @Bean(name = "redisVectorStore")
    public VectorStore vectorStore(JedisPooled jedisPooled, EmbeddingModel embeddingModel,
                                   RedisVectorStoreProperties properties,
                                   RedisConnectionDetails redisConnectionDetails) {
        return RedisVectorStore.builder(jedisPooled, embeddingModel)
                .indexName(properties.getIndex())                // Optional: defaults to "spring-ai-index"
                .prefix(properties.getPrefix())                  // Optional: defaults to "embedding:"
                .initializeSchema(true)                   // Optional: defaults to false
                .batchingStrategy(new TokenCountBatchingStrategy())// Optional: defaults to TokenCountBatchingStrategy
                .build();
    }
}

文档嵌入

在上面的 VectorStore 配置中我们提供了EmbeddingModel,调用vectorStore.add(splitDocuments)底层会把文档给EmbeddingModel把文本变成向量然后再存入向量数据库。

/**
     * 描述:处理文件以提取和存储文档嵌入
     * 使用SneakyThrows注解来处理可能的异常,避免显式地捕获和处理
     * 使用PostMapping注解来处理POST请求,路径为"embedding"
     * 
     * 参数:file - 上传的文件,类型为MultipartFile
     * 返回值:一个ResultEntity<Boolean>对象,表示操作是否成功
     * 
     * 功能:读取上传的文件内容,将其拆分成多个文档,并存储到Redis中
     */
    @SneakyThrows
    @PostMapping("embedding")
    public ResultEntity<Boolean> embedding(@RequestParam MultipartFile file) {
        // 使用TikaDocumentReader读取上传的文件内容
        TikaDocumentReader tikaDocumentReader = new TikaDocumentReader(new InputStreamResource(file.getInputStream()));
        // 将读取的文档内容拆分成多个文档
        List<Document> splitDocuments = new TokenTextSplitter().apply(tikaDocumentReader.read());
        // 将拆分后的文档添加到Redis存储中
        redisVectorStore.add(splitDocuments);
    
        // 返回操作成功的结果
        return ResultUtils.success(true);
    }

文档查询

们可以使用 VectorStore 接口提供的 similaritySearch 方法进行向量相似度搜索:

	/**
     * 处理查询请求,根据给定的查询字符串返回最相似的文档列表
     * 该方法使用GET请求来检索与查询字符串最匹配的文档,利用Redis矢量存储进行相似性搜索
     *
     * @param query 查询字符串,用户输入的用于搜索相似文档的文本
     * @return 包含相似文档的列表
     */
    @GetMapping("query")
    public List<Document> query(@RequestParam String query) {
        return this.redisVectorStore.similaritySearch(query);
    }

总结

本文介绍了如何在 Spring AI 项目中集成 Redis Stack 作为向量数据库,并使用 Docker 安装和运行 Redis Stack。通过使用 Spring AI 和 Redis Stack,您可以轻松构建基于向量搜索的智能应用,例如语义搜索、推荐系统等。

参考

pring AI Documentation
Redis Stack Documentation
Docker Documentation

posted @ 2025-03-12 17:18  brother_four  阅读(1447)  评论(0)    收藏  举报