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

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的版本,因为有些方法可能不是很兼容,如果想要完成可能有一些方法需要替换一下,但是肯定是可以用的


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

相关文章:

  • 危机13小时:追踪一场GitHub投毒事件
  • 微服务(一)
  • Julius AI 人工智能数据分析工具介绍
  • 判断子序列
  • ARM64平台Flutter环境搭建
  • 深入探讨数据库索引类型:B-tree、Hash、GIN与GiST的对比与应用
  • Baklib数字化内容管理打破传统束缚提升企业效能
  • 内置序列,专业版已破!
  • 【cran Archive R包的安装方式】
  • 开源先锋DeepSeek-V3 LLM 大语言模型本地调用,打造自己专属 AI 助手
  • 1688平台数据深度挖掘:商品详情与关键词搜索实战指南
  • 在线课堂小程序设计与实现(LW+源码+讲解)
  • linux通过deb包安装(命令模式)
  • 从synchronized到ReentrantLock_Java锁机制的演进与选择
  • waitpid使用
  • 新年祝词(原创)
  • Egg.js GraphQL 完整指南
  • Github 2025-01-28 Python开源项目日报 Top9
  • C语言/C++的函数——memset函数
  • 【2024年华为OD机试】 (C卷,200分)- 发广播(JavaScriptJava PythonC/C++)
  • 【愚公系列】《循序渐进Vue.js 3.x前端开发实践》022-定义组件
  • 基于STM32的智能语音控制灯光系统设计
  • tcp/ip协议中ip层协议,tcp/ip协议中ip协议属于
  • computed , watch 的妙用
  • stack 和 queue容器的介绍和使用
  • 项目部署(springboot项目)