springAI結(jié)合ollama簡單實現(xiàn)小結(jié)
一、ollama安裝下載
1、官方下載地址
2、修改模型的安裝地址
Ollama的模型會占用較大的磁盤空間,默認(rèn)會在C盤用戶文件夾下的.ollama/models文件夾中,可以配置環(huán)境變量OLLAMA_MODELS,設(shè)置為指定的路徑:
3、模型參考
下載命令:
# 電腦性能好的可以裝一個高版本的,例如4b、7b等 ollama run qwen:0.5b # 查看已安裝的模型 ollama list
二、springAI的使用
1、環(huán)境準(zhǔn)備
jdk17、springboot3.0+
2、添加依賴
這里貼出完整pom:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>ollamaTest</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-ai-ollama</name> <description>spring-ai-ollama</description> <properties> <java.version>17</java.version> <!-- 快照版本--> <spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-ollama-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <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> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> <!-- 快照版本--> <repositories> <repository> <id>spring-snapshot</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </repository> </repositories> </project>
3、編寫一個公共的調(diào)用組件
/** * 存入上下文信息,并調(diào)用接口進(jìn)行聊天 */ @Component public class Completion { @Resource private OllamaChatModel aiClient; /** * 最大消息記錄數(shù) */ private final static Integer MAX_SIZE = 10; /** * 消息記錄 */ private List<Message> messages = new ArrayList<>(); /** * 初始化存入系統(tǒng)消息 */ @PostConstruct private void addSystemMessage() { String message = "李白(701年2月28日—762年12月),字太白,號青蓮居士,出生于蜀郡綿州昌隆縣(今四川省綿陽市江油市青蓮鎮(zhèn)),一說出生于西域碎葉 ,祖籍隴西成紀(jì)(今甘肅省秦安縣)。唐朝偉大的浪漫主義詩人,涼武昭王李暠九世孫 。" + "為人爽朗大方,樂于交友,愛好飲酒作詩,名列“酒中八仙” 。曾經(jīng)得到唐玄宗李隆基賞識,擔(dān)任翰林供奉,賜金放還后,游歷全國,先后迎娶宰相許圉師、宗楚客的孫女。唐肅宗李亨即位后,卷入永王之亂,流放夜郎,輾轉(zhuǎn)到達(dá)當(dāng)涂縣令李陽冰家。上元二年,去世,時年六十二 。" + "著有《李太白集》,代表作有《望廬山瀑布》《行路難》《蜀道難》《將進(jìn)酒》《早發(fā)白帝城》《黃鶴樓送孟浩然之廣陵》等。李白所作詞賦,就其開創(chuàng)意義及藝術(shù)成就而言,享有極為崇高的地位,后世譽(yù)為“詩仙”,與詩圣杜甫并稱“李杜”。"; Message systemMessage = new SystemMessage(message); messages.add(systemMessage); } /** * 存儲用戶發(fā)送的消息 */ private void addUserMessage(String message) { Message userMessage = new UserMessage(message); messages.add(userMessage); } /** * 存儲AI回復(fù)的消息 */ private void addAssistantMessage(String message) { Message assistantMessage = new AssistantMessage(message); messages.add(assistantMessage); } /** * 聊天接口 */ public String chat(String message) { addUserMessage(message); String result = aiClient.call(new Prompt(messages)).getResult().getOutput().getContent(); addAssistantMessage(result); update(); return result; } /** * 流式聊天接口 */ public Flux<String> chatStream(String message) { addUserMessage(message); StringBuffer fullReply = new StringBuffer(); Flux<String> fluxResult = aiClient.stream(new Prompt(messages)) .flatMap(response -> { String reply = response.getResult().getOutput().getContent(); //拼接回復(fù)內(nèi)容 fullReply.append(reply); return Flux.just(reply); }) .doOnComplete(() -> { //監(jiān)聽流式響應(yīng)完成,完整回復(fù)存入消息記錄 System.out.println(fullReply); addAssistantMessage(String.valueOf(fullReply)); }); update(); return fluxResult; } /** * 更新消息記錄 */ private void update() { if (messages.size() > MAX_SIZE) { messages = messages.subList(messages.size() - MAX_SIZE, messages.size()); } } }
4、調(diào)用接口
@RestController @RequestMapping("/ollama") public class OllamaController { @Resource private OllamaChatModel ollamaChatModel; /** * 簡單調(diào)用 */ @PostMapping(value = "/ai/ask") public Object ask(String msg) { String called = ollamaChatModel.call(msg); System.out.println(called); return called; } /*** * 流式方式 */ @PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> stream(String msg) { return ollamaChatModel.stream(msg).flatMapSequential(Flux::just); } private final Completion completion; public OllamaController(Completion completion) { this.completion = completion; } /** * 分析上下文聊天 */ @PostMapping("/chat") public String chat(String message) { return completion.chat(message); } /** * 流式上下文 */ @PostMapping(value = "/chatStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> chatStream(@RequestBody String message) { return completion.chatStream(message); } }
5、測試調(diào)用
6、前端使用fetch處理流式數(shù)據(jù)
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Test Page</title> </head> <body> <input type="text" id="inputData"> <button onclick="sendRequest()">發(fā)送</button> <div id="output"></div> <script> const s = document.getElementById('output'); //獲取元素ID function sendRequest(msg) { const inputData = document.getElementById('inputData').value; s.innerText += (inputData + "\n"); // 發(fā)送 POST 請求 fetch('http://localhost:8088/ollama/chatStream', { method: "POST", body: JSON.stringify({ "message": inputData }), timeout: 0, dataType: "text/event-stream", headers: { "Content-Type": "application/json" }, }).then(response => { // 檢查響應(yīng)是否成功 if (!response.ok) { throw new Error('Network response was not ok'); } // 返回一個可讀流 return response.body; }).then(body => { const reader = body.getReader(); // 讀取數(shù)據(jù)流 function read() { return reader.read().then(({ done, value }) => { // 檢查是否讀取完畢 if (done) { console.log('已傳輸完畢'); s.innerText += "\n"; return; } // 處理每個數(shù)據(jù)塊 // console.log('收到的數(shù)據(jù):', value); let data = new TextDecoder().decode(value); //處理data:字樣,格式化流數(shù)據(jù) s.innerText += data.replace(/data:/g, "").replace(/\n/g, "");; // 繼續(xù)讀取下一個數(shù)據(jù)塊 read(); }); } // 開始讀取數(shù)據(jù)流 read(); }).catch(error => { console.error('Fetch error:', error); }); } </script> </body> </html>
到此這篇關(guān)于springAI結(jié)合ollama簡單實現(xiàn)小結(jié)的文章就介紹到這了,更多相關(guān)springAI結(jié)合ollama內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
jdk環(huán)境變量配置切換jdk版本及安裝jdk后環(huán)境變量不生效問題解決辦法
這篇文章主要介紹了jdk環(huán)境變量配置切換jdk版本及安裝jdk后環(huán)境變量不生效問題解決辦法,包括配置JAVA_HOME、Path和CLASSPATH,以及如何驗證配置是否成功,文章還講解了如何切換JDK版本,并解決了安裝新JDK后環(huán)境變量配置不生效的問題,需要的朋友可以參考下2024-12-12SpringMVC實現(xiàn)自定義類型轉(zhuǎn)換器
本篇文章主要介紹了SpringMVC實現(xiàn)自定義類型轉(zhuǎn)換器 ,詳細(xì)的介紹了自定義類型轉(zhuǎn)換器的用法和好處,有興趣的可以了解一下。2017-04-04Java實現(xiàn)斗地主與猜數(shù)字游戲詳細(xì)流程
這篇文章主要介紹了怎么用Java來寫斗地主種洗牌和發(fā)牌的功能,以及猜數(shù)字的游戲,斗地主相信大家都知道,同時也知道每一局都要洗牌打亂順序再發(fā)牌,本篇我們就來實現(xiàn)它們能,感興趣的朋友跟隨文章往下看看吧2022-04-04Java 中String StringBuilder 與 StringBuffer詳解及用法實例
這篇文章主要介紹了Java 中String StringBuilder 與 StringBuffer詳解及用法實例的相關(guān)資料,需要的朋友可以參考下2017-02-02