之前做個幾個大模型的應用,都是使用Python語言,后來有一個項目使用了Java,并使用了Spring AI框架。隨著Spring AI不斷地完善,最近它發布了1.0正式版,意味著它已經能很好的作為企業級生產環境的使用。對于Java開發者來說真是一個福音,其功能已經能滿足基于大模型開發企業級應用。借著這次機會,給大家分享一下Spring AI框架。
注意:由于框架不同版本改造會有些使用的不同,因此本次系列中使用基本框架是 Spring AI-1.0.0,JDK版本使用的是19。
代碼參考: https://github.com/forever1986/springai-study
目錄
- 1 ChatModel 源碼解析
- 2 示例演示
- 2.1 簡單示例
- 2.2 提示詞示例
- 2.3 手動配置示例
上一章解析了ChatClient的創建和底層原理,也知道其最終調用了ChatModel。那這一章,來了解Spring AI的ChatModel。
1 ChatModel 源碼解析
聊天大模型通常的工作方式是向人工智能模型發送提示或部分對話,然后該模型根據其訓練數據和對自然語言模式的理解生成對話的完成部分或延續內容。完成后的響應隨后返回給應用程序,應用程序可以將其呈現給用戶或用于進一步處理。
而Spring AI 秉承著這個工作方式,ChatModel API 被設計成一個簡單且便攜的接口,用于與各種 AI 模型進行交互,使開發人員能夠在不同模型之間切換時只需進行最少的代碼更改。這種設計與 Spring 的模塊化和可互換性理念相一致。
下面來看看ChatModel這個接口的源碼,代碼如下:
public interface ChatModel extends Model<Prompt, ChatResponse>, StreamingChatModel {default String call(String message) {Prompt prompt = new Prompt(new UserMessage(message));Generation generation = call(prompt).getResult();return (generation != null) ? generation.getOutput().getText() : "";}default String call(Message... messages) {Prompt prompt = new Prompt(Arrays.asList(messages));Generation generation = call(prompt).getResult();return (generation != null) ? generation.getOutput().getText() : "";}// 大模型供應商需要實現真正call方法@OverrideChatResponse call(Prompt prompt);default ChatOptions getDefaultOptions() {return ChatOptions.builder().build();}// 大模型供應商需要實現真正stream方法,繼承至StreamingChatModel。流式實現流式方式default Flux<ChatResponse> stream(Prompt prompt) {throw new UnsupportedOperationException("streaming is not supported");}}
說明:從上面代碼看,如果一個大模型供應商要集成到Spring AI,就需要實現ChatModel 接口,實現call和stream方法
在Spring AI中已經實現了很多聊天大模型,如下圖:
說明:上面對于ChatModel 的源碼解析以及Spring AI聊天大模型目前集成的廠商做了一個預覽,下面通過使用ChatModel 方式來調用聊天大模型,而非ChatClient。
2 示例演示
以下代碼參考lesson15子模塊
2.1 簡單示例
代碼參考lesson15子模塊的simple子模塊
示例說明:使用ChatModel方式訪問聊天大模型
1)在lesson15子模塊下,新建simple子模塊,其pom引入如下:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-zhipuai</artifactId></dependency>
</dependencies>
2)配置application.properties文件
# 聊天模型
spring.ai.zhipuai.api-key=你的智譜模型的API KEY
spring.ai.zhipuai.chat.options.model=GLM-4-Flash-250414
spring.ai.zhipuai.chat.options.temperature=0.7
3)新建演示類ChatModelController :
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ChatModelController {private final ChatModel chatModel;@Autowiredpublic ChatModelController(ChatModel chatModel) {this.chatModel = chatModel;}@GetMapping("/chatmodel/generate")public String generate(@RequestParam(value = "message", defaultValue = "請跟我說個笑話!") String message) {return this.chatModel.call(message);}
}
4)新建啟動類Lesson15SimpleApplication :
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Lesson15SimpleApplication {public static void main(String[] args) {SpringApplication.run(Lesson15SimpleApplication.class, args);}}
5)演示效果:
http://localhost:8080/chatmodel/generate
2.2 提示詞示例
代碼參考lesson15子模塊的simple子模塊
示例說明:使用ChatModel方式訪問聊天大模型,并為大模型設定角色
1)沿用lesson15子模塊的的simple子模塊,新建演示類:
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class ChatModelRoleController {private final ChatModel chatModel;@Autowiredpublic ChatModelRoleController(ChatModel chatModel) {this.chatModel = chatModel;}@GetMapping(value = "/chatmodel/systemrole", produces = "text/html;charset=UTF-8") //設定返回的字符,不然會出現亂碼public String systemrole(@RequestParam(value = "message", defaultValue = "空指針一般有什么問題造成的?") String message) {Message systemMessage = new SystemMessage("你是一個精通Java的工程師,專門解決Java遇到的問題。");Message userMessage = new UserMessage(message);Prompt prompt = new Prompt(List.of(systemMessage,userMessage));return this.chatModel.call(prompt).getResult().getOutput().getText();}
}
2)演示效果
http://localhost:8080/chatmodel/systemrole
說明:從上面可以看到如果不使用ChatClient一樣能達到效果,只不過在一些場景下需要自己實現功能,比如聊天記憶、RAG、MCP等。這就說明Spring AI 為了方便用戶使用大模型,遵循的簡單和便利的原則。
2.3 手動配置示例
代碼參考lesson15子模塊的manual-demo子模塊
示例說明:如果你不是SpringBoot項目或者Web項目,Spring AI一樣開發了手動配置ChatModel的包,下面就演示手動配置ChatModel
1)新建lesson16子模塊,其pom引入如下:
<dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-zhipuai</artifactId></dependency>
</dependencies>
2)創建演示類ManualChatModelTest:
import org.springframework.ai.zhipuai.ZhiPuAiChatModel;
import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
import org.springframework.ai.zhipuai.api.ZhiPuAiApi;public class ManualChatModelTest {public static void main(String[] args) {// 設置API KEYvar zhiPuAiApi = new ZhiPuAiApi("你的智譜模型的API KEY");var chatModel = new ZhiPuAiChatModel(zhiPuAiApi, ZhiPuAiChatOptions.builder()// 設置模型.model("GLM-4-Flash-250414")// 設置溫度.temperature(0.7).build());System.out.println(chatModel.call("請跟我說個笑話!"));}
}
3)演示效果
說明:可以看到每個廠商的大模型都提供一個通過手動方式創建的模式,這就是Spring AI框架為了用戶在不同場景下使用考慮的各方各面。
結語:本章通過解析ChatModel源碼,并通過幾個示例演示了不通過ChatClient的方式使用ChatModel。雖然一樣可以實現,但是如果遇到如RAG、MCP等復雜場景,其使用便捷度就沒有ChatClient那么高。ChatModel聊天大模型是比較規范和成熟的模型,因此在Spring AI中有很多不同廠商的實現,下兩章將針對聊天大模型比較常用的2種部署模式進行講解。
Spring AI系列上一章:《Spring AI 系列之十七 - ChatClient源碼解析》
Spring AI系列下一章:《Spring AI 系列之十九 - Ollama集成Deepseek》