历史文章

Spring AI:对接DeepSeek实战
Spring AI:对接官方 DeepSeek-R1 模型 —— 实现推理效果
Spring AI:ChatClient实现对话效果
Spring AI:使用 Advisor 组件 - 打印请求大模型出入参日志
Spring AI:ChatMemory 实现聊天记忆功能
Spring AI:本地安装 Ollama 并运行 Qwen3 模型
Spring AI:提示词工程
Spring AI:提示词工程 - Prompt 角色分类(系统角色与用户角色)
Spring AI:基于 “助手角色” 消息实现聊天记忆功能
Spring AI:结构化输出 - 大模型响应内容
Spring AI:Docker 安装 Cassandra 5.x(限制内存占用)&& CQL
Spring AI:整合 Cassandra - 实现聊天消息持久化
Spring AI:多模态 AI 大模型
Spring AI:文生图:调用通义万相 AI 大模型
Spring AI:文生音频 - cosyvoice-V2
Spring AI:文生视频 - wanx2.1-i2v-plus
Spring AI:上手体验工具调用(Tool Calling)
Spring AI:整合 MCP Client - 调用高德地图 MCP 服务
Spring AI:搭建自定义 MCP Server:获取 QQ 信息
Spring AI:对接自定义 MCP Server
Spring AI:RAG 增强检索介绍
Spring AI:Docker 安装向量数据库 - Redis Stack

上文中,我们已经在本地环境中,将 Redis 向量数据库安装好了。本文中,我们尝试将一些文档,通过 “向量模型” 进行向量化处理,并存储到 Redis 数据库中,最后通过关键词进行检索,看看能否将相似的文档检索出来。

新建项目

新建一个Spring Boot项目,xiaoma-vector-store-search

①:选择 Spring Boot 生成器来创建项目;
②:项目名称填写 xiaoma-vector-store-search;
③: 项目存放位置,选择之前创建好的文件夹;
④:项目构建方式选择 Maven;
⑤:填写 Group 组织名称,通常为公司域名倒写,如 com.xiaoma;
⑥: 项目唯一标识符,这里填写 xiaoma-vector-store-search;
⑦: 包名填写 com.xiaoma.vector.store;
⑧: JDK 版本选择 21 版本;
⑨: Java 语言版本也选择 21, 和 JDK 保持一致;

修改 pom

接着,编辑 pom.xml 文件,首先将 Spring Boot 的版本号修改为 3.4.5。另外,添加 Spring AI 框架的依赖管理、 lombok 工具依赖、仓库地址等,如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.xiaoma</groupId>
    <artifactId>xiaoma-vector-store-search</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>xiaoma-vector-store-search</name>
    <description>向量存储与检索</description>
    <properties>
        <!-- JDK 版本 -->
        <java.version>21</java.version>
        <!-- Spring AI 版本 -->
        <spring-ai.version>1.0.0</spring-ai.version>
        <lombok.version>1.18.30</lombok.version>
    </properties>

    <!-- Spring AI 依赖管理   -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 避免编写那些冗余的 Java 样板式代码,如 get、set 方法等 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>

        <!-- 添加华为云、阿里云 maven 中央仓库,提升 Jar 包下载速度 -->
        <repository>
            <id>huaweicloud</id>
            <name>huawei</name>
            <url>https://mirrors.huaweicloud.com/repository/maven/</url>
        </repository>
        <repository>
            <id>aliyunmaven</id>
            <name>aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
    </repositories>

</project>

选择向量模型

我们需要先挑选一个 “向量模型”,它够将文本、图像、视频等数据转换为数学空间中的向量。通过计算向量之间的距离或夹角,可以量化数据的相似度,从而作用于精准搜索、智能推荐、自动分类及异常检测等任务。

登陆到 “阿里百炼 ” 的模型广场,筛选 “向量模型” 分类下所有大模型,如下图所示:

在这里插入图片描述
这里我们选择最新的 “通用文本向量-v4” 模型,点击 “API参考”,可以知道此模型的具体名称为 text-embedding-v4 , 将其复制出来。

添加依赖

<!-- OpenAI -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

<!-- 整合向量数据库 Redis -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-vector-store-redis</artifactId>
</dependency>

记得刷新一下 pom.xml 文件,将依赖下载到本地 Maven 仓库中。

添加配置

添加文件application.yml

然后,将 application.properties 重命名为 application.yml,添加配置项如下,包括 Redis 链接、阿里百炼接入配置、使用的哪个向量模型、以及向量数据库的相关设置:

server:
  port: 8090 # 项目启动端口

spring:
  data:
    redis:
      host: localhost # Redis URL 链接
      port: 6379 # Redis 端口
  ai:
    openai:
      base-url: https://dashscope.aliyuncs.com/compatible-mode # OpenAI 服务的访问地址,这里使用的是阿里云百炼
      api-key: xxx  # 填写阿里百炼的 API Key, 改成你自己的
      embedding:
        options:
          model: text-embedding-v4 # 向量模型
    vectorstore:
      redis:
        initialize-schema: true # 是否初始化模式
        index-name: xiaoma-ai-index # 自定义索引名称
        prefix: embedding # 自定义键名前缀

文档向量化处理,并存入 Redis

接着,在后端项目中新建一个 /runner 包,并新建一个 InitEmbeddingIndexRunner 启动任务,用于在项目刚启动时,将 3 条文档进行向量化处理,并存储到 Redis 中:

@Component
public class InitEmbeddingIndexRunner implements ApplicationRunner {

    @Resource
    private VectorStore vectorStore;

    @Override
    public void run(ApplicationArguments args) {
        // 定义 3 条文档
        List<Document> documents = List.of(
                new Document("冰箱首次使用指南:拆箱后静置24小时再通电,调节温控器至4℃冷藏室、-18℃冷冻室。清洁内胆时请使用中性洗涤剂。",
                        Map.of("章节", "安全须知", "版本", "2025")),
                new Document("节能技巧:避免频繁开关门,热食冷却后再放入,定期除霜可提升制冷效率。建议每月清洁一次冷凝器。"),
                new Document("故障代码手册:E1温度传感器异常,E2化霜故障,F1通讯错误。遇到E2代码请断电2小时后重启,若持续出现需联系售后。",
                        Map.of("章节", "故障处理", "紧急程度", "高"))
        );

        // 通过向量模型,将文档向量化存储到 Redis 中
        vectorStore.add(documents);
    }
}

测试

重启后端项目,观察控制台日志,确保启动没有任何报错:

然后,查看 Redis 数据库,如下图所示,不出意外,3条文档的向量化数据已经存储成功了:

在这里插入图片描述

检索向量数据库

接下来,我们再新建一个 /controller 包,并新建 VectorSearchController 控制器,声明 /vector/search 接口,用于根据对应关键词来检索向量数据库,代码如下:

@RestController
@RequestMapping("/vector")
public class VectorSearchController {

    @Resource
    private VectorStore vectorStore;

    /**
     * 检索向量数据库
     * @param key
     * @return
     */
    @GetMapping(value = "/search")
    public List<Document> search(@RequestParam(value = "key") String key) {
        // 检索与查询相似的文档
        List<Document> results = vectorStore.similaritySearch(SearchRequest.builder()
                .query(key) // 查询的关键词
                .topK(2) // 查询相似度最高的 2 条文档
                .build());

        return results;
    }

}

测试

重启后端项目,浏览器请求地址 http://localhost:8090/vector/search?key=冰箱第一次使用,看看能否检索出与关键词 “冰箱第一次使用” 匹配度高的文档。

在这里插入图片描述
可以看到返回的结果中,是相似度较高的文档,不过,返回了两条一摸一样的文档,这是怎么回事呢?这是因为我们启动了两次后端项目,导致 Runnner 初始化任务执行了 2 次,导致重复添加了一次文档。刷新一下 Redis 数据,也可以看到目前有 6 条数据,所以,返回 2 条是正常的!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐