Spring AI Alibaba 向量(VectorStore)

Spring AI Alibaba 向量(VectorStore)

1. 概述

Spring AI Alibaba VectorStore 是 Spring AI Alibaba 生态系统中用于与向量数据库交互的核心组件。它基于 Spring AI 框架的抽象设计,提供了一套统一的 API 来操作不同的向量数据库,极大地简化了 AI 应用中向量数据的存储、检索和管理流程。

VectorStore 是实现**检索增强生成(RAG)**技术的关键基础设施。它允许开发者将私有数据转换为向量表示并存储在向量数据库中,当用户提问时,系统会先从向量数据库中检索相关上下文,再将其与用户问题一起发送给大语言模型,从而生成更准确、更有针对性的回答。

2. 核心概念

2.1 VectorStore 接口

Spring AI 通过 VectorStore 接口提供了与向量数据库交互的抽象 API,定义了所有向量数据库实现都必须支持的核心操作:

java 复制代码
public interface VectorStore extends DocumentWriter {
    // 获取向量存储名称
    default String getName() {
        return this.getClass().getSimpleName();
    }
    
    // 批量添加文档(自动生成向量并存储)
    void add(List<Document> documents);
    
    // 根据文档ID批量删除
    void delete(List<String> idList);
    
    // 根据元数据过滤条件删除
    void delete(Filter.Expression filterExpression);
    
    // 简单相似度搜索
    List<Document> similaritySearch(String query);
    
    // 高级相似度搜索(支持过滤、topK、相似度阈值等)
    List<Document> similaritySearch(SearchRequest request);
    
    // 获取底层原生客户端
    default <T> Optional<T> getNativeClient() {
        return Optional.empty();
    }
}

2.2 Document 类

Document 是 Spring AI 中表示文本数据的核心类,包含以下主要属性:

  • id:文档唯一标识符
  • content:文档的文本内容
  • metadata:文档的元数据(键值对形式)
  • embedding:文档的向量表示(可选,通常由 EmbeddingModel 自动生成)

2.3 EmbeddingModel

EmbeddingModel 负责将文本内容转换为高维向量表示。Spring AI Alibaba 内置了对多种国产嵌入模型的支持,包括:

  • 通义千问 Embedding(DashScope)
  • 百川 Embedding
  • Moonshot Embedding

2.4 相似度搜索

相似度搜索是向量数据库的核心功能,它通过计算查询向量与数据库中存储向量之间的距离(如余弦距离、欧氏距离)来找出最相似的文档。Spring AI 支持通过 SearchRequest 构建器来配置搜索参数:

java 复制代码
SearchRequest request = SearchRequest.builder()
    .query("Spring AI Alibaba 是什么?")
    .topK(5)                  // 返回前5个最相似的文档
    .similarityThreshold(0.7) // 相似度阈值(0~1,值越高越相似)
    .filterExpression(filter) // 元数据过滤条件
    .build();

2.5 元数据过滤

元数据过滤允许在相似度搜索的同时,基于文档的元数据进行精确过滤,从而提高检索的准确性和效率。Spring AI 提供了两种过滤方式:

  1. SQL-like 字符串表达式:简单直观,但缺乏类型安全
  2. FilterExpressionBuilder:类型安全的构建器 API,推荐在生产环境使用

3. 支持的向量数据库

Spring AI Alibaba 不仅提供了对阿里云原生向量服务的支持,还兼容 Spring AI 官方支持的所有向量数据库实现:

向量数据库 特点 适用场景
DashScopeCloudStore 阿里云原生向量检索服务,无需自建,高可用 企业级应用,快速上线
Milvus 专为向量设计,高吞吐、高可用 大规模向量检索场景
PGVector PostgreSQL 扩展,关系型+向量 已有 PostgreSQL 基础设施
Redis 高性能,成熟生态 已有 Redis 基础设施,实时性要求高
Elasticsearch 全文搜索+向量搜索 混合检索场景
Chroma 轻量级,易用 小型项目、原型开发
SimpleVectorStore 内存/文件存储,无需额外依赖 开发测试、演示

4. 快速开始

4.1 环境准备

  1. 获取 DashScope API Key :访问 阿里云百炼平台 注册并获取 API Key
  2. 创建 Spring Boot 项目:使用 Spring Initializr 创建一个新的 Spring Boot 3.x 项目

4.2 添加依赖

pom.xml 中添加 Spring AI Alibaba 依赖:

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter</artifactId>
    <version>2024.0.1.0</version>
</dependency>

4.3 配置应用

application.properties 中添加配置:

properties 复制代码
# DashScope API Key
spring.ai.dashscope.api-key=YOUR_DASHSCOPE_API_KEY

# 配置嵌入模型
spring.ai.dashscope.embedding.model=text-embedding-v3

# 配置聊天模型(用于RAG)
spring.ai.dashscope.chat.model=qwen-turbo

4.4 基础使用示例

创建一个简单的控制器来演示 VectorStore 的基本操作:

java 复制代码
@RestController
@RequestMapping("/vector")
public class VectorStoreController {

    private final VectorStore vectorStore;

    // Spring Boot 自动注入配置好的 VectorStore
    public VectorStoreController(VectorStore vectorStore) {
        this.vectorStore = vectorStore;
    }

    // 添加文档到向量数据库
    @PostMapping("/add")
    public String addDocuments() {
        List<Document> documents = List.of(
            new Document("Spring AI Alibaba 是阿里云基于 Spring AI 框架开发的 AI 应用开发工具包。"),
            new Document("VectorStore 是 Spring AI 中用于与向量数据库交互的核心接口。"),
            new Document("RAG(检索增强生成)是一种将检索系统与大语言模型结合的技术。", 
                Map.of("type", "tutorial", "version", "1.0"))
        );
        
        vectorStore.add(documents);
        return "文档添加成功!";
    }

    // 简单相似度搜索
    @GetMapping("/search")
    public List<Document> search(@RequestParam String query) {
        return vectorStore.similaritySearch(query);
    }

    // 高级相似度搜索
    @GetMapping("/advanced-search")
    public List<Document> advancedSearch(@RequestParam String query) {
        SearchRequest request = SearchRequest.builder()
            .query(query)
            .topK(3)
            .similarityThreshold(0.6)
            .build();
        
        return vectorStore.similaritySearch(request);
    }

    // 根据ID删除文档
    @DeleteMapping("/delete")
    public String delete(@RequestParam List<String> ids) {
        vectorStore.delete(ids);
        return "文档删除成功!";
    }
}

5. 高级特性

5.1 元数据过滤

元数据过滤是提高检索准确性的重要手段。Spring AI 提供了强大的过滤表达式支持:

5.1.1 使用 FilterExpressionBuilder(推荐)
java 复制代码
// 构建过滤条件:type == "tutorial" AND version >= 1.0
Filter.Expression filter = FilterExpressionBuilder.builder()
    .eq("type", "tutorial")
    .and()
    .ge("version", 1.0)
    .build();

SearchRequest request = SearchRequest.builder()
    .query("什么是RAG?")
    .filterExpression(filter)
    .topK(5)
    .build();

List<Document> results = vectorStore.similaritySearch(request);
5.1.2 支持的操作符
操作符 说明 示例
== 等于 eq("status", "active")
!= 不等于 ne("status", "deleted")
> 大于 gt("price", 100)
>= 大于等于 ge("version", 2.0)
< 小于 lt("score", 60)
<= 小于等于 le("age", 18)
in 包含于 in("category", List.of("tech", "ai"))
and 逻辑与 eq("a", 1).and().eq("b", 2)
or 逻辑或 eq("a", 1).or().eq("b", 2)

5.2 与 RAG 集成

Spring AI Alibaba 提供了开箱即用的 RAG 支持,通过 QuestionAnswerAdvisor 可以轻松实现检索增强生成:

5.2.1 添加 RAG 依赖
xml 复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-advisors-vector-store</artifactId>
</dependency>
5.2.2 配置 RAG 聊天客户端
java 复制代码
@Configuration
public class RagConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder, VectorStore vectorStore) {
        return builder
            .defaultSystem("你是一个专业的技术文档助手,只能使用提供的上下文信息回答问题。如果上下文没有相关信息,请明确说明你不知道。")
            .defaultAdvisors(QuestionAnswerAdvisor.builder(vectorStore)
                .topK(3)
                .similarityThreshold(0.7)
                .build())
            .build();
    }
}
5.2.3 使用 RAG 回答问题
java 复制代码
@RestController
@RequestMapping("/rag")
public class RagController {

    private final ChatClient chatClient;

    public RagController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @GetMapping("/ask")
    public String ask(@RequestParam String question) {
        return chatClient.prompt()
            .user(question)
            .call()
            .content();
    }

    // 动态过滤的 RAG 查询
    @GetMapping("/ask-filtered")
    public String askFiltered(@RequestParam String question, @RequestParam String type) {
        return chatClient.prompt()
            .user(question)
            .advisors(advisorSpec -> advisorSpec
                .param(VectorStoreDocumentRetriever.FILTER_EXPRESSION, "type == '" + type + "'"))
            .call()
            .content();
    }
}

5.3 批量导入文档

在实际应用中,通常需要批量导入大量文档。Spring AI 提供了文档分割器来处理长文本:

java 复制代码
@Service
public class DocumentImportService {

    private final VectorStore vectorStore;
    private final TextSplitter textSplitter;

    public DocumentImportService(VectorStore vectorStore) {
        this.vectorStore = vectorStore;
        // 创建一个基于 token 的文本分割器
        this.textSplitter = TokenTextSplitter.builder()
            .chunkSize(500)    // 每个块的大小(token 数)
            .chunkOverlap(50)  // 块之间的重叠大小
            .build();
    }

    public void importDocument(String content, Map<String, Object> metadata) {
        // 创建原始文档
        Document document = new Document(content, metadata);
        
        // 将长文档分割成小块
        List<Document> chunks = textSplitter.apply(List.of(document));
        
        // 批量添加到向量数据库
        vectorStore.add(chunks);
    }

    // 从文件导入文档
    public void importFromFile(String filePath, Map<String, Object> metadata) throws IOException {
        String content = Files.readString(Paths.get(filePath));
        importDocument(content, metadata);
    }
}

6. 最佳实践

6.1 文档分块策略

不同类型的文档适合不同的分块策略:

文档类型 推荐策略 说明
长文本(书籍、报告) 递归分块 先按段落分割,再按句子分割
结构化文档(Markdown、HTML) 基于结构分块 保留标题、章节等结构信息
表格数据 Text-to-SQL 不建议存入向量库,使用 SQL 查询
短文档(FAQ、问答对) 整体作为一个块 保持语义完整性

6.2 元数据设计

合理的元数据设计可以显著提高检索效率和准确性:

java 复制代码
// 推荐的元数据结构
Map<String, Object> metadata = Map.of(
    "source", "spring-ai-alibaba-docs.pdf",  // 文档来源
    "type", "tutorial",                      // 文档类型
    "version", "1.0",                        // 文档版本
    "author", "Alibaba",                     // 作者
    "created_at", LocalDateTime.now(),       // 创建时间
    "chapter", "第3章",                      // 章节信息
    "page", 45                               // 页码
);

6.3 性能优化

  1. 先过滤后检索:尽可能使用元数据过滤减少需要进行相似度计算的向量数量
  2. 合理设置 topK:根据业务需求调整返回结果数量,避免不必要的计算
  3. 批量操作 :使用 add(List<Document>) 方法批量添加文档,提高写入效率
  4. 索引优化:为常用的元数据字段创建索引
  5. 向量维度选择:根据业务需求选择合适的向量维度,维度越高精度越高但计算成本也越高

6.4 错误处理

java 复制代码
@Service
public class VectorStoreService {

    private static final Logger logger = LoggerFactory.getLogger(VectorStoreService.class);
    private final VectorStore vectorStore;

    public VectorStoreService(VectorStore vectorStore) {
        this.vectorStore = vectorStore;
    }

    public void safeAddDocuments(List<Document> documents) {
        try {
            vectorStore.add(documents);
            logger.info("成功添加 {} 个文档", documents.size());
        } catch (Exception e) {
            logger.error("添加文档失败", e);
            // 实现重试逻辑或错误处理
        }
    }

    public List<Document> safeSearch(SearchRequest request) {
        try {
            return vectorStore.similaritySearch(request);
        } catch (Exception e) {
            logger.error("相似度搜索失败", e);
            return Collections.emptyList();
        }
    }
}

7. 常见问题

7.1 为什么搜索结果不相关?

可能的原因和解决方案:

  • 文档分块不合理:调整分块大小和重叠度
  • 嵌入模型不适合:尝试使用针对中文优化的嵌入模型
  • 相似度阈值设置不当:降低相似度阈值以返回更多结果
  • 元数据过滤过于严格:检查过滤条件是否正确

7.2 如何处理大文件?

使用 Spring AI 提供的文档读取器和分割器:

  • TextReader:读取纯文本文件
  • PdfReader:读取 PDF 文件
  • MarkdownReader:读取 Markdown 文件(保留结构信息)
  • TokenTextSplitter:基于 token 数量分割文本

7.3 如何更新向量数据库中的文档?

Spring AI 目前没有提供直接的更新方法,推荐的做法是:

  1. 根据 ID 删除旧文档
  2. 添加更新后的新文档

7.4 SimpleVectorStore 可以用于生产环境吗?

不推荐。SimpleVectorStore 是一个基于内存和文件的简单实现,不支持高并发和大规模数据存储。生产环境建议使用专业的向量数据库如 Milvus、PGVector 或阿里云 DashScopeCloudStore。

8. 总结

Spring AI Alibaba VectorStore 为开发者提供了一套简单、统一、高效的向量数据库操作 API,极大地降低了构建 RAG 应用的门槛。通过本文档的学习,您应该已经掌握了 VectorStore 的核心概念、基本使用方法和高级特性。

相关推荐
IT_陈寒2 小时前
React中useEffect依赖项这个坑我居然踩了三天
前端·人工智能·后端
江畔柳前堤2 小时前
github实战指南02-仓库管理与 Issue
人工智能·深度学习·github·信号处理·caffe·wps·issue
邵宇然2 小时前
内存分配优化:基于 Unsafe 指针与内存对齐的 Rust 区域分配器
人工智能
海兰2 小时前
【游戏】迷雾镇(Mist Town)AI 沙箱游戏详细设计与部署指南(附源代码)
人工智能·游戏
小赖同学啊3 小时前
智能连接器集群化高可用生产方案
linux·运维·人工智能
ZStack开发者社区3 小时前
基于AI Agent的ZCF API文档全链路自动化
运维·人工智能·自动化
沈麽鬼3 小时前
别瞎用AI写代码!90%开发者都搞错了AI编程的底层逻辑
人工智能·ai编程·trae
小陈爱编程3 小时前
我终于把 Codex 的 API 配置理顺了:从踩坑到跑通
人工智能
不爱洗脚的小滕3 小时前
【Agent】如何为 AI Agent 设计高可用的 Tools
人工智能·aigc·ai编程·rag