Google Cloud 和 Spring AI
1.概述
Spring AI 是一個應用程式框架,它具有適用於各種 LLM 的通用接口,可幫助我們將它們整合到我們的 Spring Boot 應用程式中。
在本教程中,我們將探討如何將 Spring AI 與 Google Cloud Vertex AI 平台集成,並採用各種模型在我們的應用程式中提供聊天和嵌入功能。
2. 先決條件
我們需要 Spring AI Vertex AI Gemini並在我們的pom.xml
中嵌入依賴項:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-vertex-ai-gemini</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-vertex-ai-embedding</artifactId>
</dependency>
這些啟動模型依賴項將根據我們在application.yml
中的設定自動配置 Vertex AI 模型。
第一步,我們必須在 Google Cloud 控制台中啟用 Vertex AI API,以便對 Vertex AI 進行 API 呼叫。
一旦啟用,我們需要在安裝了 Google Cloud CLI 的控制台中執行兩個額外的命令。
第一個指令為所有後續 CLI 指令設定活動項目:
$ gcloud config set project <PROJECT-ID>
PROJECT-ID
參數是我們啟用了 Vertex AI 的 Google Cloud 專案的唯一 ID。
第二個進行身份驗證並為我們提供 OAuth2 存取令牌,該令牌授予我們存取 Vertex AI API 的權限:
$ gcloud auth application-default login <YOUR-ACCOUNT>
這將開啟一個 Web 瀏覽器窗口,並提示我們使用 Google Cloud 帳戶登入。登入後,它會將 OAuth2 存取權令牌保存在本機。
3.聊天
Gemini 是 Vertex AI 中提供的聊天模型。在本節中,我們將把 Gemini 整合到我們的 Spring Boot 應用程式中。
3.1. 配置
我們需要在application.yml
中添加一些屬性,以將聊天模型與 Spring AI 整合:
spring:
ai:
vertex:
ai:
gemini:
project-id: <YOUR-GOOGLE-CLOUD-PROJECT-ID>
location: "europe-west1"
model: "gemini-2.0-flash-lite"
project-id
屬性指定在我們的應用程式中應使用哪些 Google Cloud 專案資源(包括驗證和計費)。
model
屬性指定了我們將整合哪個 Gemini 聊天模型。有多種 Gemini車型可供選擇。
3.2. 服務
讓我們建立一個簡單的ChatService
來接受提示作為輸入參數:
@Component
@SessionScope
public class ChatService {
private final ChatClient chatClient;
public ChatService(ChatModel chatModel, ChatMemory chatMemory) {
this.chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
.build();
}
public String chat(String prompt) {
return chatClient.prompt()
.user(userMessage -> userMessage.text(prompt))
.call()
.content();
}
}
在這個服務中,我們注入自動配置的 Gemini ChatModel
來建立我們的ChatClient
實例。
由於 LLM 是無狀態的,它們無法取得先前的對話訊息。因此,我們也注入了一個ChatMemory
實例,以便提供類似對話的體驗。
為了測試目的,我們需要一個ChatController
來接受查詢:
@RestController
public class ChatController {
private final ChatService chatService;
public ChatController(ChatService chatService) {
this.chatService = chatService;
}
@PostMapping("/chat")
public ResponseEntity<String> chat(@RequestBody @NotNull String prompt) {
String response = chatService.chat(prompt);
return ResponseEntity.ok(response);
}
}
此控制器接受請求正文中的字串,並透過ChatService
將提示傳送給 Gemini 聊天模型。
3.3. 測試運行
現在,讓我們透過 Postman 向此端點發出一個請求來執行測試。我們應該會看到來自 Gemini 的回應:
4.文本嵌入
文字嵌入是將自然語言文字輸入轉換為高維向量表示的過程。嵌入的用例可以是基於上下文含義執行相似性搜尋。
4.1. 配置
我們需要一個不同的模型來將文字轉換為嵌入。讓我們在application.yml
中加入一些屬性:
spring:
ai:
vertex:
ai:
embedding:
project-id: <YOUR-GOOGLE-CLOUD-PROJECT-ID>
location: "europe-west1"
text:
options:
model: "gemini-embedding-001"
與聊天模型類似,我們需要定義project-id
和location
屬性,我們可以套用上一個聊天設定部分定義的值。
4.2. 服務
現在,我們的應用程式已配置為將EmbeddingModel
注入到我們的服務中。我們現在可以定義一個TextEmbeddingService
類別來將文字轉換為嵌入:
@Service
public class TextEmbeddingService {
private final EmbeddingModel embeddingModel;
public TextEmbeddingService(EmbeddingModel embeddingModel) {
this.embeddingModel = embeddingModel;
}
public EmbeddingResponse getEmbedding(String... texts) {
EmbeddingRequest request = new EmbeddingRequest(Arrays.asList(texts), null);
return embeddingModel.call(request);
}
}
讓我們建立一個TextEmbeddingController
來執行測試運行:
@RestController
public class TextEmbeddingController {
private final TextEmbeddingService textEmbeddingService;
public TextEmbeddingController(TextEmbeddingService textEmbeddingService) {
this.textEmbeddingService = textEmbeddingService;
}
@PostMapping("/embedding/text")
public ResponseEntity<EmbeddingResponse> getEmbedding(@RequestBody @NotNull String text) {
EmbeddingResponse response = textEmbeddingService.getEmbedding(text);
return ResponseEntity.ok(response);
}
}
4.3. 測試運行
現在,我們準備好測試我們的文字嵌入服務。讓我們向這個端點發送一些文本,看看它返回什麼:
完成後,端點返回元數據,最重要的是,返回我們在output
屬性中找到的嵌入。
5. 多模態嵌入
除了文字之外,Vertex AI 還能夠將各種媒體(例如圖像)轉換為嵌入。
我們甚至不需要對多模式嵌入服務進行任何額外的配置。我們只需要在application.yml
中新增文字嵌入配置。
5.1. 服務
讓我們建立一個MultiModalEmbeddingService
來將不同的影像轉換為嵌入:
@Service
public class MultiModalEmbeddingService {
private final DocumentEmbeddingModel documentEmbeddingModel;
public MultiModalEmbeddingService(DocumentEmbeddingModel documentEmbeddingModel) {
this.documentEmbeddingModel = documentEmbeddingModel;
}
public EmbeddingResponse getEmbedding(MimeType mimeType, Resource resource) {
Document document = new Document(new Media(mimeType, resource), Map.of());
DocumentEmbeddingRequest request = new DocumentEmbeddingRequest(List.of(document));
return documentEmbeddingModel.call(request);
}
}
我們需要圖像Resource
及其 MIME 類型,以便將其轉換為嵌入。目前,Vertex AI 接受 BMP、GIF、JPG 和 PNG 圖像格式。
讓我們建立一個從請求中接受圖像檔案的控制器。它從請求內容類型派生出 MIME 類型,並將圖像檔案Resource
連同 MIME 類型一起傳送到MultiModalEmbeddingService
:
@RestController
public class MultiModalEmbeddingController {
private final MultiModalEmbeddingService embeddingService;
public MultiModalEmbeddingController(MultiModalEmbeddingService embeddingService) {
this.embeddingService = embeddingService;
}
@PostMapping("/embedding/image")
public ResponseEntity<EmbeddingResponse> getEmbedding(@RequestParam("image") @NotNull MultipartFile imageFile) {
EmbeddingResponse response = embeddingService.getEmbedding(
MimeType.valueOf(imageFile.getContentType()),
imageFile.getResource());
return ResponseEntity.ok(response);
}
}
5.2. 測試運行
這次我們將向控制器端點發送圖像而不是文字:
完成後,我們得到了與文字嵌入類似的回應,並且我們會在回應的output
屬性中找到圖像嵌入。
6. 結論
Spring AI 簡化了 LLM 與我們應用程式的集成,這有助於我們以最小的開發工作量採用和切換不同的 LLM。
在本文中,我們探索如何在 Spring Boot 應用程式中設定 Vertex AI。我們也學習如何應用 Gemini 聊天模型和嵌入模型將文字和圖像轉換為嵌入,以便進一步處理和分析。
與往常一樣,我們的完整程式碼範例可在 GitHub 上找到。