deepseek sse流式輸出

鏈接

semi-ui-vue聊天組件 - 可以用這個組件優化界面

sse服務端消息推送

webflux&webclient

Hi-Dream-Blog - 參考這個博客,可以在后臺將markdown語法轉為html

文章目錄

  • 鏈接
  • 效果
  • 代碼
    • pom.xml
    • DeepSeekController
    • WebConfig
    • DeepSeekClient
    • AiChatRequest
    • AiChatMessage
    • SseApp

效果

在這里插入圖片描述
在這里插入圖片描述

代碼

pom.xml

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring-boot-dependencies</artifactId><groupId>org.springframework.boot</groupId><version>2.1.8.RELEASE</version></parent><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>demo-sse</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.10</version></dependency></dependencies></project>

DeepSeekController

@RestController
@RequestMapping("/deepseek")
public class DeepSeekController {@Autowiredprivate DeepSeekClient deepSeekClient;@RequestMapping(value = "chatCompletions", produces = "text/event-stream;charset=utf-8")public Flux<String> chatCompletions(@RequestParam(required = true, value = "content") String content) {return deepSeekClient.chatCompletions(content);}@RequestMapping(value = "chatCompletions2", produces = "text/event-stream;charset=utf-8")public SseEmitter chatCompletions2(@RequestParam(required = true, value = "content2") String content2) {return deepSeekClient.chatCompletions2(content2);}}

WebConfig

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").maxAge(3600).allowCredentials(true).allowedOrigins("*").allowedMethods("*").allowedHeaders("*").exposedHeaders("token", "Authorization");}}

DeepSeekClient

package com.zzhua.service;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zzhua.pojo.AiChatMessage;
import com.zzhua.pojo.AiChatRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;import java.io.IOException;
import java.util.Arrays;@Slf4j
@Component
public class DeepSeekClient {private static final ObjectMapper mapper = new ObjectMapper();public Flux<String> chatCompletions(String content) {AiChatMessage chatMsg1 = new AiChatMessage("system", "You are a helpful assistant.");AiChatMessage chatMsg2 = new AiChatMessage("user", content);AiChatRequest request = new AiChatRequest();request.setModel("deepseek-chat");request.setMessages(Arrays.asList(chatMsg1, chatMsg2));// 流式輸出request.setStream(true);return WebClient.builder().baseUrl("https://api.deepseek.com").defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).defaultHeader("Authorization", "Bearer sk-xxx").build().post().uri("/chat/completions").body(BodyInserters.fromObject(request)).retrieve().bodyToFlux(String.class).flatMap(this::handleResult);}private Flux<String> handleResult(String result) {if ("[DONE]".equals(result)) {return Flux.empty();} else {try {JsonNode jsonNode = mapper.readTree(result);String content = jsonNode.get("choices").get(0).get("delta").get("content").asText();System.out.println(content);return Flux.just(content);} catch (Exception e) {log.error("解析失敗: {}", result);}}return Flux.empty();}public SseEmitter chatCompletions2(String content2) {SseEmitter sseEmitter = new SseEmitter();AiChatMessage chatMsg1 = new AiChatMessage("system", "You are a helpful assistant.");AiChatMessage chatMsg2 = new AiChatMessage("user", content2);AiChatRequest request = new AiChatRequest();request.setModel("deepseek-chat");request.setMessages(Arrays.asList(chatMsg1, chatMsg2));// 流式輸出request.setStream(true);WebClient.builder().baseUrl("https://api.deepseek.com").defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).defaultHeader("Authorization", "Bearer sk-xxx").build().post().uri("/chat/completions").body(BodyInserters.fromObject(request)).retrieve().bodyToFlux(String.class).flatMap(this::handleResult).doOnComplete(()->{sseEmitter.complete();log.warn("結束");}).subscribe(data->{try {sseEmitter.send(SseEmitter.event().data(data));} catch (IOException e) {e.printStackTrace();}});return sseEmitter;}public static void main(String[] args) throws IOException {RestTemplate restTemplate = new RestTemplate();ObjectMapper mapper = new ObjectMapper();AiChatMessage chatMsg1 = new AiChatMessage("system", "You are a helpful assistant.");AiChatMessage chatMsg2 = new AiChatMessage("user", "");AiChatRequest request = new AiChatRequest();request.setModel("deepseek-chat");request.setMessages(Arrays.asList(chatMsg1, chatMsg2));request.setStream(false);HttpHeaders headers = new HttpHeaders();headers.add("Content-Type", "application/json");headers.add("Authorization", "Bearer sk-xxx");HttpEntity<AiChatRequest> requestEntity = new HttpEntity<>(request, headers);String response = restTemplate.exchange("https://api.deepseek.com/chat/completions",HttpMethod.POST,requestEntity,String.class).getBody();System.out.println(response);System.out.println(mapper.readTree(response).get("choices").get(0).get("message").get("content"));}
}

AiChatRequest

@Data
public class AiChatRequest {private String model;private List<AiChatMessage> messages;private boolean stream;}

AiChatMessage

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AiChatMessage {private String role;private String content;
}

SseApp

@SpringBootApplication
public class SseApp {public static void main(String[] args) {SpringApplication.run(SseApp.class, args);}
}

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

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

相關文章

Linux時間日期類指令

1、data指令 基本語法&#xff1a; date &#xff1a; 顯示當前時間date %Y : 顯示當前年份date %m &#xff1a; 顯示當前月份date %d &#xff1a; 顯示當前哪一天date “%Y-%m-%d %H:%M:%S" &#xff1a; 顯示年月日時分秒date -s 字符串時間 &#xff1a; 設置系統時…

SQLMesh 系列教程9- 宏變量及內置宏變量

SQLMesh 的宏變量是一個強大的工具&#xff0c;能夠顯著提高 SQL 模型的動態化能力和可維護性。通過合理使用宏變量&#xff0c;可以實現動態時間范圍、多環境配置、參數化查詢等功能&#xff0c;從而簡化數據模型的開發和維護流程。隨著數據團隊的規模擴大和業務復雜度的增加&…

鵬哥c語言數組(初階數組)

前言&#xff1a; 對應c語言視頻54集 內容&#xff1a; 一維數組的創建 數組是一組相同元素的集合&#xff0c; 數組的創建方式 type_t就是數組的元素類型&#xff0c;const_n是一個常量表達式&#xff0c;用來指定數組的大小 c99標準之前的&#xff0c;數組的大小必須是…

爬蟲運行后如何保存數據?

爬蟲運行后&#xff0c;將獲取到的數據保存到本地或數據庫中是常見的需求。Python 提供了多種方式來保存數據&#xff0c;包括保存為文本文件、CSV 文件、JSON 文件&#xff0c;甚至存儲到數據庫中。以下是幾種常見的數據保存方法&#xff0c;以及對應的代碼示例。 1. 保存為文…

計算機視覺:經典數據格式(VOC、YOLO、COCO)解析與轉換(附代碼)

第一章&#xff1a;計算機視覺中圖像的基礎認知 第二章&#xff1a;計算機視覺&#xff1a;卷積神經網絡(CNN)基本概念(一) 第三章&#xff1a;計算機視覺&#xff1a;卷積神經網絡(CNN)基本概念(二) 第四章&#xff1a;搭建一個經典的LeNet5神經網絡(附代碼) 第五章&#xff1…

linux--多進程基礎(2)GDB多進程調試(面試會問)

將其中的命令記住就行。 總結&#xff1a;GDB下默認調試父進程&#xff0c;可以設置調試父進程還是子進程&#xff0c;也可以設置調試模式&#xff0c;調試模式默認是on即一個在調試另一個直接運行&#xff0c;off就是另一個進程掛起&#xff0c;最后可以查看調試進程 一般默認…

Cramér-Rao界:參數估計精度的“理論底線”

Cramr-Rao界&#xff1a;參數估計精度的“理論底線” 在統計學中&#xff0c;當我們用數據估計一個模型的參數時&#xff0c;總希望估計結果盡可能精確。但精度有沒有一個理論上的“底線”呢&#xff1f;答案是有的&#xff0c;這就是Cramr-Rao界&#xff08;Cramr-Rao Lower …

【復習】Redis

數據結構 Redis常見的數據結構 String&#xff1a;緩存對象Hash&#xff1a;緩存對象、購物車List&#xff1a;消息隊列Set&#xff1a;點贊、共同關注ZSet&#xff1a;排序 Zset底層&#xff1f; Zset底層的數據結構是由壓縮鏈表或跳表實現的 如果有序集合的元素 < 12…

Git add --- error: Filename too long

0 Preface/Foreword 1 解決辦法 git config --system core.longpaths true

在 Spring Boot 中使用 `@Autowired` 和 `@Bean` 注解

文章目錄 在 Spring Boot 中使用 Autowired 和 Bean 注解示例背景 1. 定義 Student 類2. 配置類&#xff1a;初始化 Bean3. 測試類&#xff1a;使用 Autowired 注解自動注入 Bean4. Spring Boot 的自動裝配5. 總結 在 Spring Boot 中使用 Autowired 和 Bean 注解 在 Spring Bo…

【AI+智造】DeepSeek價值重構:當采購與物控遇上數字化轉型的化學反應

作者&#xff1a;Odoo技術開發/資深信息化負責人 日期&#xff1a;2025年2月24日 引言&#xff1a;從事企業信息化工作16年&#xff0c;我見證過無數企業從手工臺賬到ERP系統的跨越。但真正讓采購和物控部門脫胎換骨的&#xff0c;是融合了Deepseek AI的Odoo數字化解決方案——…

qt-C++筆記之創建和初始化 `QGraphicsScene` 和 `QGraphicsView` 并關聯視圖和場景的方法

qt-C++筆記之創建和初始化 QGraphicsScene 和 QGraphicsView 并關聯視圖和場景的方法 code review! 參考筆記 1.qt-C++筆記之創建和初始化 QGraphicsScene 和 QGraphicsView 并關聯視圖和場景的方法 2.qt-C++筆記之QGraphicsScene和 QGraphicsView中setScene、通過scene得到vie…

Java Map實現類面試題

Java Map實現類面試題 HashMap Q1: HashMap的實現原理是什么&#xff1f; HashMap基于哈希表實現&#xff0c;使用數組鏈表紅黑樹&#xff08;Java 8&#xff09;的數據結構。 public class HashMapPrincipleExample {// 模擬HashMap的基本結構public class SimpleHashMap&…

Win32/ C++ 簡易對話框封裝框架(多語言, 通知欄菜單, 拖拽文件處理)

Win32 簡易對話框封裝簡易框架示例 1. 菜單操作: 多語言 2. 通知欄圖標菜單 3. 其他操作: 接受拖拽文件等等 CDialogFrame.h #pragma once #include "CWindow/CDialogBase.h" #include "CNSFHeader.h" #include "Win32Utils/CBytesUtils.h" …

如何在WordPress網站中查看移動版本—快速預覽與自定義設置

在WordPress網站的構建過程中&#xff0c;確保網站在移動端的顯示效果至關重要。畢竟&#xff0c;隨著越來越多的用戶通過手機訪問互聯網&#xff0c;一個優化良好的移動版網站將直接影響用戶的留存率和訪問體驗。 如果你是WordPress網站的所有者&#xff0c;本文將向你介紹如…

課程1. 深度學習簡介

課程1. 深度學習簡介 神經網絡結構邏輯回歸XOR問題&#xff08;異或問題&#xff09; 中間特征的生成全連接神經網絡中間網絡層的激活函數Sigmoid函數Tanh函數ReLU函數其它激活函數 使用全連接神經網絡解決 XOR 問題神經網絡用于回歸問題訓練神經網絡 不同類型的神經網絡 附加材…

Vue.js Vue 測試工具:Vue Test Utils 與 Jest

Vue.js Vue 測試工具&#xff1a;Vue Test Utils 與 Jest 在 Vue.js 的開發過程中&#xff0c;編寫和執行測試是確保應用質量和穩定性的關鍵步驟。Vue Test Utils 和 Jest 是 Vue.js 官方推薦的測試工具&#xff0c;二者結合使用&#xff0c;可以高效地進行單元測試和集成測試…

數據結構 1-2 線性表的鏈式存儲-鏈表

1 原理 順序表的缺點&#xff1a; 插入和刪除移動大量元素數組的大小不好控制占用一大段連續的存儲空間&#xff0c;造成很多碎片 鏈表規避了上述順序表缺點 邏輯上相鄰的兩個元素在物理位置上不相鄰 頭結點 L&#xff1a;頭指針 頭指針&#xff1a;鏈表中第一個結點的存儲…

各種以太坊Rollup技術

以太坊Rollup技術是一種通過將大量交易批處理并在主鏈上記錄較小的數據摘要來擴展以太坊網絡的方法。Rollup技術主要分為兩種類型&#xff1a;樂觀Rollup&#xff08;Optimistic Rollup&#xff09;和零知識Rollup&#xff08;ZK-Rollup&#xff09;。下面詳細介紹這兩種技術及…

Kubernetes開發環境minikube | 開發部署MySQL單節點應用

minikube是一個主要用于開發與測試Kubernetes應用的運行環境 本文主要描述在minikube運行環境中部署MySQL單節點應用 minikube start --force kubectl get nodes 如上所示&#xff0c;啟動minikube單節點運行環境 minikube ssh docker pull 如上所示&#xff0c;從MySQL官…