向量化
- [一、 什么是向量化?](#一、 什么是向量化?)
-
- [1. 基本概念](#1. 基本概念)
- [2. 核心原理:语义相似性](#2. 核心原理:语义相似性)
- [二、 Spring AI Alibaba 向量化核心组件](#二、 Spring AI Alibaba 向量化核心组件)
-
- [1. EmbeddingClient(嵌入客户端)](#1. EmbeddingClient(嵌入客户端))
- [2. VectorStore(向量存储库)](#2. VectorStore(向量存储库))
- [三、 向量化全流程实战详解](#三、 向量化全流程实战详解)
-
- [1. 索引阶段:文档加载与向量化存储](#1. 索引阶段:文档加载与向量化存储)
- [2. 检索阶段:语义搜索与 RAG 增强](#2. 检索阶段:语义搜索与 RAG 增强)
- [四、 关键配置与最佳实践](#四、 关键配置与最佳实践)
-
- [1. 选择合适的 Embedding 模型](#1. 选择合适的 Embedding 模型)
- [2. 文本分块策略 (Text Splitting)](#2. 文本分块策略 (Text Splitting))
- [3. 元数据过滤 (Metadata Filtering)](#3. 元数据过滤 (Metadata Filtering))
- [4. 向量数据库选型](#4. 向量数据库选型)
在 Spring AI Alibaba 中,向量化(Vectorization) 是构建检索增强生成(RAG)应用的核心基础。它通过嵌入模型(Embedding Model)将非结构化的文本数据转换为计算机可理解、可计算的数值向量,从而实现语义层面的相似度搜索。
一、 什么是向量化?
1. 基本概念
向量是一串有序的数字数组(例如 [0.23, -0.56, 0.81, ...])。在大模型语境下,向量化是指利用 Embedding 模型 将文本(如单词、句子、段落)映射到高维向量空间中的过程。
- 维度:常见的向量维度有 768、1024、1536 等,取决于所使用的 Embedding 模型。
- 语义表示:向量中的每一个数字代表文本的一个"隐藏特征"。这些特征并非人工定义,而是模型在训练过程中自动学习到的语义信息(如相关性、类别、情感倾向等)。
2. 核心原理:语义相似性
向量化的核心价值在于语义距离。在向量空间中,语义相近的文本,其对应的向量在空间上的距离(通常使用余弦相似度 Cosine Similarity 衡量)也更近。
- 示例:"猫"和"小狗"的向量距离,会比"猫"和"汽车"的向量距离更近。
- 应用:这使得系统能够根据用户问题的语义,而非仅仅依靠关键词匹配,从海量文档中检索出最相关的内容。
二、 Spring AI Alibaba 向量化核心组件
Spring AI Alibaba 提供了标准化的接口来屏蔽不同向量数据库和嵌入模型的差异主要涉及以下三个核心组件:
1. EmbeddingClient(嵌入客户端)
负责调用嵌入模型将文本转换为向量。
-
功能:接收字符串列表,返回
Embedding对象列表。 -
默认实现:Spring AI Alibaba 默认集成阿里云 DashScope(通义千问系列)的 Embedding 模型(如
text-embedding-v1或text-embedding-v2)。 -
配置示例:
yamlspring: ai: dashscope: api-key: ${AI_DASHSCOPE_API_KEY} embedding: options: model: text-embedding-v2 指定嵌入模型
2. VectorStore(向量存储库)
负责存储向量及其关联的元数据,并提供相似度搜索能力。
- 功能:
add(): 将文档及其向量存入数据库。similaritySearch(): 根据查询向量检索最相似的文档。delete(): 删除指定 ID 的文档。
- 支持后端:Spring AI Alibaba 支持多种向量数据库,包括阿里云 OpenSearch、PostgreSQL (pgvector)、Redis、Milvus 等。
- Document(文档对象)
Spring AI 中承载数据的基本单元。
- 结构:
content: 原始文本内容。metadata: 元数据 Map(如来源、页码、作者等),可用于过滤检索结果。id: 唯一标识符。
三、 向量化全流程实战详解
一个完整的向量化应用通常包含两个阶段:索引阶段(Indexing) 和 检索阶段(Retrieval)。
1. 索引阶段:文档加载与向量化存储
此阶段的目标是将原始文档转化为向量并存入向量数据库。
步骤分解:
- 文档加载与分割:使用
DocumentReader读取文件,并通过TextSplitter将长文档切分为较小的文本块(Chunk),以确保上下文窗口不超限且检索更精准。 - 生成向量:调用
EmbeddingClient对每个文本块进行向量化。 - 持久化存储:将文本块、生成的向量以及元数据一起存入
VectorStore。
代码示例:
java
@Service
public class RagIndexingService {
private final VectorStore vectorStore;
private final EmbeddingClient embeddingClient;
public RagIndexingService(VectorStore vectorStore, EmbeddingClient embeddingClient) {
this.vectorStore = vectorStore;
this.embeddingClient = embeddingClient;
}
public void indexDocuments(List<String> texts) {
List<Document> documents = new ArrayList<>();
for (String text : texts) {
// 1. 构建 Document 对象
Document doc = new Document(text);
// 可选:添加元数据,如来源
doc.getMetadata().put("source", "manual_input");
documents.add(doc);
}
// 2. Spring AI 会自动处理向量化过程
// 当调用 vectorStore.add 时,内部会自动调用 embeddingClient 将文本转为向量
// 注意:具体行为取决于 VectorStore 的实现配置,部分实现需手动先 embed 再 add
vectorStore.add(documents);
}
}
注:在某些配置下,VectorStore 会自动拦截 add 操作并调用默认的 EmbeddingClient 进行向量化;若需手动控制,可先调用 embeddingClient.embed(text) 获取向量,再构建包含向量的 Document 存入。
2. 检索阶段:语义搜索与 RAG 增强
此阶段的目标是根据用户问题,从向量库中找出最相关的知识片段。
步骤分解:
- 问题向量化:将用户的自然语言问题通过同样的
EmbeddingClient转换为向量。 - 相似度搜索:在
VectorStore中查找与问题向量距离最近的 Top-K 个文档。 - 构建上下文:将检索到的文档内容拼接成字符串,作为上下文注入到 Prompt 中。
- 生成回答:将包含上下文的 Prompt 发送给 ChatModel 生成最终答案。
代码示例:
java
@Service
public class RagQueryService {
private final VectorStore vectorStore;
private final ChatClient chatClient;
public RagQueryService(VectorStore vectorStore, ChatClient.Builder chatClientBuilder) {
this.vectorStore = vectorStore;
this.chatClient = chatClientBuilder.build();
}
public String answerQuestion(String question) {
// 1. 执行相似度搜索
// SearchRequest 允许设置 topK(返回数量)、相似度阈值等
List<Document> relevantDocs = vectorStore.similaritySearch(
SearchRequest.query(question).withTopK(3)
);
// 2. 提取相关文本内容
String context = relevantDocs.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n"));
// 3. 构建增强后的 Prompt
String promptTemplate = """
请根据以下参考信息回答问题:
参考信息:
{context}
问题:
{question}
如果参考信息中不包含答案,请说明无法回答。
""";
// 4. 调用大模型生成回答
return chatClient.prompt()
.user(userSpec -> userSpec.text(promptTemplate)
.param("context", context)
.param("question", question))
.call()
.content();
}
}
四、 关键配置与最佳实践
1. 选择合适的 Embedding 模型
- 通义千问 Embedding 模型:Spring AI Alibaba 默认支持阿里云 DashScope 的
text-embedding-v1和text-embedding-v2。v2 版本在中文语义理解上表现更优,推荐优先使用。 - 一致性原则:索引阶段和检索阶段必须使用同一个 Embedding 模型,否则向量空间不一致,导致检索失效。
2. 文本分块策略 (Text Splitting)
- 块大小(Chunk Size):建议设置为 500-1000 字符。过小会丢失上下文,过大会引入噪声且增加 Token 消耗。
- 重叠区(Overlap):设置 10%-20% 的重叠区,防止关键信息被切断在两个块的边界处。
3. 元数据过滤 (Metadata Filtering)
在 SearchRequest 中可以添加过滤器,仅检索特定来源或特定时间范围内的文档,提高检索精度。
java
SearchRequest request = SearchRequest.query(question)
.withTopK(3)
.withFilterExpression("source == 'internal_doc'"); // 仅搜索内部文档
4. 向量数据库选型
- 开发/测试:可使用内置的
SimpleVectorStore(基于内存),无需额外部署。 - 生产环境:推荐使用阿里云 OpenSearch、PostgreSQL (pgvector) 或 Milvus。Spring AI Alibaba 对阿里云 OpenSearch 有深度集成,支持高性能大规模向量检索。