1. 概述
現代應用程序越來越多地使用大型語言模型 (LLM) 構建超越傳統編程能力的解決方案。然而,將這些模型集成到我們的應用程序中通常涉及處理複雜的 API、管理不同的 AI 提供商以及處理各種配置挑戰。
Spring AI,是 Spring 生態系統中新增的組件,通過提供一種通用的抽象層,使用熟悉的 Spring 編程模式來與不同的 AI 提供商進行交互,從而解決了這些問題。
它消除了顯式使用特定提供商 SDK 的需求,並允許我們在不修改應用程序代碼的情況下在不同的模型之間切換。
在本教程中,我們將通過構建一個基本的詩歌生成服務來實踐探索 Spring AI 的基本概念。
2. 項目設置
為了演示我們的詩歌生成服務,我們將使用 OpenAI 的 GPT-5 模型。
然而,Spring AI 支持來自其他提供商的模型,例如 Anthropic、DeepSeek,以及通過 Hugging Face 或 Ollama 的本地 LLM。 我們可以根據具體要求選擇最合適的模型,因為在本次實現中,具體的 AI 模型並不重要。
2.1. 依賴項
讓我們首先添加必要的依賴項到我們項目的 pom.xml 文件中:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
<version>1.0.1</version>
</dependency>OpenAI starter 依賴項是一個圍繞 OpenAI 的 Chat Completions API 的包裝器,我們將使用它來與我們應用程序中的 GPT-5 模型進行交互。
2.2. 配置 LLM 屬性
接下來,讓我們在 application.yaml 文件中配置我們的 OpenAI API 密鑰 和聊天模型:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-5
temperature: 1我們使用 ${} 屬性佔位符從環境變量中加載我們的 API 密鑰。
接下來,我們指定 gpt-5 作為模型 ID。根據需求,我們可以使用 不同的模型。
此外,我們將 temperature 設置為 1,因為我們配置的模型 僅接受此默認值。
3. 構建詩歌生成服務
有了我們已配置的設置,現在我們將構建一個使用配置好的 LLM 生成詩歌的服務。我們首先將從一個基本實現開始,然後逐步重構它以利用更高級的 Spring AI 功能。
3.1. 使用 ChatClient 與 LLM 進行通信
在 Spring AI 中,ChatClient 類作為與我們配置的任何模型進行交互的主要入口點。
我們可以使用 ChatClient.Builder Bean 獲取該實例,該框架會自動根據我們在 application.yaml 文件中配置的屬性為我們創建它。
讓我們使用它來創建一個新的 PoetryService 類:
private final ChatClient chatClient;
PoetryService(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
String generate() {
return chatClient
.prompt("Write a playful haiku about morning coffee following the traditional 5-7-5 syllable structure.")
.call()
.content();
}在這裏,我們向服務的構造函數注入 ,並使用它構建一個 實例。
接下來,在我們的 generate() 方法中,我們使用 的 prompt() 方法發送一個請求,請求一首 俳句。
然後,我們調用 call() 方法來執行請求,並使用 content() 方法提取生成的文本作為簡單的 String。
3.2. 使用 `PromptTemplate> 和結構化輸出進行重構
雖然我們的初始實現能夠工作,但它僅限於生成關於咖啡的俳句,並且返回一個簡單的字符串響應,對於客户端來説可能難以處理。
為了解決這些侷限性,我們將重構我們的服務,使用 PromptTemplate,以便在運行時動態地替換流派和主題值,並將 LLM 的響應映射到結構化的 Java 對象。
首先,讓我們定義一個 `Poem> 記錄來表示輸出的結構:
record Poem(
String title,
String content,
String genre,
String theme) {
}我們定義了包含 標題、內容、類型 和 主題 字段的記錄,以代表我們期望從 LLM 獲得的結果結構。
接下來,讓我們重構我們的服務方法:
private final static PromptTemplate PROMPT_TEMPLATE
= new PromptTemplate("Write a {genre} haiku about {theme} following the traditional 5-7-5 syllable structure.");
Poem generate(String genre, String theme) {
Prompt prompt = PROMPT_TEMPLATE
.create(Map.of(
"genre", genre,
"theme", theme));
return chatClient
.prompt(prompt)
.call()
.entity(Poem.class);
}在我們的重構版本中,我們用 PromptTemplate 替換了硬編碼的提示,該 PromptTemplate 包含用於 流派 和 主題 的佔位符。在 generate() 方法中,我們現在期望這些值在方法參數中,並使用它們來創建 Prompt 實例。
此外,我們用 entity() 方法替換了 content() 方法,其中我們指定了我們的 Poem 記錄。 Spring AI 將會自動向提示中添加指令,以引導 LLM 生成可以映射到此記錄的響應。
3.3. 暴露 REST API 並處理錯誤
現在我們已經實現了服務層,讓我們在上面暴露一個 REST API:
@PostMapping("/poems")
ResponseEntity<Poem> generate(@RequestBody PoemGenerationRequest request) {
Poem response = poetryService.generate(request.genre, request.theme);
return ResponseEntity.ok(response);
}
record PoemGenerationRequest(String genre, String theme) {}在這裏,我們簡單地定義了一個 POST /poems 端點,它接受 PoemGenerationRequest 記錄作為請求體,並直接委託給我們的服務層以返回生成的詩歌。
此外,與與任何外部服務進行通信一樣,配置的 LLM 有時可能會失敗。為了優雅地處理此類場景,OpenAI 錯誤 提供了一個抽象層。
讓我們為該類定義一個異常處理程序:
private static final String LLM_COMMUNICATION_ERROR =
"Unable to communicate with the configured LLM. Please try again later.";
@ExceptionHandler(OpenAiApiClientErrorException.class)
ProblemDetail handle(OpenAiApiClientErrorException exception) {
logger.error("OpenAI returned an error.", exception);
return ProblemDetail.forStatusAndDetail(HttpStatus.SERVICE_UNAVAILABLE, LLM_COMMUNICATION_ERROR);
}在這裏,我們故意避免在響應中暴露實際的錯誤詳情,以防止泄露有關我們基礎設施或 API 密鑰的敏感信息。相反,我們為調試目的記錄完整的異常,並通過標準化的 ProblemDetail 響應格式返回一個用户友好的消息。
4. 測試我們的應用程序
最後,讓我們使用我們暴露的 API 端點與我們的應用程序進行交互和測試。
我們將使用 HTTPie CLI 調用 API:
http POST :8080/poems genre="frustrated" theme="code review comments"在這裏,我們向我們的 /poems 端點發送一個 POST 請求,其中包含我們想要的 流派 和 主題。
讓我們看看我們收到的響應內容:
{
"title": "Nitpick Nightmare",
"content": "Tabs versus spaces\nThey argue while prod is down\nPriorities... where?",
"genre": "frustrated",
"theme": "code review comments"
}如我們所見,我們得到一首能夠有效捕捉我們提供的類型和主題的俳句。
這證實我們的應用程序正確地填充了提示模板,並接收了 LLM 的輸出,該輸出可以映射到我們的 詩歌記錄。
5. 結論
在本文中,我們探討了如何將人工智能能力集成到 Spring Boot 應用程序中,使用 Spring AI。
我們詳細介紹了必要的配置,並使用 OpenAI 的 GPT-5 模型實現了詩歌生成服務。我們從基於字符串的提示到更復雜的解決方案,利用提示模板和結構化輸出,不斷改進了我們的簡單實現。
雖然本教程涵蓋了基本原理,但 Spring AI 提供了廣泛的人工智能能力,可以在我們的 Spring AI 教程系列中進行探索。