当前位置: 首页 > news >正文

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 {

    @Autowired
    private 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 {

    @Override
    public 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);
    }
}

相关文章:

  • 音乐游戏Dance Dance Revolution(DDR)模拟器
  • 【LLM】本地部署LLM大语言模型+可视化交互聊天,附常见本地部署硬件要求(以Ollama+OpenWebUI部署DeepSeekR1为例)
  • RAGS评测后的数据 如何利用influxdb和grafan 进行数据汇总查看
  • NetData部署与运行
  • Dify自定义工作流集成指南:对接阿里云百炼文生图API的实现方案
  • python算法-用递归打印数字3的幂--Day017
  • 详解cv::cvtColor
  • 【Python】Python判断语句经典题合集
  • C语言 第一章 (2)
  • 力扣47. 全排列 II
  • 文心一言AI创意画
  • 清华大学DeepSeek文档下载,清华大学deepseek下载(完成版下载)
  • RAG技术落地:核心痛点与应对策略全面解析
  • 自动驾驶两个传感器之间的坐标系转换
  • Anaconda 2025 最新版安装与Python环境配置指南(附官方下载链接)
  • 二、大模型微调技术栈全解析
  • go基础语法
  • 【论文学习】DeepSeek-V3 总结
  • 002简单MaterialApp主题和Scaffold脚手架
  • 要实现将JSON格式数据动态生成思维导图图片,可以使用`pygraphviz`库结合`json`解析。以下是完整实现代码:
  • 淮安做网站的公司/韩国seocaso
  • 网站后台编辑/如何优化关键词搜索排名
  • 服务器方面如何规划建设网站/最新的军事新闻
  • 深圳十大甲级装饰公司/寻找郑州网站优化公司
  • 想开一家网店/品牌推广百度seo
  • 西安 企业网站建设/网站搜索排优化怎么做