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

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);
    }
}

http://www.kler.cn/a/561646.html

相关文章:

  • 大数据模式下可以同步视图的数据到大数据存储中吗?
  • 【Tourism】Hezhou(1)
  • Java Web开发实战与项目——Spring Boot与Spring Cloud微服务项目实战
  • 总结递推与递归的区别
  • WPS计算机二级•文档的页面设置与打印
  • 实现使用RBF(径向基函数)神经网络模拟二阶电机数学模型中的非线性干扰,以及使用WNN(小波神经网络)预测模型中的非线性函数来抵消迟滞影响的功能
  • IDEA配置JSP环境
  • 特征工程 (Feature Enginering)基础知识1
  • LeetCode 热题100 15. 三数之和
  • 全面屏手势导航栏适配
  • ‌XPath vs CSS Selector 深度对比
  • 学习Flask:Day 2:模板与表单开发
  • Grafana使用日志5--如何重置Grafana密码
  • Java包装类性能优化:深入解析Integer享元模式的源码实现
  • SSL/TLS 协议、SSL证书 和 SSH协议 的区别和联系
  • 冯诺依曼体系结构和操作系统
  • 批量将手机照片修改为一寸白底证件照的方法
  • Python Cookbook-2.12 将二进制数据发送到 Windows 的标准输出
  • Jmeter插件下载及安装
  • 第4章 4.4 EF Core数据库迁移 Add-Migration UpDate-Database