SpringBoot或SpringAI对接DeekSeek大模型

今日除夕夜,deepseek可是出尽了风头,但是我看网上还没有这方面的内容对接,官网也并没有,故而本次对接是为了完成这个空缺

我看很多的博客内容是流式请求虽然返回时正常的,但是他并不是实时返回,而是全部响应结束之后返回,是有问题的,我这里的这个方法弥补了这个缺陷

下一次我应该会开源一个Starter,让大家使用起来更加方便,下一次直接开源出来,供大家参考,应该就在这一两天,可以期待一下

这里需要仔细看一下了

因为我使用的是JDK21,不过你也可以使用JDK8去做这件事情,但是前提fastjson和okHttp的版本,因为有些方法可能不是很兼容,如果想要完成可能有一些方法需要替换一下,但是肯定是可以用的

文章目录

  • 前言
  • 目录

    文章目录

    一、DeepSeek是什么?

    二、使用步骤

    1.引入库

    2.配置环境变量

     3.配置

    三、 请求

    1.流式请求

     2.非流失请求

    1.定义类

     2.非流式请求

     四、返回结果

    1.流式结果

     2.非流式请求

    总结



一、DeepSeek是什么?

我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-V3。

  • 开发者:深度求索(DeepSeek),一家专注于实现AGI(通用人工智能)的中国科技公司。

  • 技术架构:基于大规模语言模型(LLM),通过深度学习技术训练,具备自然语言理解、生成和推理能力。

  • 数据来源:训练数据涵盖多领域公开文本(如书籍、网页、学术论文等),经过严格清洗和过滤,符合伦理与安全规范。

二、使用步骤

1.引入库

代码如下(示例):

        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.66</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.12.0</version>
        </dependency>

2.配置环境变量

spring:
  ai:
    deepseek:
      api-key: 这里填写自己的APIKey
      api-host: https://api.deepseek.com/chat/completions

 3.配置

package com.hhh.springai_test.config;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ChatConfig {


    @Value("${spring.ai.deepseek.api-key}")
    private String DeepSeekConfigUrl;

    @Value("${spring.ai.deepseek.api-host}")
    private String DeepSeekConfigHost;


    public String getDeepSeekConfigUrl() {
        return DeepSeekConfigUrl;
    }

    public String getDeepSeekConfigHost() {
        return DeepSeekConfigHost;
    }

}

三、 请求

1.流式请求

@Resource
private ChatConfig config;

@GetMapping(value = "/ai/generateStreamAsString2", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> generateStreamAsString2(@RequestParam(value = "message") String message) throws Exception {
        // 初始化 OkHttpClient
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        // 创建动态请求体,使用流式传输
        RequestBody body = new RequestBody() {
            @Override
            public okhttp3.MediaType contentType() {
                return okhttp3.MediaType.parse("application/json");
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                // 构建请求体 JSON 数据
                String requestBodyJson = "{\n" +
                        "  \"messages\": [\n" +
                        "    {\n" +
                        "      \"content\": \"" + message + "\",\n" +  // 动态插入用户消息
                        "      \"role\": \"user\"\n" +
                        "    }\n" +
                        "  ],\n" +
                        "  \"model\": \"deepseek-chat\",\n" +
                        "  \"frequency_penalty\": 0,\n" +
                        "  \"max_tokens\": 1024,\n" +
                        "  \"presence_penalty\": 0,\n" +
                        "  \"response_format\": {\n" +
                        "    \"type\": \"text\"\n" +
                        "  },\n" +
                        "  \"stop\": null,\n" +
                        "  \"stream\": true,\n" +
                        "  \"stream_options\": null,\n" +
                        "  \"temperature\": 1,\n" +
                        "  \"top_p\": 1,\n" +
                        "  \"tools\": null,\n" +
                        "  \"tool_choice\": \"none\",\n" +
                        "  \"logprobs\": false,\n" +
                        "  \"top_logprobs\": null\n" +
                        "}";
                // 写入请求体数据
                sink.writeUtf8(requestBodyJson);
            }
        };
        // 创建 Headers
        Headers headers = new Headers.Builder()
                .add("Content-Type", "application/json")
                .add("Accept", "application/json")
                .add("Authorization", "Bearer " + config.getDeepSeekConfigUrl())  // 使用您的 API 密钥
                .build();
        // 创建 HttpUrl
        HttpUrl url = HttpUrl.parse(config.getDeepSeekConfigHost()); // 使用您的 API URL
        if (url == null) {
            throw new IllegalArgumentException("您此时未携带URL参数");
        }
        // 构造 Request
        okhttp3.Request request = new okhttp3.Request.Builder()
                .url(url)
                .post(body)  // 使用流式请求体
                .headers(headers)
                .build();
        // 执行请求并返回 Flux 流
        return Flux.create(sink -> {
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    // 异常发生时调用 sink.error()
                    sink.error(e);
                }
                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    ResponseBody responseBody = response.body();
                    BufferedSource source = responseBody.source();
                    while (true) {
                        // 逐行读取响应数据
                        String line = source.readUtf8Line();
                        if (line == null) {
                            break;
                        } else if (line.startsWith("data:")) {
                            String data = line.substring(5).trim();
                            // 检查数据是否为结束信号"[DONE]"
                            if (!"[DONE]".equals(data)) {
                                // 解析接收到的数据为JSON对象
                                JSONObject jsonResponse = new JSONObject(data);
                                String finishReason = jsonResponse.getJSONArray("choices").getJSONObject(0).optString("finish_reason");
                                if ("stop".equals(finishReason)) {
                                    // 结束时推送数据并完成
                                    sink.next(data);
                                    sink.complete();
                                    break;
                                } else {
                                    // 否则继续推送数据
                                    sink.next(data);
                                }
                                // 打印调试信息
                                System.out.println(jsonResponse.getJSONArray("choices"));
                            }
                        }
                    }
                }
            });
        });
    }

 2.非流失请求

1.定义类

package com.hhh.springai_test.model.dto.DeepSeekChat;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatCompletionResponse {

    private String id;
    private String object;
    private long created;
    private String model;
    private List<Choice> choices;
    private Usage usage;
    private String system_fingerprint;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Choice {
        private int index;
        private Message message;
        private Object logprobs;
        private String finish_reason;
    }

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

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Usage {
        private int prompt_tokens;
        private int completion_tokens;
        private int total_tokens;
        private PromptTokensDetails prompt_tokens_details;
        private int prompt_cache_hit_tokens;
        private int prompt_cache_miss_tokens;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class PromptTokensDetails {
        private int cached_tokens;
    }
}

 2.非流式请求

//引入这个bean
@Resource
private ChatConfig config;

 
   @GetMapping(value = "/ai/generateAsString3")
    public ChatCompletionResponse generateStreamAsString3(@RequestParam(value = "message") String message) {
        // 初始化 OkHttpClient
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, "{\n" +
                "  \"messages\": [\n" +
                "    {\n" +
                "      \"content\": \"" + "请介绍一下你自己" + "\",\n" +  // 动态插入用户消息
                "      \"role\": \"user\"\n" +
                "    },\n" +
                "    {\n" +
                "      \"content\": \"" + message + "\",\n" +  // 动态插入用户消息
                "      \"role\": \"user\"\n" +
                "    }\n" +
                "  ],\n" +
                "  \"model\": \"deepseek-chat\",\n" +
                "  \"frequency_penalty\": 0,\n" +
                "  \"max_tokens\": 1024,\n" +
                "  \"presence_penalty\": 0,\n" +
                "  \"response_format\": {\n" +
                "    \"type\": \"text\"\n" +
                "  },\n" +
                "  \"stop\": null,\n" +
                "  \"stream\": false,\n" +
                "  \"stream_options\": null,\n" +
                "  \"temperature\": 1,\n" +
                "  \"top_p\": 1,\n" +
                "  \"tools\": null,\n" +
                "  \"tool_choice\": \"none\",\n" +
                "  \"logprobs\": false,\n" +
                "  \"top_logprobs\": null\n" +
                "}");
        Buffer buffer = new Buffer();
        try {
            requestBody.writeTo(buffer);
            System.out.println("Request Body Content: " + buffer.readUtf8());
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 创建 Headers
        Headers headers = new Headers.Builder()
                .add("Content-Type", "application/json")
                .add("Accept", "application/json")
                .add("Authorization", "Bearer " + config.getDeepSeekConfigUrl())  // 使用您的 API 密钥
                .build();
        // 创建 HttpUrl
        HttpUrl url = HttpUrl.parse(config.getDeepSeekConfigHost());
        if (url == null) {
            throw new IllegalArgumentException("您此时未携带URL参数");
        }
        // 构造 Request
        okhttp3.Request request = new okhttp3.Request.Builder()
                .url(url)
                .post(requestBody)
                .headers(headers)
                .build();
        // 执行请求并打印响应
        try (Response response = client.newCall(request).execute()) {
            String responseBody = response.body().string();
            System.out.println(responseBody);
            ChatCompletionResponse responseVo = JSON.parseObject(responseBody, ChatCompletionResponse.class);
            return responseVo;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

 四、返回结果

1.流式结果

 2.非流式请求


总结

因为我使用的是JDK21,不过你也可以使用JDK8去做这件事情,但是前提fastjson和okHttp的版本,因为有些方法可能不是很兼容,如果想要完成可能有一些方法需要替换一下,但是肯定是可以用的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/962721.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式C语言:什么是共用体?

在嵌入式C语言编程中&#xff0c;共用体&#xff08;Union&#xff09;是一种特殊的数据结构&#xff0c;它允许在相同的内存位置存储不同类型的数据。意味着共用体中的所有成员共享同一块内存区域&#xff0c;因此&#xff0c;在任何给定时间&#xff0c;共用体只能有效地存储…

Unet 改进:在encoder和decoder间加入TransformerBlock

目录 1. TransformerBlock 2. Unet 改进 3. 完整代码 Tips:融入模块后的网络经过测试,可以直接使用,设置好输入和输出的图片维度即可 1. TransformerBlock TransformerBlock是Transformer模型架构的基本组件,广泛应用于机器翻译、文本摘要和情感分析等自然语言处理任务…

音标-- 01--音标

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 国际音标1.元音音标单元音双元音常见单词 2.辅音音标清辅音&#xff0c;浊辅音清辅音&#xff08;不振动&#xff09;和 浊辅音&#xff08;振动&#xff09;是成对…

使用Pygame制作“打砖块”游戏

1. 前言 打砖块&#xff08;Breakout / Arkanoid&#xff09; 是一款经典街机游戏&#xff0c;玩家控制一个可左右移动的挡板&#xff0c;接住并反弹球&#xff0c;击碎屏幕上方的砖块。随着砖块被击碎&#xff0c;不仅能获得分数&#xff0c;还可以体验到不断加速或复杂的反弹…

【AI绘画】MidJourney关键词{Prompt}全面整理

AI绘画整理&#xff0c;MidJourney关键词。喜欢AI绘画的朋友必备&#xff0c;建议收藏&#xff0c;后面用到时供查阅使用。 1、光线与影子篇 中 英 闪耀的霓虹灯 shimmeringneon lights 黑暗中的影子 shadows in the dark 照亮城市的月光 moonlightilluminatingthe cit…

嵌入式系统|DMA和SPI

文章目录 DMA&#xff08;直接内存访问&#xff09;DMA底层原理1. 关键组件2. 工作机制3. DMA传输模式 SPI&#xff08;串行外设接口&#xff09;SPI的基本原理SPI连接示例 DMA与SPI的共同作用 DMA&#xff08;直接内存访问&#xff09; 类型&#xff1a;DMA是一种数据传输接口…

AVL树介绍

一、介绍 高度平衡的搜索二叉树&#xff0c;保证每个节点的左右子树高度差不超过1&#xff0c;降低搜索树的高度以提高搜索效率。 通过平衡因子和旋转来保证左右子树高度差不超过1 二、插入节点 1、插入规则 &#xff08;1&#xff09;搜按索树规则插入节点 &#xff08;…

win11 sourcetree安装问题

win11 sourcetree安装出现msys-2.0.dll 问题&#xff0c;需要从win10的以下路径复制出 msys-2.0.dll来加入到win11中 C:\Users\kz121468\AppData\Local\Atlassian\SourceTree\git_local\usr\bin\ 复制到 win11的 C:\Users\kz121468\AppData\Local\Atlassian\SourceTree\git_lo…

Contrastive Imitation Learning

机器人模仿学习中对比解码的一致性采样 摘要 本文中&#xff0c;我们在机器人应用的对比模仿学习中&#xff0c;利用一致性采样来挖掘演示质量中的样本间关系。通过在排序后的演示对比解码过程中&#xff0c;引入相邻样本间的一致性机制&#xff0c;我们旨在改进用于机器人学习…

Spring Web MVC基础第一篇

目录 1.什么是Spring Web MVC&#xff1f; 2.创建Spring Web MVC项目 3.注解使用 3.1RequestMapping&#xff08;路由映射&#xff09; 3.2一般参数传递 3.3RequestParam&#xff08;参数重命名&#xff09; 3.4RequestBody&#xff08;传递JSON数据&#xff09; 3.5Pa…

DeepSeek的使用技巧介绍

DeepSeek是一款由杭州深度求索人工智能技术有限公司开发的AI工具&#xff0c;结合了自然语言处理和深度学习技术&#xff0c;能够完成多种任务&#xff0c;如知识问答、数据分析、文案创作、代码开发等。以下将从使用技巧、核心功能及注意事项等方面详细介绍DeepSeek的使用方法…

创新创业计划书|建筑垃圾资源化回收

目录 第1部分 公司概况........................................................................ 1 第2部分 产品/服务...................................................................... 3 第3部分 研究与开发.................................................…

为AI聊天工具添加一个知识系统 之80 详细设计之21 符号逻辑 之1

本文要点 要点 前面我们讨论了本项目中的正则表达式。现在我们将前面讨论的正则表达式视为狭义的符号文本及其符号规则rule&#xff08;认识的原则--认识上认识对象的约束&#xff09;&#xff0c;进而在更广泛的视角下将其视为符号逻辑及其符号原则principle&#xff08;知识…

Spring Boot 热部署实现指南

在开发 Spring Bot 项目时&#xff0c;热部署功能能够显著提升开发效率&#xff0c;让开发者无需频繁重启服务器就能看到代码修改后的效果。下面为大家详细介绍一种实现 Spring Boot 热部署的方法&#xff0c;同时也欢迎大家补充其他实现形式。 步骤一、开启 IDEA 自动编译功能…

ARM嵌入式学习--第十一天(中断处理 , ADC)

--中断的概念 中断是指计算机运行过程中&#xff0c;出现某些意外情况需主机干预时&#xff0c;机器能自动停止正在运行的程序并转入处理新情况的程序&#xff0c;处理完毕后又返回被暂停的程序继续运行 --CPU处理事情的方式 -轮询方式 不断查询是否有事情需要处理&#xff0c…

ARM嵌入式学习--第十天(UART)

--UART介绍 UART(Universal Asynchonous Receiver and Transmitter)通用异步接收器&#xff0c;是一种通用串行数据总线&#xff0c;用于异步通信。该总线双向通信&#xff0c;可以实现全双工传输和接收。在嵌入式设计中&#xff0c;UART用来与PC进行通信&#xff0c;包括与监控…

socket实现HTTP请求,参考HttpURLConnection源码解析

背景 有台服务器&#xff0c;网卡绑定有2个ip地址&#xff0c;分别为&#xff1a; A&#xff1a;192.168.111.201 B&#xff1a;192.168.111.202 在这台服务器请求目标地址 C&#xff1a;192.168.111.203 时必须使用B作为源地址才能访问目标地址C&#xff0c;在这台服务器默认…

漏洞扫描工具之xray

下载地址&#xff1a;https://github.com/chaitin/xray/releases 1.9.11 使用文档&#xff1a;https://docs.xray.cool/tools/xray/Scanning 与burpsuite联动&#xff1a; https://xz.aliyun.com/news/7563 参考&#xff1a;https://blog.csdn.net/lza20001103/article/details…

正月初三特殊的一天

在我们河南豫东地区&#xff0c;初三这一天一般情况下可以在家休息&#xff0c;不需要串门走亲戚&#xff0c;给亲戚的长辈或比自己辈份长的拜年。 特殊的正月初三 还有两种情况&#xff0c;正月初三这一天必须去走亲戚。一种是有去世的亲戚没有过三周年&#xff0c;正月初三这…

强化学习笔记——4策略迭代、值迭代、TD算法

基于策略迭代的贝尔曼方程和基于值迭代的贝尔曼方程&#xff0c;关系还是不太理解 首先梳理一下&#xff1a; 通过贝尔曼方程将强化学习转化为值迭代和策略迭代两种问题 求解上述两种贝尔曼方程有三种方法&#xff1a;DP&#xff08;有模型&#xff09;&#xff0c;MC&#xff…