主题
嵌入模型 API
嵌入是文本、图像或视频的数值表示,用于捕捉输入之间的关系。
嵌入的工作原理是将文本、图像和视频转换为浮点数数组,即所谓向量。 这些向量旨在捕捉文本、图像和视频的含义。 嵌入数组的长度被称为该向量的维度。
通过计算两段文本的向量表示之间的数值距离,应用就可以判断生成这两个嵌入向量的对象之间的相似度。
EmbeddingModel 接口专为在 AI 与机器学习场景中轻松集成嵌入模型而设计。 它的主要功能是把文本转换为数值向量,也就是常说的嵌入(embeddings)。 这些嵌入对于语义分析、文本分类等各类任务都至关重要。
EmbeddingModel 接口的设计围绕两个主要目标:
可移植性(Portability):该接口确保能轻松适配各种嵌入模型。 它让开发者只需极少的代码改动,就能在不同的嵌入技术或模型之间切换。 这一设计与 Spring 的模块化与可互换理念一脉相承。
简洁性(Simplicity):EmbeddingModel 简化了将文本转换为嵌入的过程。 通过提供
embed(String text)和embed(Document document)这样直白的便捷方法,它将处理原始文本数据与嵌入算法的复杂性屏蔽在外。这一设计选择让开发者——尤其是 AI 新手——能够在不深究底层机制的情况下,轻松在自己的应用中使用嵌入。
API 概览
嵌入模型 API 构建在通用的 Spring AI Model API 之上,后者是 Spring AI 库的一部分。 因此,EmbeddingModel 接口继承了 Model 接口,后者提供了一组与 AI 模型交互的标准方法。EmbeddingRequest 和 EmbeddingResponse 类分别继承自 ModelRequest 和 ModelResponse,用于封装嵌入模型的输入与输出。
而嵌入 API 又被更上层的组件使用,以针对 OpenAI、Titan、Ollie 等具体嵌入模型实现 Embedding Models。
下图展示了嵌入 API 及其与 Spring AI Model API 和 Embedding Models 之间的关系:
EmbeddingModel
本节提供 EmbeddingModel 接口及相关类的指南。
java
public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {
@Override
EmbeddingResponse call(EmbeddingRequest request);
/**
* Embeds the given document's content into a vector.
* @param document the document to embed.
* @return the embedded vector.
*/
float[] embed(Document document);
/**
* Extracts the text content from a Document to be used for embedding.
* By default, returns Document.getText(). Implementations that support
* MetadataMode should override this to return
* Document.getFormattedContent(MetadataMode) so that metadata is
* included in the text sent to the embedding API.
*/
default String getEmbeddingContent(Document document) {
return document.getText();
}
/**
* Embeds the given text into a vector.
* @param text the text to embed.
* @return the embedded vector.
*/
default float[] embed(String text) {
Assert.notNull(text, "Text must not be null");
return this.embed(List.of(text)).iterator().next();
}
/**
* Embeds a batch of texts into vectors.
* @param texts list of texts to embed.
* @return list of list of embedded vectors.
*/
default List<float[]> embed(List<String> texts) {
Assert.notNull(texts, "Texts must not be null");
return this.call(new EmbeddingRequest(texts, EmbeddingOptions.EMPTY))
.getResults()
.stream()
.map(Embedding::getOutput)
.toList();
}
/**
* Embeds a batch of texts into vectors and returns the {@link EmbeddingResponse}.
* @param texts list of texts to embed.
* @return the embedding response.
*/
default EmbeddingResponse embedForResponse(List<String> texts) {
Assert.notNull(texts, "Texts must not be null");
return this.call(new EmbeddingRequest(texts, EmbeddingOptions.EMPTY));
}
/**
* @return the number of dimensions of the embedded vectors. It is generative
* specific.
*/
default int dimensions() {
return embed("Test String").size();
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
embed 方法提供了把文本转换为嵌入的多种选项,可处理单个字符串、结构化的 Document 对象,或成批的文本。
提供了多个用于嵌入文本的便捷方法,其中包括 embed(String text) 方法,它接收单个字符串并返回对应的嵌入向量。 所有便捷方法都围绕 call 方法实现,而 call 是调用嵌入模型的主要方法。
getEmbeddingContent(Document) 方法控制在嵌入前如何从 Document 中提取文本。 默认它返回 Document.getText(),但支持 MetadataMode 的嵌入模型实现(如 OpenAI 或 Mistral AI)会覆写此方法以返回 Document.getFormattedContent(MetadataMode),从而在配置后确保文档元数据被包含在发送给嵌入 API 的文本中。 向量库所依赖的批量嵌入路径会用到这个方法。
通常,嵌入会返回一个浮点数列表,以数值向量格式表示这些嵌入。
embedForResponse 方法提供更全面的输出,可能还包含关于嵌入的额外信息。
dimensions 方法是一个便捷工具,让开发者能快速确定嵌入向量的大小,这对于理解嵌入空间以及后续处理步骤都很重要。
EmbeddingRequest
EmbeddingRequest 是一个 ModelRequest,它接收一个文本对象列表以及可选的嵌入请求选项。 下面的清单展示了 EmbeddingRequest 类的精简版本,省略了构造器和其他工具方法:
java
public class EmbeddingRequest implements ModelRequest<List<String>> {
private final List<String> inputs;
private final EmbeddingOptions options;
// other methods omitted
}1
2
3
4
5
2
3
4
5
EmbeddingResponse
EmbeddingResponse 类的结构如下:
java
public class EmbeddingResponse implements ModelResponse<Embedding> {
private List<Embedding> embeddings;
private EmbeddingResponseMetadata metadata = new EmbeddingResponseMetadata();
// other methods omitted
}1
2
3
4
5
6
2
3
4
5
6
EmbeddingResponse 类持有 AI 模型的输出,其中每个 Embedding 实例包含来自单个文本输入的结果向量数据。
EmbeddingResponse 类还携带一个 EmbeddingResponseMetadata,即关于 AI 模型响应的元数据。
Embedding
Embedding 表示单个嵌入向量。
java
public class Embedding implements ModelResult<float[]> {
private float[] embedding;
private Integer index;
private EmbeddingResultMetadata metadata;
// other methods omitted
}1
2
3
4
5
6
2
3
4
5
6
可用实现
在内部,各种 EmbeddingModel 实现使用不同的底层库和 API 来完成嵌入任务。以下是 EmbeddingModel 的一些可用实现: