1. 概述
將人工智能集成到應用程序中通常涉及處理文本數據。 在該領域,嵌入模型是一種關鍵技術,它將文本信息轉換為應用程序可處理的嵌入式表示。
在本教程中,我們將探索 Spring AI 中的嵌入模型 API。 此功能強大的 API 提供了一個抽象層,使您可以輕鬆地採用不同的嵌入模型,並最大限度地減少工作量,從而幫助應用程序理解文本。
2. 嵌入式介紹
為了訓練人工智能模型以學習文本和圖像的語義含義,我們通常會將這些數據類型轉換為高維向量表示,這些表示被稱為嵌入式(embeddings)。
人工智能模型通過計算嵌入式之間的相似度來理解它們之間的關係。當兩個嵌入式之間的相似度得分更高時,這意味着它們所代表的文本的上下文含義相似。
3. 嵌入模型 API
Spring AI 提供了一組 API,以簡化我們與嵌入模型的工作。這些 API 是接口,隱藏了所有實現細節,從而使我們無需關心底層實現。
3.1. 嵌入模型 (EmbeddingModel)
嵌入模型是一種經過訓練的機器學習模型,它將不同類型的對象,例如段落和圖像,轉換為高維向量空間。
有多種模型可供選擇,例如由不同提供商提供的 BERT 模型。 Spring AI 嵌入 API 提供一個 EmbeddingModel 接口,該接口封裝了採用嵌入模型的詳細信息:
public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {
EmbeddingResponse call(EmbeddingRequest request);
// constructors & other methods
}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;
// constructors & other methods
}3.3. EmbeddingResponse
EmbeddingResponse 封裝了嵌入模型提供商的響應。它包含一個 Embedding 對象列表以及諸如 token 使用量之類的額外元數據:
public class EmbeddingResponse implements ModelResponse<Embedding> {
private final List<Embedding> embeddings;
private final EmbeddingResponseMetadata metadata;
// constructors & other methods
}3.4. 嵌入式表示 (Embedding)
嵌入式表示包含在一個float數組中的向量表示。維度取決於我們選擇的嵌入式模型,通常從幾百到大約數千不等:
public class Embedding implements ModelResult<float[]> {
private final float[] embedding;
private final Integer index;
private final EmbeddingResultMetadata metadata;
// constructors & other methods
}4. 與 OpenAI 集成
Spring AI 支持 OpenAI 作為一種嵌入模型集成。 在本部分,我們將使用 OpenAI 並創建一個 Spring 服務,將文本轉換為嵌入。
4.1. Maven 依賴
讓我們首先將以下 Spring AI Open AI 依賴 添加到我們的 pom.xml 中:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>4.2. OpenAI 配置
為了完成 OpenAI 與 Spring AI 的集成,我們需要將 OpenAI API 的認證 API 密鑰配置上。
spring:
ai:
openai:
api-key: "<YOUR-API-KEY>"4.3. 嵌入模型自動配置
Spring AI 能夠自動配置 EmbeddingModel。 讓我們通過在 application.yml 中添加額外的屬性來啓用它:
spring:
ai:
openai:
embedding:
options:
model: "text-embedding-3-small"此 模型屬性配置我們即將使用的嵌入模型。OpenAI 提供了 三種不同的模型。
定義好此嵌入模型後,我們只需將 EmbeddingModel注入到 Spring Boot 服務中,無需指定任何 OpenAI 詳細信息。所有依賴於 Spring AI 的嵌入 API:
@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);
}
}根據我們的示例,我們首先創建了一個 OpenAI 客户端,OpenAiApi,並使用注入的 API 密鑰 openAiApiKey。然後,我們使用該客户端創建 OpenAI 嵌入模型。
我們對服務進行了輕微更新,以注入 OpenAIEmbeddingModel 實現,而不是 EmbeddingModel 接口:
@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,
...
]
}
}值得注意的是,這並非完整響應,因為它非常冗長。我們對其進行了精簡,以描述 JSON 中的兩個主要頂級節點:metadata 和 result。
metadata 提供有關在嵌入轉換過程中使用的模型和資源利用情況的信息。 model 指示我們選擇的 OpenAI 模型,而 totalTokens 則顯示轉換消耗的 token 數量。
result 存儲嵌入結果。 output 在 result 中包含一個 float 數組,該數組是嵌入模型從我們提供的文本轉換後的嵌入。
6. 結論
Spring AI 的嵌入式模型 API 提供了一個抽象層和對模型提供商(如 OpenAI)的支持,使我們能夠將其集成到我們的 Java 應用程序中。
在本文中,我們使用了 OpenAI 作為參考嵌入式模型,並採用自動配置以簡化操作,同時採用手動配置以實現靈活性。嵌入式 API 提供了將文本轉換為嵌入向量的能力。