文本向量化实战:阿里 DashScope 向量模型快速上手

平时做知识库、本地RAG、文档语义检索都会用到文本向量化,很多人刚上手不知道怎么对接阿里灵积的向量模型。

这里直接贴一套可跑通的Spring AI Alibaba Demo,全是单元测试代码,拿来改下API Key就能本地测,覆盖日常开发最常用的几个场景:基础存向量、带元数据检索、删向量、批量导入文本。

一、项目依赖&配置

1. pom.xml 核心依赖

父工程是Spring Boot 3.4.0,JDK17,只贴关键ai相关包,其他web/test常规依赖就不啰嗦了:

xml 复制代码
<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>
    <!-- 阿里灵积AI核心包 -->
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-agent-framework</artifactId>
        <version>1.1.2.0</version>
    </dependency>
    <!-- DashScope一键starter,内置Embedding向量模型 -->
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
        <version>1.1.2.0</version>
    </dependency>
    <!-- SpringAI向量存储顶层抽象 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-vector-store</artifactId>
        <version>1.1.2</version>
    </dependency>
</dependencies>

2. application.yml 配置

关键点:自己去阿里云灵积后台拿api-key,填这里,模型用qwen3.7-max就行,向量生成底层会自动调用dashscope的embedding接口,不用单独配向量模型名称。

yaml 复制代码
server:
  port: 8080
spring:
  ai:
    dashscope:
      api-key: sk-xxxx你的真实key
      chat:
        options:
          model: qwen3.7-max

二、核心概念说明

  1. 文本向量化:将自然语言文本转换为计算机可计算的向量(Embedding),向量的距离越近表示文本语义越相似。
  2. VectorStore :向量存储组件,负责文本向量的存储、检索、删除等操作,本教程使用 SimpleVectorStore(轻量级内存实现,只适合本地测试),生产要换Milvus(后续有安装使用教程)或ES
  3. SearchRequest:检索条件构造器,可控制返回条数topK、相似度阈值,过滤低分无关文本。
  4. Document:Spring AI 封装的文档对象,包含文本内容(text)、元数据(metadata)、向量得分(score)等属性。每一段待向量化的文本,支持塞自定义元数据(分类、标签、业务ID),生成向量后一起存;
  5. DashScopeEmbeddingModel:阿里灵积提供的向量模型,输入文本自动返回浮点向量数组;

三、实战案例开发

3.1 核心配置类

首先创建测试配置类,注入向量存储 Bean,关联阿里 DashScope 向量模型:

java 复制代码
package com.wigang.ai;

import com.alibaba.cloud.ai.dashscope.embedding.DashScopeEmbeddingModel;
import org.junit.jupiter.api.Test;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;

import java.util.Arrays;
import java.util.List;

@SpringBootTest
public class VectorStoreTest {

    // 注入向量存储组件
    @Autowired
    private VectorStore vectorStore;

    // 测试配置:创建VectorStore Bean,绑定阿里DashScope向量模型
    @TestConfiguration
    static class TestVectorStoreConfig {
        @Bean
        public VectorStore vectorStore(DashScopeEmbeddingModel dashScopeEmbeddingModel) {
            return SimpleVectorStore.builder(dashScopeEmbeddingModel).build();
        }
    }
}

3.2 案例1:基础向量存储与相似度搜索

实现文本向量的存储,并基于语义相似度检索相关文本:

java 复制代码
/**
 * 测试向量存储和相似度搜索
 */
@Test
public void testVectorStore() {
    // 1. 准备测试文档
    Document document1 = Document.builder().text("机器学习是人工智能的重要分支,通过算法让计算机从数据中学习").build();
    Document document2 = Document.builder().text("深度学习使用神经网络进行特征提取和模式识别").build();
    Document document3 = Document.builder().text("自然语言处理技术让计算机能够理解和生成人类语言").build();
    Document document4 = Document.builder().text("计算机视觉致力于让计算机能够理解和处理图像信息").build();
    Document document5 = Document.builder().text("今天天气真好,适合出去散步").build();
    
    // 2. 添加文档到向量存储(自动完成文本向量化)
    vectorStore.add(Arrays.asList(document1, document2, document3, document4, document5));

    // 3. 相似度搜索
    System.out.println("=== 测试相似度搜索 ===");
    String query = "人工智能和机器学习";
    List<Document> documents = vectorStore.similaritySearch(
            SearchRequest.builder()
                    .query(query)  // 搜索查询文本
                    .topK(3)       // 返回最相似的3条结果
                    .build()
    );

    // 4. 输出搜索结果
    System.out.println("查询: " + query);
    System.out.println("找到 " + documents.size() + " 个相关结果:");
    for (int i = 0; i < documents.size(); i++) {
        Document document = documents.get(i);
        System.out.println((i + 1) + ". 内容: " + document.getText());
        System.out.println("   相似度得分: " + document.getScore());
        System.out.println();
    }
}

预期结果

查询"人工智能和机器学习"时,document1(机器学习)、document2(深度学习)、document3(自然语言处理)会被优先返回,document5(天气)因语义无关不会出现在结果中,且结果按相似度得分降序排列。

bash 复制代码
=== 测试相似度搜索 ===
查询: 人工智能和机器学习
找到 3 个相关结果:
1. 内容: 机器学习是人工智能的重要分支,通过算法让计算机从数据中学习
   相似度得分: 0.7147222458406114

2. 内容: 深度学习使用神经网络进行特征提取和模式识别
   相似度得分: 0.5567623647510608

3. 内容: 自然语言处理技术让计算机能够理解和生成人类语言
   相似度得分: 0.5235128486798544

同时还可以通过控制相似度来返回精确的数据

java 复制代码
List<Document> documents = vectorStore.similaritySearch(
        SearchRequest.builder()
                .query(query)  // 搜索查询文本
                .topK(3)       // 返回最相似的3条结果
                .similarityThreshold(0.6f) // 返回相似度超过0.6的向量
                .build()
);
bash 复制代码
=== 测试相似度搜索 ===
查询: 人工智能和机器学习
找到 1 个相关结果:
1. 内容: 机器学习是人工智能的重要分支,通过算法让计算机从数据中学习
   相似度得分: 0.7147222458406114

3.3 案例2:带元数据的向量存储与检索

为文档添加元数据(如分类、标签),实现更精细化的语义检索:

java 复制代码
/**
 * 测试带元数据的向量存储
 */
@Test
public void testVectorStoreWithMetadata() {
    // 1. 准备带元数据的文档
    Document doc1 = Document.builder()
            .text("Spring Boot是一个用于构建微服务的Java框架")
            .metadata("category", "Java开发")  // 分类元数据
            .metadata("tags", "Spring Boot,微服务,Java")  // 标签元数据
            .build();

    Document doc2 = Document.builder()
            .text("React是一个用于构建用户界面的JavaScript库")
            .metadata("category", "前端开发")
            .metadata("tags", "React,JavaScript,前端")
            .build();

    Document doc3 = Document.builder()
            .text("Docker是一个容器化平台,用于打包和部署应用")
            .metadata("category", "DevOps")
            .metadata("tags", "Docker,容器化,部署")
            .build();

    Document doc4 = Document.builder()
            .text("MySQL是一个流行的关系型数据库管理系统")
            .metadata("category", "数据库")
            .metadata("tags", "MySQL,数据库,SQL")
            .build();

    // 2. 添加文档到向量存储
    System.out.println("=== 添加带元数据的文档 ===");
    vectorStore.add(Arrays.asList(doc1, doc2, doc3, doc4));
    // 打印元数据验证
    System.out.println("已添加: " + doc1.getText());
    System.out.println("  分类: " + doc1.getMetadata().get("category"));
    System.out.println("  标签: " + doc1.getMetadata().get("tags"));

    // 3. 按语义+相似度阈值搜索
    System.out.println("=== 搜索Java相关内容 ===");
    List<Document> results = vectorStore.similaritySearch(
            SearchRequest.builder()
                    .query("Java开发和框架")
                    .topK(2)  // 返回2条结果
                    .similarityThreshold(0.6f)  // 相似度阈值(0-1,仅返回≥0.6的结果)
                    .build()
    );

    // 4. 输出结果(包含元数据)
    System.out.println("找到 " + results.size() + " 个相关结果:");
    for (int i = 0; i < results.size(); i++) {
        Document document = results.get(i);
        System.out.println((i + 1) + ". 内容: " + document.getText());
        System.out.println("   相似度得分: " + document.getScore());
        System.out.println("   分类: " + document.getMetadata().get("category"));
        System.out.println("   标签: " + document.getMetadata().get("tags"));
        System.out.println();
    }
}

核心亮点

通过 similarityThreshold 设置相似度阈值,过滤低相关度结果;元数据可用于后续业务层的二次筛选(如仅展示"Java开发"分类的结果)。

bash 复制代码
=== 搜索Java相关内容 ===
找到 1 个相关结果:
1. 内容: Spring Boot是一个用于构建微服务的Java框架
   相似度得分: 0.6322960226800465
   分类: Java开发
   标签: Spring Boot,微服务,Java

3.4 案例3:向量删除功能

实现向量文档的删除,并验证删除结果:

java 复制代码
/**
 * 测试向量删除功能
 */
@Test
public void testVectorDeletion() {
    // 1. 添加测试文档
    Document doc1 = Document.builder().text("第一个测试文档").build();
    Document doc2 = Document.builder().text("第二个测试文档").build();
    Document doc3 = Document.builder().text("第三个测试文档").build();

    System.out.println("=== 添加文档 ===");
    vectorStore.add(Arrays.asList(doc1, doc2, doc3));

    // 2. 搜索验证添加结果
    System.out.println("=== 搜索所有文档 ===");
    List<Document> allResults = vectorStore.similaritySearch(
            SearchRequest.builder()
                    .query("测试")
                    .topK(10)
                    .build()
    );
    System.out.println("当前文档数量: " + allResults.size());

    // 3. 删除指定文档(通过文档ID)
    if (!allResults.isEmpty()) {
        String docId = allResults.get(0).getId();
        System.out.println("=== 删除文档 ===");
        System.out.println("删除文档ID: " + docId);
        vectorStore.delete(List.of(docId));  // 按ID删除

        // 4. 验证删除结果
        System.out.println("=== 再次搜索 ===");
        List<Document> finalResults = vectorStore.similaritySearch(
                SearchRequest.builder()
                        .query("测试")
                        .topK(10)
                        .build()
        );
        System.out.println("最终文档数量: " + finalResults.size());
        for (int i = 0; i < finalResults.size(); i++) {
            Document document = finalResults.get(i);
            System.out.println((i + 1) + ". 内容: " + document.getText());
        }
    }
}

注意事项

SimpleVectorStore 中文档ID由框架自动生成,删除操作需基于ID执行;生产环境建议使用持久化向量存储(如Milvus、Pinecone)。

bash 复制代码
=== 添加文档 ===
2026-06-17T16:21:38.168+08:00  INFO 53030 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 4818bad4-b251-40db-94b9-114f88b7a8b3
2026-06-17T16:21:38.463+08:00  INFO 53030 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 231d1fbd-3fc9-4cb4-9b03-09c70051069b
2026-06-17T16:21:38.748+08:00  INFO 53030 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 3d43f22a-38f6-4aba-b893-1871815902e8
已添加: 第一个测试文档
已添加: 第二个测试文档
已添加: 第三个测试文档

=== 搜索所有文档 ===
当前文档数量: 3

=== 删除文档 ===
删除文档ID: 4818bad4-b251-40db-94b9-114f88b7a8b3
文档已成功删除

=== 再次搜索 ===
最终文档数量: 2
1. 内容: 第二个测试文档
2. 内容: 第三个测试文档

3.5 案例4:批量向量生成与存储

处理大批量文档的向量化和检索,验证性能与准确性:

java 复制代码
/**
 * 测试批量向量生成和存储
 */
@Test
public void testBatchEmbedding() {
    // 1. 准备批量文档
    Document doc1 = Document.builder().text("人工智能正在改变各行各业").build();
    Document doc2 = Document.builder().text("大数据技术帮助我们从海量数据中发现价值").build();
    Document doc3 = Document.builder().text("云计算提供了弹性的计算资源").build();
    Document doc4 = Document.builder().text("区块链技术确保了数据的安全性和不可篡改性").build();
    Document doc5 = Document.builder().text("物联网连接了物理世界和数字世界").build();
    Document doc6 = Document.builder().text("5G网络提供了高速低延迟的通信").build();
    Document doc7 = Document.builder().text("边缘计算将计算能力推向网络边缘").build();
    Document doc8 = Document.builder().text("量子计算有望解决传统计算机无法处理的复杂问题").build();

    System.out.println("=== 批量处理文档 ===");
    System.out.println("文档总数: 8");

    // 2. 批量添加到向量存储
    vectorStore.add(Arrays.asList(doc1, doc2, doc3, doc4, doc5, doc6, doc7, doc8));
    System.out.println("所有文档已成功添加到向量存储");

    // 3. 多关键词检索验证
    String[] queries = {"人工智能技术发展", "数据存储和处理", "网络技术"};
    for (String query : queries) {
        System.out.println("查询: " + query);
        List<Document> results = vectorStore.similaritySearch(
                SearchRequest.builder()
                        .query(query)
                        .topK(2)
                        .build()
        );

        System.out.println("找到 " + results.size() + " 个相关结果:");
        for (int i = 0; i < results.size(); i++) {
            Document document = results.get(i);
            System.out.println((i + 1) + ". " + document.getText() +
                    " (相似度: " + String.format("%.4f", document.getScore()) + ")");
        }
        System.out.println();
    }
}

性能说明

阿里 DashScope 向量模型支持批量向量化,SimpleVectorStore 适合小规模测试;生产环境处理大批量文档时,建议使用分布式向量数据库(如 Milvus、Elasticsearch)。

bash 复制代码
=== 批量处理文档 ===
文档总数: 8
2026-06-17T16:22:16.233+08:00  INFO 53218 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = cc24eee9-a2ef-46f7-81a7-6cf7c38fd91a
2026-06-17T16:22:16.346+08:00  INFO 53218 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 49e09560-bb64-40c6-826e-f246be877c53
2026-06-17T16:22:16.489+08:00  INFO 53218 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 9d94f7da-a0db-4828-a4ed-c72e52f02fa1
2026-06-17T16:22:16.625+08:00  INFO 53218 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 1b697a18-2f68-47a6-876c-bd4e7b1bdd38
2026-06-17T16:22:16.761+08:00  INFO 53218 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 8ac8467d-9c4d-4263-a77e-f3da062591dd
2026-06-17T16:22:17.024+08:00  INFO 53218 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 94966e46-e584-430e-bcc3-b931b07b24c5
2026-06-17T16:22:17.164+08:00  INFO 53218 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 7115b895-c97f-4dc4-abed-00f04bedbf31
2026-06-17T16:22:17.465+08:00  INFO 53218 --- [           main] o.s.ai.vectorstore.SimpleVectorStore     : Calling EmbeddingModel for document id = 6f98e8f2-9a32-4e7e-b51d-bebe9173c31f
所有文档已成功添加到向量存储

查询: 人工智能技术发展
找到 2 个相关结果:
1. 人工智能正在改变各行各业 (相似度: 0.6908)
2. 大数据技术帮助我们从海量数据中发现价值 (相似度: 0.4944)

查询: 数据存储和处理
找到 2 个相关结果:
1. 大数据技术帮助我们从海量数据中发现价值 (相似度: 0.6091)
2. 区块链技术确保了数据的安全性和不可篡改性 (相似度: 0.5958)

查询: 网络技术
找到 2 个相关结果:
1. 边缘计算将计算能力推向网络边缘 (相似度: 0.6004)
2. 5G网络提供了高速低延迟的通信 (相似度: 0.5640)

四、扩展与生产优化

  1. 替换向量存储 :将 SimpleVectorStore 替换为 Milvus、Chroma、Pinecone 等持久化向量存储,支持大规模数据和持久化。
  2. 元数据筛选:结合业务需求,在搜索结果中基于元数据(如 category、tags)进行二次过滤。
  3. 模型优化:调整 DashScope 向量模型参数(如维度、相似度算法),提升检索准确性。
  4. 异常处理:添加 API 调用失败重试、超时处理等机制,保证生产环境稳定性。
  5. 性能优化:批量处理文档时,控制单次批量大小(建议 100-500 条/批),避免 API 限流。
  6. 相似度阈值灵活调整:短文本建议0.5~0.6,长文档知识库建议0.7以上,太低会返回大量无关垃圾数据;
  7. 元数据不支持复杂对象:metadata只能存字符串,数字、布尔值存进去会自动转string,取的时候自己手动转类型。
  8. 文本预处理:入库前统一清洗文本(去换行、空格、无效特殊符号),提升向量匹配准确度。