嵌入是文本、图像或视频的数值表示,能够捕捉输入数据之间的关联关系。
嵌入的工作原理是将文本、图像和视频转换为浮点数组,该数组也被称为向量。这些向量的设计目标是捕捉文本、图像和视频的语义含义。嵌入数组的长度被称为向量的维度。
通过计算两段文本向量表示之间的数值距离,应用程序可以判断生成嵌入向量的对象之间的相似度。
EmbeddingModel 接口专为便捷集成人工智能与机器学习领域的嵌入模型而设计。它的核心功能是将文本转换为数值向量,这类向量通常被称为嵌入向量。嵌入向量对于语义分析、文本分类等多种任务至关重要。
EmbeddingModel 接口的设计围绕两大核心目标:
可移植性:该接口确保能够轻松适配各类嵌入模型。开发者只需极少的代码修改,即可在不同的嵌入技术或模型之间切换。这种设计符合 Spring 模块化、可互换的设计理念。
简洁性:EmbeddingModel 简化了文本转嵌入的流程。通过提供 embed(String text) 和 embed(Document document) 等简洁方法,它屏蔽了处理原始文本数据和嵌入算法的复杂性。这种设计让开发者(尤其是人工智能领域的新手)能够轻松在应用中使用嵌入功能,无需深入钻研底层原理。
API 概述
嵌入模型 API 构建在通用的 Spring AI 模型 API 之上,该 API 是 Spring AI 库的一部分。因此,EmbeddingModel 接口继承自 Model 接口,Model 接口提供了与人工智能模型交互的标准方法集。EmbeddingRequest 和 EmbeddingResponse 类分别继承自 ModelRequest 和 ModelResponse,用于封装嵌入模型的输入和输出。
嵌入 API 会被更上层的组件使用,为 OpenAI、Titan、Azure OpenAI、Ollama 等特定嵌入模型实现对应的嵌入模型功能。
下图展示了嵌入 API 及其与 Spring AI 模型 API、嵌入模型之间的关系:
嵌入 API 结构图
EmbeddingModel
本节介绍 EmbeddingModel 接口及相关类的使用指南。
public interface EmbeddingModel extends Model{
@Override
EmbeddingResponse call(EmbeddingRequest request);
/**
* 将给定文档的内容嵌入为向量。
* @param document 待嵌入的文档
* @return 嵌入后的向量
*/
float[] embed(Document document);
/**
* 从文档中提取用于嵌入的文本内容。
* 默认返回 Document.getText()。支持 MetadataMode 的实现类应重写该方法,
* 返回 Document.getFormattedContent(MetadataMode),
* 确保在配置后元数据会被包含在发送给嵌入 API 的文本中。
*/
default String getEmbeddingContent(Document document) {
return document.getText();
}
/**
* 将给定文本嵌入为向量。
* @param text 待嵌入的文本
* @return 嵌入后的向量
*/
default float[] embed(String text) {
Assert.notNull(text, "Text must not be null");
return this.embed(List.of(text)).iterator().next();
}
/**
* 将一批文本批量嵌入为向量。
* @param texts 待嵌入的文本列表
* @return 嵌入向量的列表
*/
default Listembed(Listtexts) {
Assert.notNull(texts, "Texts must not be null");
return this.call(new EmbeddingRequest(texts, EmbeddingOptions.EMPTY))
.getResults()
.stream()
.map(Embedding::getOutput)
.toList();
}
/**
* 将一批文本批量嵌入为向量,并返回 EmbeddingResponse。
* @param texts 待嵌入的文本列表
* @return 嵌入响应结果
*/
default EmbeddingResponse embedForResponse(Listtexts) {
Assert.notNull(texts, "Texts must not be null");
return this.call(new EmbeddingRequest(texts, EmbeddingOptions.EMPTY));
}
/**
* @return 嵌入向量的维度,与具体的生成模型相关
*/
default int dimensions() {
return embed("Test String").size();
}
}embed 方法提供了多种将文本转换为嵌入向量的方式,支持单个字符串、结构化 Document 对象或批量文本。
框架提供了多个文本嵌入的快捷方法,包括 embed(String text),该方法接收单个字符串并返回对应的嵌入向量。所有快捷方法都基于 call 方法实现,call 方法是调用嵌入模型的核心方法。
getEmbeddingContent(Document) 方法控制嵌入前如何从文档中提取文本。默认返回 Document.getText(),但支持 MetadataMode 的嵌入模型实现类(如 OpenAI、Azure OpenAI、Mistral AI)会重写该方法,返回 Document.getFormattedContent(MetadataMode),确保在配置后文档元数据会被包含在发送给嵌入 API 的文本中。该方法被向量数据库依赖的批量嵌入流程使用。
通常情况下,嵌入结果会返回浮点数列表,以数值向量格式表示嵌入内容。
embedForResponse 方法提供更完整的输出,可能包含嵌入相关的额外信息。
dimensions 方法是开发者快速获取嵌入向量维度的实用工具,这对于理解嵌入空间和后续处理步骤非常重要。
EmbeddingRequest
EmbeddingRequest 是一种 ModelRequest,接收文本对象列表和可选的嵌入请求选项。以下代码展示了 EmbeddingRequest 类的精简版本,省略了构造函数和其他工具方法:
public class EmbeddingRequest implements ModelRequest> {
private final Listinputs;
private final EmbeddingOptions options;
// 其他方法省略
}EmbeddingResponse
EmbeddingResponse 类的结构如下:
public class EmbeddingResponse implements ModelResponse{
private Listembeddings;
private EmbeddingResponseMetadata metadata = new EmbeddingResponseMetadata();
// 其他方法省略
}EmbeddingResponse 类存储人工智能模型的输出,每个 Embedding 实例对应单个文本输入的向量结果数据。
EmbeddingResponse 类还携带了 EmbeddingResponseMetadata,用于存储人工智能模型响应的元数据。
Embedding
Embedding 表示单个嵌入向量。
public class Embedding implements ModelResult{
private float[] embedding;
private Integer index;
private EmbeddingResultMetadata metadata;
// 其他方法省略
}可用实现
各类 EmbeddingModel 实现内部使用不同的底层库和 API 完成嵌入任务。以下是部分可用的 EmbeddingModel 实现:
Spring AI OpenAI 嵌入
Spring AI Azure OpenAI 嵌入
Spring AI Ollama 嵌入
Spring AI Transformers (ONNX) 嵌入
Spring AI PostgresML 嵌入
Spring AI Bedrock Cohere 嵌入
Spring AI Bedrock Titan 嵌入
Spring AI VertexAI 嵌入
Spring AI Mistral AI 嵌入
Spring AI 甲骨文云基础设施生成式人工智能嵌入