1. 概述
在应用中集成人工智能通常需要处理文本数据。嵌入模型(Embedding Model)是这一领域的核心技术,它能将文本信息转换为应用可处理的嵌入向量。
本教程将探索 Spring AI 中的嵌入模型 API。这个强大的 API 提供了抽象层,让我们能轻松切换不同的嵌入模型,帮助应用理解文本语义。
2. 嵌入模型简介
要让 AI 模型学习文本和图像的语义含义,我们通常将这些数据转换为高维向量表示,即嵌入(Embeddings)。
AI 模型通过计算嵌入之间的相似度理解它们的关系。当两个嵌入的相似度分数较高时,表示它们所代表的文本在语义上更接近。
3. 嵌入模型 API
Spring AI 提供了一套简化嵌入模型操作的 API。这些接口封装了所有实现细节,让我们专注于业务逻辑。
3.1. EmbeddingModel 接口
嵌入模型是训练好的机器学习模型,能将段落、图像等对象转换为高维向量空间。
不同提供商(如 BERT)提供多种模型。Spring AI 嵌入 API 通过 EmbeddingModel
接口封装了模型实现细节:
public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {
EmbeddingResponse call(EmbeddingRequest request);
// 构造函数和其他方法
}
call()
方法接收包含数据源的 EmbeddingRequest
,将其发送给模型提供商,并返回包含 Embedding
的 EmbeddingResponse
。
3.2. EmbeddingRequest 类
EmbeddingRequest
包含待转换文本列表的载荷。除了文本,我们还可以添加特定于 EmbeddingModel
的额外选项:
public class EmbeddingRequest implements ModelRequest<List<String>> {
private final List<String> inputs;
private final EmbeddingOptions options;
// 构造函数和其他方法
}
3.3. EmbeddingResponse 类
EmbeddingResponse
封装了嵌入模型提供商的响应。它包含 Embedding
对象列表和元数据(如 token 使用情况):
public class EmbeddingResponse implements ModelResponse<Embedding> {
private final List<Embedding> embeddings;
private final EmbeddingResponseMetadata metadata;
// 构造函数和其他方法
}
3.4. Embedding 类
Embedding
包含 float
数组形式的向量表示。其维度取决于所选模型,通常在几百到几千之间:
public class Embedding implements ModelResult<float[]> {
private final float[] embedding;
private final Integer index;
private final EmbeddingResultMetadata metadata;
// 构造函数和其他方法
}
4. 集成 OpenAI
Spring AI 支持 OpenAI 作为嵌入模型集成方案之一。 本节我们将采用 OpenAI,创建一个将文本转换为嵌入向量的 Spring 服务。
4.1. Maven 依赖
首先在 pom.xml
中添加 Spring AI OpenAI 依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>
4.2. OpenAI 配置
完成集成需要在 application.yml
中配置 OpenAI API 密钥:
spring:
ai:
openai:
api-key: "sk-1234567890abcdef" # 替换为你的实际密钥
4.3. EmbeddingModel 自动配置
Spring AI 能自动配置 EmbeddingModel
。在 application.yml
中添加以下属性启用自动配置:
spring:
ai:
openai:
embedding:
options:
model: "text-embedding-3-small"
model
属性指定使用的嵌入模型。OpenAI 目前提供三种不同模型。
定义模型后,直接在 Spring Boot 服务中注入 EmbeddingModel
即可,无需关心 OpenAI 实现细节:
@Service
public class EmbeddingService {
private final EmbeddingModel embeddingModel;
public EmbeddingService(EmbeddingModel embeddingModel) {
this.embeddingModel = embeddingModel;
}
public EmbeddingResponse getEmbeddings(String... texts) {
EmbeddingRequest request = new EmbeddingRequest(Arrays.asList(texts), null);
return embeddingModel.call(request);
}
}
✅ 自动配置提供了便利,同时隐藏了具体实现细节,让我们只需修改 application.yml
就能轻松切换不同实现。
4.4. EmbeddingModel 手动配置
虽然自动配置很方便,但某些场景下缺乏灵活性,比如需要同时使用多个嵌入模型或不同提供商时。
此时可在配置类中手动定义嵌入模型:
@Configuration
public class EmbeddingConfig {
@Bean
public OpenAiApi openAiApi(@Value("${spring.ai.openai.api-key}") String apiKey) {
return OpenAiApi.builder()
.apiKey(apiKey)
.build();
}
@Bean
public OpenAiEmbeddingModel openAiEmbeddingModel(OpenAiApi openAiApi) {
OpenAiEmbeddingOptions options = OpenAiEmbeddingOptions.builder()
.model("text-embedding-3-small")
.build();
return new OpenAiEmbeddingModel(openAiApi, MetadataMode.EMBED, options);
}
}
首先使用注入的 API 密钥创建 OpenAI 客户端 OpenAiApi
,然后用该客户端创建 OpenAI 嵌入模型。
修改服务类注入 OpenAIEmbeddingModel
实现而非接口:
@Service
public class ManualEmbeddingService {
private final OpenAiEmbeddingModel openAiEmbeddingModel;
public ManualEmbeddingService(OpenAiEmbeddingModel openAiEmbeddingModel) {
this.openAiEmbeddingModel = openAiEmbeddingModel;
}
public EmbeddingResponse getEmbeddings(String... texts) {
EmbeddingRequest request = new EmbeddingRequest(Arrays.asList(texts), null);
return openAiEmbeddingModel.call(request);
}
}
5. 测试嵌入服务
基于前文的自动配置服务,我们暴露一个 REST 接口测试嵌入服务:
@RestController
public class EmbeddingController {
private final EmbeddingService embeddingService;
public EmbeddingController(EmbeddingService embeddingService) {
this.embeddingService = embeddingService;
}
@PostMapping("/embeddings")
public ResponseEntity<EmbeddingResponse> getEmbeddings(@RequestBody String text) {
EmbeddingResponse response = embeddingService.getEmbeddings(text);
return ResponseEntity.ok(response);
}
}
使用 curl 向该接口发送请求:
$ curl -X POST http://localhost:8080/embeddings -H "Content-Type: text/plain" -d "Hello world"
响应如下(为简洁起见已截断):
{
"metadata": {
"model": "text-embedding-3-small",
"usage": {
"promptTokens": 2,
"completionTokens": 0,
"totalTokens": 2,
"nativeUsage": {
"prompt_tokens": 48,
"total_tokens": 48
}
},
"empty": true
},
"result": {
"index": 0,
"metadata": {
"modalityType": "TEXT",
"documentId": "",
"mimeType": {
"type": "text",
"subtype": "plain",
"parameters": {},
"charset": null,
"concrete": true,
"wildcardSubtype": false,
"subtypeSuffix": null,
"wildcardType": false
},
"documentData": null
},
"output": [
-0.0020785425,
-0.049085874,
...
]
}
}
⚠️ 注意这不是完整响应,实际数据非常长。我们截取后重点说明两个顶级节点:
metadata:提供模型信息和资源使用情况
model
:使用的 OpenAI 模型totalTokens
:转换消耗的 token 数量
result:包含嵌入结果
output
:由模型生成的float
数组向量
6. 总结
Spring AI 的嵌入模型 API 提供了抽象层和对 OpenAI 等模型提供商的支持,使我们能轻松将其集成到 Java 应用中。
本文通过 OpenAI 演示了两种配置方式:✅ 自动配置适合简单场景,✅ 手动配置提供更高灵活性。嵌入 API 核心能力是将文本转换为嵌入向量。
完整代码示例请查看 GitHub 仓库。