Spring AI 系列之十八 - ChatModel

之前做個幾個大模型的應用,都是使用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》

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/89950.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/89950.shtml
英文地址,請注明出處:http://en.pswp.cn/web/89950.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux學習之Linux系統權限

在上一篇的內容中我們學習到了Linux系統命令相關的知識及其相關的擴展內容&#xff0c;本期我們將學習Linux基礎的另一個重要部分&#xff1a;Linux系統權限管理 作者的個人gitee&#xff1a;樓田莉子 (riko-lou-tian) - Gitee.com 目錄 權限概念及必要性 什么是權限 為什么要…

Web3.0 能為你帶來哪些實質性的 改變與突破

如今各種大廠裁員消息層出不窮&#xff0c;今年又添飛書、剪映、微軟、思科... 這有一張網友整理的去年互聯網大廠裁員裁員信息表&#xff1a; 目前國內很多大廠都在裁員&#xff0c;非常現實、且越來越多 35 技術人&#xff0c;正在面臨這樣的問題&#xff0c;那么Web3.0 確實…

doker centos7安裝1

1.什么是doker Docker 是一個開源的應用容器引擎&#xff0c;它允許開發者將應用程序及其依賴項打包到一個可移植的容器中&#xff0c;然后發布到任何支持 Docker 的操作系統上&#xff0c;實現 “一次構建&#xff0c;到處運行”。 容器是一種輕量級的虛擬化技術&#xff0c…

自動化面試題

1、什么是測試套件測試套件是多個測試用例的集合。2、搭建接口自動化框架中&#xff0c;你遇到最大的難點是什么&#xff0c;以及怎么解決的?測試數據動態管理難點:接口依賴動態參數(如Token、訂單ID)&#xff0c;數據無法硬編碼.解決方案:使用關聯提取(如正則提取響應中的Tok…

【Linux】LVS(Linux virual server)環境搭建

一、LVS的運行原理1.1 LVS簡介LVS:Linux Virtual Server&#xff0c;負載調度器&#xff0c;內核集成&#xff0c;章文嵩&#xff0c;阿里的四層SLB(Server LoadBalance)是基于LVSkeepalived實現LVS 官網: http://www.linuxvirtualserver.org/ LVS 相關術語 VS: Virtual Server…

算法競賽備賽——【圖論】求最短路徑——Dijkstra

Dijkstra 用來計算從一個點到其他所有點的最短路徑的算法&#xff0c;是一種單源最短路徑算法。也就是說&#xff0c;只能計算起點只有一個的情況。Dijkstra的時間復雜度是O (|v|^2)&#xff0c;它不能處理存在負邊權的情況。 鄰接矩陣存圖 #include<iostream> using …

影刀 RPA:批量修改 Word 文檔格式,高效便捷省時省力

在日常辦公和文檔處理中&#xff0c;Word 文檔格式的統一和規范是許多企業和個人用戶的重要需求。無論是撰寫報告、制作提案&#xff0c;還是整理資料&#xff0c;都需要確保文檔格式的一致性。然而&#xff0c;手動修改多個 Word 文檔的格式不僅耗時費力&#xff0c;還容易因疏…

GitLab 社區版 10.8.4 安裝、漢化與使用教程

一、GitLab 安裝 GitLab 提供了集成所需軟件的 RPM 包&#xff0c;簡化了安裝流程。我們選擇安裝社區版&#xff08;CE&#xff09;10.8.4&#xff0c;可通過官方網站或國內鏡像源&#xff08;如清華鏡像&#xff09;獲取安裝包。 1. 準備工作 首先創建工具目錄并進入&#…

[硬件電路-64]:模擬器件 -二極管在穩壓電路中的應用

二極管在穩壓電路中的應用主要基于其單向導電性和特定類型二極管&#xff08;如穩壓二極管&#xff09;的電壓穩定特性。以下是詳細解釋&#xff1a;一、普通二極管的穩壓作用&#xff08;有限場景&#xff09;正向導通壓降的利用&#xff1a;原理&#xff1a;普通二極管在正向…

【Linux】重生之從零開始學習運維之Nginx

安裝apt/yum安裝apt imstall nginx yum install nginxRocky源碼編譯安裝基礎編譯環境yum install gcc make gcc-c glibc glibc-devel pcre pcre-devel openssl openssldevel systemd-devel zlib-devel yum install libxml2 libxml2-devel libxslt libxslt-devel php-gd gd-deve…

主流 MQ 的關鍵性能指標

常用消息隊列&#xff08;MQ&#xff09;的“數量級”通常圍繞吞吐量&#xff08;TPS&#xff0c;每秒處理消息數&#xff09;、消息堆積能力、延遲三個核心指標展開&#xff0c;不同MQ因設計目標&#xff08;高吞吐、低延遲、高可靠等&#xff09;不同&#xff0c;數量級差異顯…

[NIPST AI]對抗性機器學習攻擊和緩解的分類和術語

原文link&#xff1a;https://nvlpubs.nist.gov/nistpubs/ai/NIST.AI.100-2e2025.pdf Introduction 人工智能&#xff08;AI&#xff09;系統在過去幾年中持續全球擴展。這些系統正在被眾多國家開發并廣泛部署于各自的經濟體系中&#xff0c;人們在生活的許多領域都獲得了更多使…

[深度學習] 大模型學習3上-模型訓練與微調

在文章大語言模型基礎知識里&#xff0c;模型訓練與微調作為大語言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;應用構建的主要方式被簡要提及&#xff0c;本系列文章將從技術原理、實施流程及應用場景等維度展開深度解析。相關知識的進一步參考見&#x…

Claude Code 啟動提示 Note: Claude Code might not be available in your country. 解決

如下圖所示 主播參考了在別的地方看來的解決方案&#xff08;并非主播不想標注來源&#xff0c;主要是忘記是哪里看來的了&#xff0c;下班就忘記了&#xff0c;懶得找了&#x1f62d;&#xff0c;如果后續找到會補上的&#xff09;。 好了&#xff0c;開始正文&#xff0c;開始…

Unity VR多人手術系統恢復3:Agora語音通訊系統問題解決全記錄

&#x1f3af; 前言 這是一個Unity多人VR手術模擬項目&#xff0c;已經擱置了近兩年時間。最近重新啟動了這個項目&#xff0c;然而在恢復過程中卻遇到了些的技術障礙。 項目重啟遇到的挑戰 當我們重新部署和測試系統時&#xff0c;發現原本運行良好的Agora語音通訊功能完全…

sqli-labs靶場通關筆記:第46-53關 order by注入

目錄 第46關 order by注入 第47關 閉合的order by注入 第48關 無報錯回顯的數字型order by注入 第49關 無報錯回顯的閉合型order by注入 第50關 基于order by的堆疊注入 第51關 閉合的報錯注入或堆疊注入 第52關 數字型盲注或堆疊注入 第53關 閉合的盲注或堆疊注入 第…

cdh6.3.2的hive使用apache paimon格式只能創建不能寫報錯的問題

前言根據官網paimon安裝教程&#xff0c;看上去簡單&#xff0c;實則報錯阻礙使用的信心。 解決方法原帶的jars下的zstd開頭的包舊了&#xff0c;重新下載zstd較新的包單獨放到每個節點的hive/lib下;然后將hdfs yarn用戶下的mr-framework.tar.gz中的zstdjar包替換成新的版本。重…

【Vue進階學習筆記】實現圖片懶加載

創建Vue項目 首先確保你已安裝Vue CLI&#xff0c;然后創建一個新的Vue 3項目&#xff1a; npm init vuelatest安裝依賴 安裝vueuse/core庫&#xff0c;它提供了useIntersectionObserver組合式API&#xff1a; cnpm install cnpm install vueuse/core創建指令文件夾和文件 在sr…

深入理解 synchronized

深入理解 synchronized 引言&#xff1a;synchronized的核心地位 在Java并發編程中&#xff0c;synchronized關鍵字是實現線程安全的基石。自JDK 1.0引入以來&#xff0c;它經歷了從"重量級鎖"到"自適應鎖"的進化&#xff0c;如今已成為兼顧安全性與性能的…

C語言字符串相關函數

C語言筆記內容提要數組字符串基本操作字符串相關函數綜合案例&#xff1a;學生成績管理系統數組字符串基本操作在用格式化說明符%s進行輸入輸出時&#xff0c;其輸入輸出項均為數組名。但在輸入時&#xff0c;相鄰兩個字符串之間要用空格分隔&#xff0c;系統將自動在字符串后加…