EmbeddingClient` 接口旨在与人工智能和机器学习中的嵌入模型实现直接集成。它的主要功能是将文本转换为数值向量,通常被称为嵌入。这些嵌入对于各种任务至关重要,如语义分析和文本分类。

EmbeddingClient接口的设计围绕着两个主要目标展开:

  • 可移植性:这个接口确保了不同嵌入模型之间的容易适配性。它允许开发者在不同的嵌入技术或模型之间切换,只需进行最少的代码更改。这种设计与Spring的模块化和可互换性哲学相一致。

  • Simplicity:EmbeddingClient 简化了将文本转换为嵌入向量的过程。通过提供简单的方法,例如 embed(String text)embed(Document document),它去除了处理原始文本数据和嵌入算法的复杂性。这种设计选择使得开发人员,特别是那些刚接触人工智能的开发人员,能够在不深入了解底层机制的情况下,在他们的应用程序中利用嵌入向量变得更加容易。

API 概览

嵌入式API是建立在通用的[Spring AI Model API](https://github.com/spring-projects/spring-ai/tree/main/spring-ai-core/src/main/java/org/springframework/ai/model)之上的,它是Spring AI库的一部分。因此,EmbeddingClient接口扩展了`ModelClient`接口,后者提供了一组用于与AI模型交互的标准方法。`EmbeddingRequest`和`EmbeddingResponse`类分别从`ModelRequest`和`ModelResponse`继承,用于封装嵌入式模型的输入和输出。

嵌入式API反过来被更高级别的组件用来实现特定嵌入模型的嵌入式客户端,例如OpenAI、Titan、Azure OpenAI、Ollie等。

下图展示了嵌入式API及其与Spring人工智能模型API和嵌入式客户端的关系:

embeddings api

嵌入式客户端

这一部分提供了对`EmbeddingClient`接口及相关类的指南。

public interface EmbeddingClient extends ModelClient<EmbeddingRequest, EmbeddingResponse> {

java
@Override
EmbeddingResponse call(EmbeddingRequest request);


/**
	 * 将给定文档的内容嵌入到一个向量中。
	 * @param document 要嵌入的文档。
	 * @return 嵌入后的向量。
	 */
	List<Double> embed(Document document);

	/**
	 * 将给定文本嵌入到向量中。
	 * @param text 要嵌入的文本。
	 * @return 嵌入后的向量。
	 */
	default List<Double> embed(String text) {
		Assert.notNull(text, "文本不能为null");
		return this.embed(List.of(text)).iterator().next();
	}

	/**
	 * 将一批文本嵌入到向量中。
	 * @param texts 要嵌入的文本列表。
	 * @return 嵌入向量的列表的列表。
	 */
	default List<List<Double>> embed(List<String> texts) {
		Assert.notNull(texts, "文本不能为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();
	}

}

嵌入方法提供了各种选项,用于将文本转换为嵌入,可以容纳单个字符串、结构化的`Document`对象或文本批次。

为了嵌入文本,提供了多种快捷方法,包括`embed(String text)`方法,它接收一个字符串并返回相应的嵌入向量。所有的快捷方法都是围绕`call`方法实现的,这是调用嵌入模型的主要方法。

嵌入通常返回一个双精度浮点数列表,代表以数值向量格式表示的嵌入。

"`embedForResponse` 方法提供了一个更全面的输出,可能包括关于嵌入的额外信息。"

维度方法是开发人员快速确定嵌入向量大小的便捷工具,这对于理解嵌入空间和后续处理步骤至关重要。

嵌入请求

EmbeddingRequest`是一个`ModelRequest`,它接受一个文本对象列表和可选的嵌入请求选项。以下清单显示了`EmbeddingRequest`类的缩减版本,排除了构造函数和其他工具方法:

public class EmbeddingRequest implements ModelRequest<List<String>> {
	private final List<String> inputs;
	private final EmbeddingOptions options;
	// other methods omitted
}

嵌入响应

EmbeddingResponse` 类的结构如下:

public class EmbeddingResponse implements ModelResponse<Embedding> {

private List<Embedding> embeddings;
private EmbeddingResponseMetadata metadata = new EmbeddingResponseMetadata();
// other methods omitted
}

EmbeddingResponse` 类保存了AI模型的输出,每一个 Embedding 实例包含了来自单一文本输入的结果向量数据。

EmbeddingResponse` 类还携带了有关AI模型响应的`EmbeddingResponseMetadata`元数据。

嵌入

Embedding`代表一个单独的嵌入向量。

public class Embedding implements ModelResult<List<Double>> {
	private List<Double> embedding;
	private Integer index;
	private EmbeddingResultMetadata metadata;
	// other methods omitted
}

可用实现