深入理解Java对接DeepSeek

news2025/2/12 22:53:44

其实,整个对接过程很简单,就四步,获取key,找到接口文档,接口测试,代码对接。

1.获取 KEY

https://platform.deepseek.com/transactions
直接付款就是了(现在官网暂停充值2025年2月7日),不比以前gpt,花钱都不知道怎么充值。
在这里插入图片描述
输入任意key名称,即可创建key。
在这里插入图片描述

2.对接文档

在当前页面下面,即可看到接口文档。访问就是了。https://api-docs.deepseek.com/zh-cn/
在这里插入图片描述

3.接口测试

注意:不要段时间内多次重复发送同一个问题,容易奔溃,然后就没办法调试了,目前DeepSeek还是很脆弱,不注意就奔溃了

3.1curl测试

这是接口文档里面的第一个示例。虽然只提供了curl、python、nodejs,对于我们对接来说,完全够了。
在这里插入图片描述
这里为了比较符合我们开发规范。如果你现在有个可以访问互联网的linux那就很简单了,把你的KEY复制出来,把下面的sk-5bf10*******************0eab换成你的实际key,然后在linux上面输入下面这个命令即可。

curl https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-5bf10***********************0eab" \
  -d '{
        "model": "deepseek-chat",
        "messages": [
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "Hello!"}
        ],
        "stream": false
      }'

3.2.PostMan

如果你没有一个联网的linux,那就简单,下载一个接口测试工具,例如postman
将curl中的对应信息填入到post中即可。
在这里插入图片描述

如下所示即可掉通。
在这里插入图片描述
例如,我用post提问:给一个SpringBoot入门案例
在这里插入图片描述

3.3.浏览器F12

如果你的电脑只有浏览一个,并且你实在不想安装类似postman这样的接口测试工具,那就用浏览器F12自带的开发者模式来调试吧。
随便打开一个页面,例如这里我打开的是百度,在console输入下面的代码。
在这里插入图片描述
注意如果出现这个提示信息。
Don’t paste code into the DevTools Console that you don’t understand or haven’t reviewed yourself. This could allow attackers to steal your identity or take control of your computer. Please type ‘allow pasting’ below and hit Enter to allow pasting.表示此时禁用了粘贴,这时候让你输入:allow pasting然后回车,就可以粘贴了。
在这里插入图片描述
有些网页会禁用鼠标右键粘贴(这种情况用ctrl + v就行了)

注意替换你的key

fetch('https://api.deepseek.com/chat/completions', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer sk-5bf10***********************0eab'
    },
    body: JSON.stringify({
        model: "deepseek-chat",
        messages: [
            { role: "system", content: "SpringBoot和Spring框架的最大区别是什么?" },
        ],
        stream: false
    })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

在这里插入图片描述

4.代码对接

4.1传统API对接

这里,我以大家最为熟练的RestTemplate来调用,代码如下

	@Autowired
	private RestTemplate restTemplate;
	
	@GetMapping("/api/traditional/restTemplate")
	public String traditional() {
		 String url = "https://api.deepseek.com/chat/completions";
		 
		 HttpHeaders headers = new HttpHeaders();
		 headers.setContentType(MediaType.APPLICATION_JSON);
		 
		 //换成你自己的Key
		 headers.set("Authorization", "Bearer sk-5bf1074b825a4xxxxxxxx50eab");
		 
		 //构建请求参数ChatReq
		 Message message = new Message("system", "SpringBoot和Spring框架的最大区别是什么?");
		 ChatReq requestBody = new ChatReq("deepseek-chat", Collections.singletonList(message), false);
		 HttpEntity<ChatReq> entity = new HttpEntity<>(requestBody, headers);
		 
		 ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
		 
		 if (response.getStatusCode().is2xxSuccessful()) {
			 System.out.println("Response: " + response.getBody());
		 } else {
			 System.out.println("Error: " + response.getStatusCode());
		 }
		 
		 return response.getBody();
	}

效果展示
在这里插入图片描述

4.2.流式API对接

如果有兴趣,建议你先阅读这篇文章,方便你理解。具体相关概念,我就不在介绍了,基本上百分之99吧,我们的各类GPT,AI助手,都是用流式API对接的。
传统API和流式响应API
现在有个问题,那就是传统API,他是一次性接收所有数据,如下所示,我们问的这个问题,deepseek是将整个问题回答完毕以后,然后一次性打包发送给我们,但是和我们平时使用的AI助手明显不是这样的,平常我们使用的AI助手,他的回答是一点点出来的。
在这里插入图片描述
根据官方API说明,只需要我们将stream 设置为true,即可实现流式响应。
在这里插入图片描述
当然问题不是仅仅改这个这么简单,这里改为true,表示的含义是,对方将会按照流式响应返回数据,同时,你也得用流式响应调用。具体相关细节见我另外的博客:传统API和流式响应API,这里我不在重复。

@GetMapping("/api/stream/restTemplate")
	public String stream() {
		WebClient webClient = WebClient.builder()
				.baseUrl("https://api.deepseek.com")
				.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
				.defaultHeader("Authorization", "Bearer sk-5bf1074b825a43dxxxxxxxxxxxx0e50eab")
				.build();
		
		// 构建请求参数 ChatReq
		Message message = new Message("system", "SpringBoot和Spring框架的最大区别是什么?");
		ChatReq requestBody = new ChatReq("deepseek-chat", Collections.singletonList(message), true); // 设置 stream 为 true
		
		// 发送 POST 请求并处理流式响应
		Flux<String> responseFlux = webClient.post()
				.uri("/chat/completions")
				.bodyValue(requestBody)
				.retrieve()
				.bodyToFlux(String.class);
		
		// 逐步打印响应数据
		responseFlux.subscribe(
				data -> System.out.println("Received: " + data),
				error -> System.err.println("Error: " + error),
				() -> System.out.println("Stream completed")
				);
        return null;
	}

通过日志,我们发现是一点点打印的,每次几个字,而不是一开始的那样,等待一段时间以后,然后一次性返回。
在这里插入图片描述
我们可以稍微处理下返回值。进行解析一下。例如我们只需要里面的content内容,当然你也可以一开始就定义好返回数据类型,而不是我示例中的String

{
    "id": "d3380a6c-965d-4649-9fe4-78d2a397202a", 
    "object": "chat.completion.chunk", 
    "created": 1739338918, 
    "model": "deepseek-chat", 
    "system_fingerprint": "fp_3a5770e1b4", 
    "choices": [
        {
            "index": 0, 
            "delta": {
                "content": "管理"
            }, 
            "logprobs": null, 
            "finish_reason": null
        }
    ]
}

下面是我们稍微处理了一下返回值,效果可能就更明确了

	@GetMapping("/api/stream/webClient ")
	public String stream() {
		WebClient webClient = WebClient.builder()
				.baseUrl("https://api.deepseek.com")
				.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
				.defaultHeader("Authorization", "Bearer sk-5bf1074b825a43da935920a9b0e50eab")
				.build();
		
		// 构建请求参数 ChatReq
		Message message = new Message("system", "SpringBoot和Spring框架的最大区别是什么?");
		ChatReq requestBody = new ChatReq("deepseek-chat", Collections.singletonList(message), true); // 设置 stream 为 true
		
		// 发送 POST 请求并处理流式响应
		Flux<String> responseFlux = webClient.post()
				.uri("/chat/completions")
				.bodyValue(requestBody)
				.retrieve()
				.bodyToFlux(String.class);
		
		// 逐步打印响应数据
		ObjectMapper objectMapper = new ObjectMapper();
		responseFlux.subscribe(
				data -> {
					JsonNode jsonNode;
					try {
						jsonNode = objectMapper.readTree(data);
						String content = jsonNode.get("choices").get(0).get("delta").get("content").asText();
						System.out.print(content);
					} catch (Exception e) {
						e.printStackTrace();
					}
				},
				error -> System.err.println("Error: " + error),
				() -> System.out.println("Stream completed")
				);
        return null;
	}

此时我们打印的就是挨个返回的信息。而不是等到所有数据准备完毕以后,一次性返回。
在这里插入图片描述

但是现在也还是有个问题,那就是,我们在控制台打印,相当于我们在一个传统阻塞的API接口中打印流式API接口返回的数据,我们是否有办法实现,我们将流式API接口的数据返回去,也就是在流式API接口里面调用流式API接口。

@GetMapping(value ="/api/stream/webClient/flux", produces = "text/event-stream;charset=UTF-8")
    public Flux<String> streamFlux(@RequestParam String ask) {
        WebClient webClient = WebClient.builder()
                .baseUrl("https://api.deepseek.com")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader("Authorization", "Bearer sk-5bf1074b825a43da935920a9b0e50eab")
                .build();

        // 构建请求参数 ChatReq
        Message message = new Message("system", ask);
        ChatReq requestBody = new ChatReq("deepseek-chat", Collections.singletonList(message), true); // 设置 stream 为 true

        // 发送 POST 请求并处理流式响应
        Flux<String> responseFlux = webClient.post()
                .uri("/chat/completions")
                .bodyValue(requestBody)
                .retrieve()
                .bodyToFlux(String.class);

        // 创建一个 Sinks 用于将数据推送到响应流
        Sinks.Many<String> sink = Sinks.many().multicast().onBackpressureBuffer();

        // 逐步处理响应数据并推送到 sink
        responseFlux.subscribe(
                data -> {
                    try {
                        ObjectMapper objectMapper = new ObjectMapper();
                        JsonNode jsonNode = objectMapper.readTree(data);
                        String content = jsonNode.get("choices").get(0).get("delta").get("content").asText();
                        System.out.print(content);
                        // 将提取的内容推送到响应流
                        sink.tryEmitNext(content); 
                    } catch (Exception e) {
                        sink.tryEmitError(e); // 处理错误
                    }
                },
                error -> sink.tryEmitError(error), // 处理错误
                () -> sink.tryEmitComplete() // 完成信号
        );

        return sink.asFlux(); // 返回响应流
    }

此时我们通过浏览器访问:

http://127.0.0.1:8081/api/stream/webClient/flux?ask=介绍一下华为北向网管接口

控制台打印是这样的。

浏览器页面看到是这样的

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线段平移 实战笔记

目录 pingyi2.py pingyi2.py import numpy as np import cv2# 画线段的函数 def draw_line(img, p1, p2, color, thickness=2):cv2.line(img, tuple(p1), tuple(p2), color, thickness)# 创建图像并初始化 def create_image():# 创建一个黑色背景图像img = np.zeros((500, 50…

WinForm 防破解、反编译设计文档

一、引言 1.1 文档目的 本设计文档旨在阐述 WinForm 应用程序防破解、反编译的设计方案&#xff0c;为开发团队提供详细的技术指导&#xff0c;确保软件的知识产权和商业利益得到有效保护。 1.2 背景 随着软件行业的发展&#xff0c;软件破解和反编译现象日益严重。WinForm…

DeepSeek应用——与word的配套使用

目录 一、效果展示 二、配置方法 三、使用方法 四、注意事项 1、永久化使用 2、宏被禁用 3、office的生成失败 记录自己学习应用DeepSeek的过程...... 这个是与WPS配套使用的过程&#xff0c;office的与这个类似&#xff1a; 一、效果展示 二、配置方法 1、在最上方的…

利用邮件合并将Excel的信息转为Word(单个测试用例转Word)

利用邮件合并将Excel的信息转为Word 效果一览效果前效果后 场景及问题解决方案 一、准备工作准备Excel数据源准备Word模板 二、邮件合并操作步骤连接Excel数据源插入合并域预览并生成合并文档 效果一览 效果前 效果后 场景及问题 在执行项目时的验收阶段&#xff0c;对于测试…

OpenCV 相机标定流程指南

OpenCV 相机标定流程指南 前置准备标定流程结果输出与验证建议源代码 OpenCV 相机标定流程指南 https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html https://learnopencv.com/camera-calibration-using-opencv/ 前置准备 制作标定板&#xff1a;生成高精度棋…

网络在线考试|基于vue的网络在线考试系统的设计与实现(源码+数据库+文档)

网络在线考试系统 目录 基于SSM&#xff0b;vue的网络在线考试系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1功能页面实现 2系统功能模块 3管理员功能模块 4学生功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八…

DEEPSEEK与GPT等AI技术在机床数据采集与数字化转型中的应用与影响

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;深度学习、自然语言处理等先进技术开始广泛应用于各行各业。在制造业尤其是机床行业&#xff0c;AI技术的融合带来了巨大的变革&#xff0c;尤其在机床数据采集与机床数字化方面的应用。本文将探讨DEEPSEEK、…

【文本处理】如何在批量WORD和txt文本提取手机号码,固话号码,提取邮箱,删除中文,删除英文,提取车牌号等等一些文本提取固定格式的操作,基于WPF的解决方案

企业的应用场景 数据清洗&#xff1a;在进行数据导入或分析之前&#xff0c;往往需要对大量文本数据进行预处理&#xff0c;比如去除文本中的无关字符&#xff08;中文、英文&#xff09;&#xff0c;只保留需要的联系信息&#xff08;手机号码、固话号码、邮箱&#xff09;。…

17vue3实战-----使用配置文件生成简易页面

17vue3实战-----使用配置文件生成简易页面 1.写在前面2.背景3.实现3.1界面效果3.2新建config配置文件3.3封装组件3.4使用组件 1.写在前面 后台管理系统的开发很简单。无论是用户模块、部门模块、角色模块还是其它模块,界面和业务逻辑都相对比较简单&#xff0c;我会省略这些模…

“mysqld --initialize --console ”执行不成功情况总结和解决措施

我的MYSQL版本是9.0.1出现类似下列的报错&#xff1a; 2024-10-29T01:09:55.942951Z 0 [System] [MY-015017] [Server] MySQL Server Initialization - start. 2024-10-29T01:09:55.950379Z 0 [Warning] [MY-010915] [Server] NO_ZERO_DATE, NO_ZERO_IN_DATE and ERROR_FOR_DIV…

STM32 Unix时间戳

Unix时间戳 Unix 时间戳&#xff08;Unix Timestamp&#xff09;定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数&#xff0c;不考虑闰秒 时间戳存储在一个秒计数器中&#xff0c;秒计数器为32位/64位的整型变量 世界上所有时区的秒计数器相同&#xff0c;不同时区通过…

qwen2.5-vl-7B视觉大模型 私有化部署webUI

服务器选用&#xff1a;算力云 部署qwen2.5-vl-7B&#xff0c;24g显卡跑不起图&#xff0c;单问问题就占20g左右。有能力可以用大点的显卡 一、下载模型 Qwen2.5-VL-7B-Instruct 有conda &#xff0c;可以在conda下操作&#xff0c;不知道conda的同学可以参考本博主之前的文章…

java安全中的类加载

java安全中的类加载 提前声明: 本文所涉及的内容仅供参考与教育目的&#xff0c;旨在普及网络安全相关知识。其内容不代表任何机构、组织或个人的权威建议&#xff0c;亦不构成具体的操作指南或法律依据。作者及发布平台对因使用本文信息直接或间接引发的任何风险、损失或法律纠…

如何在Windows中配置MySQL?

MySQL是一个广泛使用的开源关系型数据库管理系统&#xff0c;它支持多种操作系统平台&#xff0c;其中包括Windows。无论是开发者进行本地开发&#xff0c;还是管理员为应用程序配置数据库&#xff0c;MySQL都是一个非常流行的选择。本篇文章将详细介绍如何在Windows操作系统中…

Docker Desktop 镜像源配置

1 打开配置页面 2 docker engine 镜像配置位置 3、替换镜像内容 {"registry-mirrors": ["https://hub-mirror.c.163.com","https://mirror.ccs.tencentyun.com","https://05f073ad3c0010ea0f4bc00b7105ec20.mirror.swr.myhuaweicloud.c…

125,【1】攻防世界unserialize3

进入靶场 代码 <?php // 定义一个名为 xctf 的类 class xctf {// 定义一个公共属性 $flag&#xff0c;初始值为字符串 111public $flag 111;// 定义 __wakeup() 魔术方法// 当使用 unserialize() 函数反序列化对象时&#xff0c;会自动调用 __wakeup() 方法// 在这个方法…

2025年数据资产管理解决方案:资料合集,从基础知识到行业应用的全面解析

在数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。如何有效地管理和利用这些数据&#xff0c;将其转化为实际的经济价值&#xff0c;已成为企业面临的重要课题。 本文将通过数据资产解决方案、数据资产行业报告白皮书、数据资产政策汇编、数据资产基础知识以及数据资…

朝天椒USB服务器:解决加密狗远程连接

本文探讨朝天椒USB服务器用Usb Over Network技术&#xff0c;解决加密狗在虚拟机、云主机甚至异地的远程连接问题。 在企业数字化转型的浪潮中&#xff0c;加密狗作为防止软件盗版的重要手段&#xff0c;广泛应用于各类软件授权场景。然而&#xff0c;随着企业超融合进程不断加…

汽车与AI深度融合:CES Asia 2025前瞻

在科技飞速发展的当下&#xff0c;汽车与AI的融合正成为行业变革的关键驱动力。近日&#xff0c;吉利、极氪、岚图、智己等多家车企纷纷官宣与DeepSeek模型深度融合&#xff0c;其中岚图知音更是将成为首个搭载该模型的量产车型&#xff0c;这无疑是汽车智能化进程中的重要里程…

数据结构与算法-单链表

链表 参考学习&#xff1a;B站-逊哥带你学编程 单链表 单链表-存储结构 typedef int ElemType;typedef struct node{ElemType data;struct node *next; }Node;单链表-初始化 Node *initList() {Node *head (Node *)malloc(sizeof(Node));head->data 0;head->next …