前言
到目前為止,我們整個系列的旅程都是在功能強大的LangChain4j框架上構建的。它就像一個裝備齊全的“瑞士軍刀”,為我們提供了構建RAG和Agents所需的所有底層和高層工具。
然而,在Java企業級開發的世界里,有一個名字我們永遠無法忽視——Spring。當AI浪潮來襲,Spring官方團隊自然不會缺席。他們推出了自己的解決方案:Spring AI。
那么,Spring AI是什么?它和我們已經熟練使用的LangChain4j是什么關系?是競爭者還是協作者?它能為我們帶來什么新的價值?今天,我們將一起探索這個由Spring官方打造的AI框架,體驗它所帶來的“原生”開發感受。
第一部分:什么是Spring AI?
Spring AI是一個應用框架,旨在將AI功能(特別是基于大語言模型的功能)以一種**“Spring原生”**的方式,無縫集成到企業級應用中。
它的核心設計哲學不是從零開始創造一切,而是:
- 提供統一的頂層抽象:無論底層模型是來自OpenAI、Google、Azure還是HuggingFace,Spring AI都力求提供一套統一的、面向接口的API,如
ChatClient
和EmbeddingClient
。 - 擁抱Spring生態:充分利用Spring Boot的自動配置、依賴注入和外部化配置等核心特性。你不需要手動創建客戶端,只需要在
application.properties
中填寫配置,相應的Bean就會被自動創建和注入。 - 可移植性:它的目標是讓你的業務代碼與具體的AI模型提供商解耦。理論上,你只需要修改配置文件,就能從OpenAI切換到Azure OpenAI,而無需改動Java代碼。
Spring AI vs. LangChain4j:是什么關系?
它們并非嚴格的競爭關系,而是不同層面的抽象。Spring AI更側重于簡化集成和提升Spring開發者的體驗。事實上,Spring AI的某些模塊底層就是由LangChain4j驅動的!你可以把Spring AI看作是一個更高層次的“門面”,它為你整合了包括LangChain4j在內的多種AI庫,并用一層標準的Spring接口將其包裝起來。
第二部分:在Spring Boot中集成Spring AI
讓我們在一個新的分支或項目中,體驗一下Spring AI的配置過程。
-
修改
pom.xml
Spring AI有自己的BOM(Bill of Materials)來管理版本。我們需要先引入BOM,再添加具體的Starter。<properties><java.version>21</java.version><!-- 定義Spring AI的版本 --><spring-ai.version>1.0.0-M3</spring-ai.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- Spring AI OpenAI Starter --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency><!-- Spring AI Vector Store - Simple (內存向量存儲) --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-transformers-spring-boot-starter</artifactId></dependency><!-- JSON處理 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories>
注意:請根據Spring AI的最新發布情況調整版本和倉庫配置。
-
修改
application.properties
Spring AI有自己的一套配置屬性,命名空間是spring.ai
。# ========================================== # Spring AI Demo 配置文件 # ==========================================# 服務器端口配置 server.port=8080# ========================================== # Spring AI OpenAI 配置 # ==========================================# OpenAI API密鑰 (請設置環境變量 OPENAI_API_KEY) spring.ai.openai.api-key=${OPENAI_API_KEY:your-api-key-here}# OpenAI API基礎URL (支持代理服務) spring.ai.openai.base-url=${OPENAI_BASE_URL:https://yibuapi.com/}# 聊天模型配置 spring.ai.openai.chat.options.model=${OPENAI_MODEL:gpt-4o-mini} spring.ai.openai.chat.options.temperature=${OPENAI_TEMPERATURE:0.7} spring.ai.openai.chat.options.max-tokens=${OPENAI_MAX_TOKENS:2000}# ========================================== # 應用程序配置 # ==========================================# 應用名稱 spring.application.name=springboot-langchain4j-demo# 日志配置 logging.level.org.springframework.ai=DEBUG logging.level.org.example.demo=DEBUG# ========================================== # Web配置 # ==========================================# 靜態資源配置 spring.web.resources.static-locations=classpath:/static/ spring.web.resources.cache.period=3600# 編碼配置 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true server.servlet.encoding.force=true
僅僅這樣配置,Spring AI的Starter就會為我們自動創建一個配置好的
ChatClient
Bean。
第三部分:實戰 - 使用ChatModel
進行聊天
現在,我們將創建一個新的Service和Controller,體驗一下ChatModel
的流暢API。
-
創建
SpringAiService.java
package com.example.aidemoapp.service;import lombok.RequiredArgsConstructor; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.stereotype.Service;@Service @RequiredArgsConstructor public class SpringAiService {private final ChatModel chatModel;/*** 簡單聊天對話*/ public String getSimpleChatResponse(String userPrompt) {return chatModel.call(userPrompt); }/*** 使用模板的聊天對話*/ public String getChatResponseWithTemplate(String topic, String style) {String template = "請用{style}的風格來介紹{topic},內容要詳細且有趣。";PromptTemplate promptTemplate = new PromptTemplate(template);Prompt prompt = promptTemplate.create(Map.of("topic", topic,"style", style));return chatModel.call(prompt).getResult().getOutput().getContent(); } }
代碼解析:
- 我們沒有看到任何
OpenAi...
相關的類,代碼完全面向ChatModel
這個抽象接口。 - API調用是鏈式的,非常清晰:定義提示 -> 發起調用 -> 獲取內容。
- 我們沒有看到任何
-
創建
SpringAiController.java
package com.example.aidemoapp.controller;import com.example.aidemoapp.service.SpringAiService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/api/spring-ai") @RequiredArgsConstructor public class SpringAiController {private final SpringAiService springAiService;/*** 簡單聊天接口*/@GetMapping("/chat")public Map<String, Object> chat(@RequestParam("query") String query) {try {String response = springAiService.getSimpleChatResponse(query);return Map.of("success", true,"data", response,"message", "聊天成功");} catch (Exception e) {return Map.of("success", false,"data", "","message", "聊天失敗: " + e.getMessage());}}/*** 模板聊天接口*/@PostMapping("/chat/template")public Map<String, Object> chatWithTemplate(@RequestBody Map<String, String> request) {try {String topic = request.get("topic");String style = request.get("style");String response = springAiService.getChatResponseWithTemplate(topic, style);return Map.of("success", true,"data", response,"message", "模板聊天成功");} catch (Exception e) {return Map.of("success", false,"data", "","message", "模板聊天失敗: " + e.getMessage());}} }
第四步:對比與思考
現在我們可以清楚地看到Spring AI和LangChain4j在設計哲學上的異同:
- 配置方式:兩者都支持外部化配置,但命名空間不同。Spring AI的
spring.ai.*
對于Spring開發者來說更具辨識度。 - 核心抽象:
- Spring AI:核心是
ChatModel
,一個非常直接、面向任務的客戶端。它的目標是讓你用最少的代碼完成最常見的任務。 - LangChain4j:核心是
ChatLanguageModel
接口和AiServices
工廠/注解。它更側重于將一個Java接口映射為一個AI服務,提供了更靈活的、聲明式的編程模型。
- Spring AI:核心是
- 易用性:
- 對于簡單的聊天或嵌入任務,Spring AI的
ChatClient
極其簡單直接,學習成本幾乎為零。 - 對于構建復雜的RAG或Agent流,LangChain4j通過
RetrievalAugmentor
和@Tool
等組件提供了更結構化、更專門的解決方案。
- 對于簡單的聊天或嵌入任務,Spring AI的
我應該用哪個?
- 如果你是Spring重度用戶,且需求是快速將聊天、RAG等標準功能集成到應用中,Spring AI是你的不二之選。它的無縫集成和極低的上手門檻會讓你事半功倍。
- 如果你需要構建高度定制化的AI工作流,或者需要使用一些LangChain4j獨有的高級功能,直接使用LangChain4j會給你更大的靈活性和控制力。
好消息是,你不必二選一。你完全可以在一個Spring AI項目中使用LangChain4j的組件,它們可以和諧共存。
總結
今天,我們探索了Spring官方的AI解決方案——Spring AI。我們了解了它以“Spring原生體驗”為核心的設計思想,并通過ChatClient
體驗了其簡潔流暢的API。
我們現在武器庫中又增添了一件利器。我們既有功能全面、靈活強大的LangChain4j,又有與Spring生態無縫集成的Spring AI。作為開發者,我們可以根據項目的具體需求,選擇最合適的工具。
在我們開發之旅接近尾聲時,我們已經探索了多種工具和技術。但無論技術如何,將AI應用推向生產環境,都會面臨一些共通的挑戰。
源碼獲取
本文中所有實戰代碼均已同步更新至Gitee倉庫。建議您git pull
拉取最新代碼,對照本文進行學習。
- Gitee倉庫地址: https://gitee.com/chaocloud/spring-ai-demo
下一篇預告:
《Java大模型開發入門 (14/15):生產環境考量 - 成本、安全與性能優化》—— 我們將從編碼轉向工程,探討在生產環境中部署和運維一個LLM應用時,必須考慮的成本控制、安全防護和性能優化等關鍵問題。