LangChain4j(2):整合SpringBoot

1 新建Springboot項目

1.1 引入依賴

<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 http://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.4.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>org.example</groupId><artifactId>langchain4jSpringbootpro</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>langchain4jSpringbootpro</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><langchain4j.version>1.0.0-beta1</langchain4j.version></properties><dependencies><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId></dependency><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><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-bom</artifactId><version>${langchain4j.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement></project>

2 配置項

查看加載的依賴中的langchain4j-community-dashscope-spring-boot-starter的Autoconfig文件。

可以看到使用時需要的配置條件,需要配置apikey。

在源文件中可以查看配置模型:

新建配置application.properties

server.port=8080langchain4j.community.dashscope.chat-model.api-key = 你的apikey
langchain4j.community.dashscope.chat-model.model-name = qwen-plus

2.3 代碼實現

package org.example.controller;import dev.langchain4j.community.model.dashscope.QwenChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/ai")
public class AiController {@AutowiredQwenChatModel qwenChatModel;@RequestMapping("/chat")public String test(@RequestParam(defaultValue = "你是誰") String message){String chat = qwenChatModel.chat(message);return chat;}}

2.4 訪問結果

啟動后,訪問鏈接http://localhost:8080/ai/chat。

2 接入DeepSeek

接入DeepSeek只需要修改配置文件即可,如下:

langchain4j.community.dashscope.chat-model.api-key = 你的key
langchain4j.community.dashscope.chat-model.model-name = deepseek-r1

啟動后,訪問鏈接http://localhost:8080/ai/chat。

3 接入Ollama

安裝Ollama,下載想要的大模型。

引用依賴:

    <dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-ollama-spring-boot-starter</artifactId><version>${langchain4j.version}</version></dependency>

加入配置文件:

langchain4j.ollama.chat-model.base-url = http://localhost:11434
langchain4j.ollama.chat-model.model-name = deepseek-r1:1.5b

代碼如下:

package org.example.controller;import dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.ollama.OllamaChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/ai")
public class AiController {@AutowiredChatLanguageModel chatLanguageModel;@RequestMapping("/ollamachat")public String ollamachatfuc(@RequestParam(defaultValue = "你是誰") String message){String ollamachat = chatLanguageModel.chat(message);return ollamachat;}}

結果如下:

4 流式輸出

之前的依賴不變,但是因為langchain4j不是spring家族,所以我們在wen應用中需要引入webflux。

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>

通過Flux進行流式響應

    @RequestMapping(value = "/streamchat",produces = "text/stream;charset=UTF-8")public Flux<String> streamchatfuc(@RequestParam(defaultValue="你是誰") String message){Flux<String> flux = Flux.create(fluxSink -> {streamingChatModel.chat(message, new StreamingChatResponseHandler() {@Overridepublic void onPartialResponse(String partialResponse) {fluxSink.next(partialResponse);}@Overridepublic void onCompleteResponse(ChatResponse completeResponse) {fluxSink.complete();}@Overridepublic void onError(Throwable error) {fluxSink.error(error);}});});return flux;}

加入配置文件:

langchain4j.community.dashscope.streaming-chat-model.api-key = sk-4d1748fba8994a2e94cb0fbaf3d34f23
langchain4j.community.dashscope.chat-model.model-name = deepseek-r1

啟動后訪問鏈接:http://localhost:8080/ai/streamchat,會發現答復是按照流式輸出的。

5 記憶對話

5.1 ChatMemory

大模型并不會把我們每次的對話存在服務端,所以他記不住我們說的話,如下代碼:

    @Testpublic void test_bad(){ChatLanguageModel model = OpenAiChatModel.builder().apiKey("demo").modelName("gpt-4o-mini").build();System.out.println(model.chat("你好,我是徐庶老師"));System.out.println("----");System.out.println(model.chat("我叫什么"));}

運行結果如下:

所以每次對話都需要將之前的對話記錄,都發給大模型,這樣才能知道我們之前說了什么:

    @Testpublic void test03(){ChatLanguageModel model = OpenAiChatModel.builder().apiKey("demo").modelName("gpt-4o-mini").build();UserMessage userMessage1 = UserMessage.userMessage("你好,我是徐庶");ChatResponse response1 = model.chat(userMessage1);AiMessage aiMessage1 = response1.aiMessage();//大模型的第一次響應System.out.println(aiMessage1.text());System.out.println("----");// 下面一行代碼是重點ChatResponse response2 = model.chat(userMessage1,aiMessage1, UserMessage.userMessage("我叫什么?"));AiMessage aiMessage2 = response2.aiMessage();// 大模型的第二次響應System.out.println(aiMessage2.text());System.out.println(model.chat("你好,我是徐庶老師"));System.out.println("----");System.out.println(model.chat("我叫什么"));}

返回結果如下:

但是如果要我們每次把之前的記錄自己去維護,未免太麻煩,所以提供了ChatMemory但是他這個ChatMemory沒有SpringAi好用、易用、十分麻煩!所以說誰在跟我說Langchain4i比SpringAi好我跟誰急!

package org.example.config;import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.TokenStream;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class Aiconfig {public interface Assistant{String chat(String message);// 流式響應TokenStream stream(String message);}@Beanpublic Assistant assistant(ChatLanguageModel qwenchatModel, StreamingChatLanguageModel qwenstreamingchatModel) {//設置最大記錄對話數ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);Assistant assistant = AiServices.builder(Assistant.class).chatLanguageModel(qwenchatModel).streamingChatLanguageModel(qwenstreamingchatModel).chatMemory(chatMemory).build();return assistant;}
}

原理:

  1. 通過AiService創建的代理對象(Aiservices.builder(XushuChatModel.class))調用chat方法(XushuChatModel.chat)
  2. 代理對象會去ChatMemory中獲取之前的對話記錄(獲取記憶)
  3. 將獲取到的對話記錄合并到當前對話中(此時大模型根據之前的聊天記錄肯定就擁有了“記憶”)
  4. 將當前的對話內容存入ChatMemory(保存記憶)

代碼如下:

package org.example.controller;import dev.langchain4j.service.TokenStream;
import jakarta.servlet.http.HttpServletResponse;
import org.example.config.Aiconfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.time.LocalDate;@RestController
@RequestMapping("/ai_other")
public class OtherAiController {@AutowiredAiconfig.Assistant assistant;//告訴模型我叫諸葛懿@RequestMapping(value = "/memory_chat")public String memorychat(@RequestParam(defaultValue = "我叫諸葛懿") String message) {return assistant.chat(message);}//流式響應@RequestMapping(value = "/memory_stream_chat",produces ="text/stream;charset=UTF-8")public Flux<String> memoryStreamChat(@RequestParam(defaultValue="我是誰") String message, HttpServletResponse response) {TokenStream stream = assistant.stream(message);return Flux.create(sink -> {stream.onPartialResponse(s -> sink.next(s)).onCompleteResponse(c -> sink.complete()).onError(sink::error).start();});}
}

先訪問http://localhost:8080/ai_other/memory_chat告訴模型你的名字,后訪問http://localhost:8080/ai_other/memory_stream_chat看結果,結果如下:

5.2 記憶分離

現在我們再來想另一種情況:如果不同的用戶或者不同的對話肯定不能用同一個記憶,要不然對話肯定會混淆此時就需要進行區分:

可以通過memoryld進行區分

5.3 持久對話

6 Funcion-call

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

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

相關文章

移動端六大語言速記:第2部分 - 控制結構

移動端六大語言速記&#xff1a;第2部分 - 控制結構 本文繼續對比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift這六種移動端開發語言的控制結構&#xff0c;幫助開發者快速掌握各語言的語法差異。 2. 控制結構 2.1 條件語句 各語言條件語句的語法對比&#xff1a; …

Linux-線程概念與線程控制的常用操作

一.Linux線程概念 1-1.線程是什么 在Linux中&#xff0c;線程是基于Linux原有的進程實現的。本質是輕量級進程(LWP)。在?個程序?的?個執?路線就叫做線程&#xff08;thread&#xff09;。更準確的定義是&#xff1a;線程是“?個進程內部的控制序列”。 我們之前所學習的進…

dfs記憶化搜索刷題 + 總結

文章目錄 記憶化搜索 vs 動態規劃斐波那契數題解代碼 不同路徑題解代碼 最長遞增子序列題解代碼 猜數字大小II題解代碼 矩陣中的最長遞增路徑題解代碼 總結 記憶化搜索 vs 動態規劃 1. 記憶化搜索&#xff1a;有完全相同的問題/數據保存起來&#xff0c;帶有備忘錄的遞歸 2.記憶…

【HTML】驗證與調試工具

個人主頁&#xff1a;Guiat 歸屬專欄&#xff1a;HTML CSS JavaScript 文章目錄 1. HTML 驗證工具概述1.1 驗證的重要性1.2 常見 HTML 錯誤類型 2. W3C 驗證服務2.1 W3C Markup Validation Service2.2 使用 W3C 驗證器2.3 驗證結果解讀 3. 瀏覽器開發者工具3.1 Chrome DevTools…

認識rand, srand, time函數,生成隨機數

要完成猜數字游戲&#xff0c;首先要生成隨機數&#xff0c;那么該怎么生成隨機數&#xff1f;、 1.rand函數 rand函數是庫函數&#xff0c;使用的時候要使用頭文件stdlib.h c語言中&#xff0c;提供了rand函數來生成隨機數&#xff0c;來看一下函數使用&#xff1a; 但是r…

BKA-CNN-GRU、CNN-GRU、GRU、CNN四模型多變量時序預測(Matlab)

BKA-CNN-GRU、CNN-GRU、GRU、CNN四模型多變量時序預測&#xff08;Matlab&#xff09; 目錄 BKA-CNN-GRU、CNN-GRU、GRU、CNN四模型多變量時序預測&#xff08;Matlab&#xff09;預測效果基本介紹程序設計參考資料 預測效果 基本介紹 BKA-CNN-GRU、CNN-GRU、GRU、CNN四模型多…

Go語言從零構建SQL數據庫引擎(2)

SQL標準與數據庫系統實現差異 在上一節中&#xff0c;我們了解了關系型數據庫的基礎概念。現在&#xff0c;讓我們深入探討SQL語言標準以及不同數據庫系統之間的實現差異。 SQL語言的誕生與演進 想象你經營的咖啡店生意蒸蒸日上&#xff0c;需要一個更強大的系統來管理數據。…

智能導診系統的技術體系組成

智能導診系統的技術體系由基礎支撐技術、核心交互技術、應用場景技術及安全保障技術構成&#xff0c;具體可歸納為以下六個維度&#xff1a; 一、基礎支撐技術 1、AI大模型與深度學習 醫療大模型&#xff1a;如騰訊醫療AI、DeepSeek等&#xff0c;通過海量醫學文獻和病例訓…

QML輸入控件: TextField(文本框)的樣式定制

目錄 引言示例簡介示例代碼與關鍵點示例1&#xff1a;基礎樣式定制示例2&#xff1a;添加圖標示例3&#xff1a;交互式元素&#xff08;清除按鈕&#xff09; 實現要點總結完整工程下載 引言 在Qt Quick應用程序開發中&#xff0c;文本輸入是最常見的用戶交互方式之一。TextFi…

leetcode hot100 多維動態規劃

1??2?? 多維動態規劃&#xff08;區間 DP、狀態機 DP&#xff09; 62. 不同路徑 一個機器人位于一個 m x n 網格的左上角 &#xff08;起始點在下圖中標記為 “Start” &#xff09;。機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角&#xff08;在下圖…

3.27學習總結 爬蟲+二維數組+Object類常用方法

高精度&#xff1a; 一個很大的整數&#xff0c;以字符串的形式進行接收&#xff0c;并將每一位數存儲在數組內&#xff0c;例如100&#xff0c;即存儲為[1][0][0]。 p2437蜜蜂路線 每一個的路線數前兩個數的路線數相加。 #include <stdio.h> int a[1005][1005]; int …

車載以太網網絡測試-26【SOME/IP-通信方式-2】

目錄 1 摘要2 Method &#xff08;FF/RR&#xff09;、Event、Filed介紹2.1. SOME/IP Method 接口2.1.1 **Fire & Forget (FF)** - 單向調用2.1.2 **Request/Response (RR)** - 請求/響應模式2.1.3 **車載ECU通信實現示例**:2.1.4 **通信序列示例**2.1.5 實現注意事項 2.2 …

把doi直接插入word中,然后直接生成參考文獻

這段代碼通過提取、查詢、替換DOI&#xff0c;生成參考文獻列表來處理Word文檔&#xff0c;可按功能模塊劃分&#xff1a; 導入模塊 import re from docx import Document from docx.oxml.ns import qn from habanero import Crossref導入正則表達式模塊re用于文本模式匹配&a…

[C++] : C++11 右值引用的理解

&#xff08;一&#xff09;什么是左值和右值&#xff1f; 傳統的C語法中就有引用的語法&#xff0c;而C11中新增了的右值引用語法特性&#xff0c;所以從現在開始我們 之前學習的引用就叫做左值引用。無論左值引用還是右值引用&#xff0c;都是給對象取別名。 1.左值 左值是一…

windows服務器切換到linux服務器踩坑點

單節點環境依賴性 單節點問題&#xff0c;影響業務可用性&#xff0c;windows影響后續自動化&#xff0c;健壯性的提升&#xff0c;需要進行linux化 每個服務至少是雙節點&#xff0c;防止單點故障&#xff0c;提升系統的可用性&#xff0c;健壯性。linux化后可以進行docker化…

美顏SDK兼容性挑戰:如何讓美顏濾鏡API適配iOS與安卓?

如何讓美顏濾鏡API同時適配iOS與Android&#xff0c;并確保性能流暢、效果一致&#xff0c;是開發者面臨的一大挑戰。今天&#xff0c;我將與大家一同深度剖析美顏SDK的跨平臺兼容性問題&#xff0c;并分享優化適配方案。 一、美顏SDK兼容性面臨的挑戰 1.1不同平臺的圖像處理框…

Vue3 表單

Vue3 表單 隨著前端技術的發展,Vue.js 作為一款流行的前端框架,不斷更新迭代,以適應更高效、更便捷的開發需求。Vue3 作為 Vue.js 的第三個主要版本,引入了許多新特性和改進,其中包括對表單處理機制的優化。本文將深入探討 Vue3 表單的使用方法、技巧以及注意事項。 1. …

筆記:代碼隨想錄算法訓練營day62:108.冗余連接、109.冗余連接II

學習資料&#xff1a;代碼隨想錄 108. 冗余連接 卡碼網題目鏈接&#xff08;ACM模式&#xff09; 判斷是否有環的依據為&#xff0c;利用并查集&#xff0c;isSame函數&#xff0c;判斷當下這條邊的兩個節點入集前是否為同根&#xff0c;如果是的話&#xff0c;該邊就是會構…

RK3588,V4l2 讀取Gmsl相機, Rga yuv422轉換rgb (mmap)

RK3588, 使用V4l2 讀取 gmsl 相機,獲得yuv422格式圖像, 使用 rga 轉換 rgb 圖像。減少cpu占用率. 內存管理方式采用 mmap… 查看相機信息 v4l2-ctl --all -d /dev/cam0 , 查看自己相機分辨率,輸出格式等信息,對應修改后續代碼測試… Driver Info:Driver name : rkcif…

Kubernetes》k8s》Containerd 、ctr 、cri、crictl

containerd ctr crictl ctr 是 containerd 的一個客戶端工具。 crictl 是 CRI 兼容的容器運行時命令行接口&#xff0c;可以使用它來檢查和調試 k8s 節點上的容器運行時和應用程序。 ctr -v 輸出的是 containerd 的版本&#xff0c; crictl -v 輸出的是當前 k8s 的版本&#x…