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: 这里填写自己的APIKeyapi-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 {// 初始化 OkHttpClientOkHttpClient client = new OkHttpClient().newBuilder().build();// 创建动态请求体,使用流式传输RequestBody body = new RequestBody() {@Overridepublic okhttp3.MediaType contentType() {return okhttp3.MediaType.parse("application/json");}@Overridepublic 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);}};// 创建 HeadersHeaders headers = new Headers.Builder().add("Content-Type", "application/json").add("Accept", "application/json").add("Authorization", "Bearer " + config.getDeepSeekConfigUrl())  // 使用您的 API 密钥.build();// 创建 HttpUrlHttpUrl url = HttpUrl.parse(config.getDeepSeekConfigHost()); // 使用您的 API URLif (url == null) {throw new IllegalArgumentException("您此时未携带URL参数");}// 构造 Requestokhttp3.Request request = new okhttp3.Request.Builder().url(url).post(body)  // 使用流式请求体.headers(headers).build();// 执行请求并返回 Flux 流return Flux.create(sink -> {client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {// 异常发生时调用 sink.error()sink.error(e);}@Overridepublic 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@NoArgsConstructorpublic static class Choice {private int index;private Message message;private Object logprobs;private String finish_reason;}@Data@AllArgsConstructor@NoArgsConstructorpublic static class Message {private String role;private String content;}@Data@AllArgsConstructor@NoArgsConstructorpublic 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@NoArgsConstructorpublic 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) {// 初始化 OkHttpClientOkHttpClient 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();}// 创建 HeadersHeaders headers = new Headers.Builder().add("Content-Type", "application/json").add("Accept", "application/json").add("Authorization", "Bearer " + config.getDeepSeekConfigUrl())  // 使用您的 API 密钥.build();// 创建 HttpUrlHttpUrl url = HttpUrl.parse(config.getDeepSeekConfigHost());if (url == null) {throw new IllegalArgumentException("您此时未携带URL参数");}// 构造 Requestokhttp3.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.rhkb.cn/news/9095.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低代码系统-产品架构案例介绍、明道云(十一)

明道云HAP-超级应用平台(Hyper Application Platform)&#xff0c;其实就是企业级应用平台&#xff0c;跟微搭类似。 通过自设计底层架构&#xff0c;兼容各种平台&#xff0c;使用低代码做到应用搭建、应用运维。 企业级应用平台最大的特点就是隐藏在冰山下的功能很深&#xf…

文献阅读 250128-Tropical forests are approaching critical temperature thresholds

Tropical forests are approaching critical temperature thresholds 来自 <Tropical forests are approaching critical temperature thresholds | Nature> 热带森林正在接近临界温度阈值 ## Abstract: The critical temperature beyond which photosynthetic machinery…

判断子序列

hello 大家好&#xff01;今天开写一个新章节&#xff0c;每一天一道算法题。让我们一起来学习算法思维吧&#xff01; function isSubsequence(s, t) {// 初始化两个指针&#xff0c;分别指向字符串 s 和 t 的起始位置let i 0; let j 0; // 当两个指针都未超出对应字符串的长…

您与此网站之间建立的连接不安全

网站建立好后&#xff0c;用360浏览器打开后地址栏有一个灰色小锁打着红色叉点击后显示“您与此网站之间建立的连接不安全”“请勿在此网站上输入任何敏感信息&#xff08;例如密码或信用卡信息&#xff09;&#xff0c;因为攻击者可能会盗取这些信息。” 出现这个提示的主要原…

解读隐私保护工具 Fluidkey:如何畅游链上世界而不暴露地址?

作者&#xff1a;Techub 独家解读 撰文&#xff1a;Tia&#xff0c;Techub News 隐私不只是个人权利的象征&#xff0c;更是我们迈向透明、信任未来的重要过渡桥梁。如果你还未意识到隐私的重要性&#xff0c;推荐阅读 KeyMapDAO 的文章《「被出卖的自由」&#xff1a;我到底该…

uniapp 地图添加,删除,编辑标记,在地图中根据屏幕范围中呈现标记

前言 小程序实现新功能&#xff0c;在地图中选取位置添加标记&#xff0c;并在地图中呈现添加的标记&#xff0c;&#xff08;呈现的是根据当前屏幕范围内的标记&#xff09;&#xff0c;并对标记进行分享&#xff0c;删除&#xff0c;编辑&#xff0c;导航&#xff0c;并从分…

DPO、KTO、DiffusionDPO

DPO&#xff08;Direct Preference Optimization&#xff09; 原文来自于 https://arxiv.org/pdf/2305.18290&#xff0c; Bradley-Terry (BT)模型&#xff0c;假设人的喜欢遵循下面的公式&#xff0c;给定x&#xff0c;得到 y 1 y_1 y1​和 y 2 y_2 y2​分别遵循以下关系&am…

Android Studio安装配置

一、注意事项 想做安卓app和开发板通信&#xff0c;踩了大坑&#xff0c;Android 开发不是下载了就能直接开发的&#xff0c;对于新手需要注意的如下&#xff1a; 1、Android Studio版本&#xff0c;根据自己的Android Studio版本对应决定了你所兼容的AGP&#xff08;Android…

GPU上没程序在跑但是显存被占用

原因&#xff1a;存在僵尸线程&#xff0c;运行完但是没有释放内存 查看僵尸线程 fuser -v /dev/nvidia*关闭僵尸线程 pkill -9 -u 用户名 程序名 举例&#xff1a;pkill -9 -u grs python参考&#xff1a;https://blog.csdn.net/qq_40206371/article/details/143798866

JAVA实战开源项目:蜗牛兼职平台(Vue+SpringBoot) 附源码

本文项目编号 T 034 &#xff0c;文末自助获取源码 \color{red}{T034&#xff0c;文末自助获取源码} T034&#xff0c;文末自助获取源码 目录 一、系统介绍1.1 平台架构1.2 管理后台1.3 用户网页端1.4 技术特点 二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景…

DeepSeek LLM解读

背景&#xff1a; 量化巨头幻方探索AGI&#xff08;通用人工智能&#xff09;新组织“深度求索”在成立半年后&#xff0c;发布的第一代大模型DeepSeek试用地址&#xff1a;DeepSeek &#xff0c;免费商用&#xff0c;完全开源。作为一家隐形的AI巨头&#xff0c;幻方拥有1万枚…

用WinForm如何制作简易计算器

首先我们要自己搭好页面 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace _7_简易计算…

Luzmo 专为SaaS公司设计的嵌入式数据分析平台

Luzmo 是一款嵌入式数据分析平台&#xff0c;专为 SaaS 公司设计&#xff0c;旨在通过直观的可视化和快速开发流程简化数据驱动决策。以下是关于 Luzmo 的详细介绍&#xff1a; 1. 背景与定位 Luzmo 前身为 Cumul.io &#xff0c;专注于为 SaaS 公司提供嵌入式分析解决方案。…

Openfga 授权模型搭建

1.根据项目去启动 配置一个 openfga 服务器 先创建一个 config.yaml文件 cd /opt/openFGA/conf touch ./config.yaml 怎么配置&#xff1f; 根据官网来看 openfga/.config-schema.json at main openfga/openfga GitHub 这里讲述详细的每一个配置每一个类型 这些配置有…

【物联网】ARM核常用指令(详解):数据传送、计算、位运算、比较、跳转、内存访问、CPSR/SPSR、流水线及伪指令

文章目录 指令格式&#xff08;重点&#xff09;1. 立即数2. 寄存器位移 一、数据传送指令1. MOV指令2. MVN指令3. LDR指令 二、数据计算指令1. ADD指令1. SUB指令1. MUL指令 三、位运算指令1. AND指令2. ORR指令3. EOR指令4. BIC指令 四、比较指令五、跳转指令1. B/BL指令2. l…

星火大模型接入及文本生成HTTP流式、非流式接口(JAVA)

文章目录 一、接入星火大模型二、基于JAVA实现HTTP非流式接口1.配置2.接口实现&#xff08;1&#xff09;分析接口请求&#xff08;2&#xff09;代码实现 3.功能测试&#xff08;1&#xff09;测试对话功能&#xff08;2&#xff09;测试记住上下文功能 三、基于JAVA实现HTTP流…

lightweight-charts-python 包 更新 lightweight-charts.js 的方法

lightweight-charts-python 是 lightweight-charts.js 的 python 包装&#xff0c;非常好用 lightweight-charts 更新比较频繁&#xff0c;导致 lightweight-charts-python 内置的 lightweight-charts 经常不是最新的。 新的 lightweight-charts 通常可以获得性能改进和bug修复…

记录 | Docker的windows版安装

目录 前言一、1.1 打开“启用或关闭Windows功能”1.2 安装“WSL”方式1&#xff1a;命令行下载方式2&#xff1a;离线包下载 二、Docker Desktop更新时间 前言 参考文章&#xff1a;Windows Subsystem for Linux——解决WSL更新速度慢的方案 参考视频&#xff1a;一个视频解决D…

2025年01月27日Github流行趋势

项目名称&#xff1a;onlook项目地址url&#xff1a;https://github.com/onlook-dev/onlook项目语言&#xff1a;TypeScript历史star数&#xff1a;5340今日star数&#xff1a;211项目维护者&#xff1a;Kitenite, drfarrell, iNerdStack, abhiroopc84, apps/dependabot项目简介…

【Linux探索学习】第二十七弹——信号(一):Linux 信号基础详解

Linux学习笔记&#xff1a; https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 前面我们已经将进程通信部分讲完了&#xff0c;现在我们来讲一个进程部分也非常重要的知识点——信号&#xff0c;信号也是进程间通信的一…