一、必要依赖
pom.xml
xml
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- SpringBoot Webflux-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
二、api相关配置
yaml
deepseek:
api:
url: https://api.deepseek.com
key: ${API keys}
API keys
在deepseek开放平台
(https://platform.deepseek.com/api_keys)注册登录后获得。调用api还需要充值
三、关键代码逻辑
deepseek
模型
java
enum DEEPSEEK_MODEL {
V3("deepseek-chat"),
R1("deepseek-reasoner");
private String name;
DEEPSEEK_MODEL(String name) {
this.name = name;
}
}
请求参数DeepSeekRequest
java
@Data
public class DeepSeekRequest {
private String model;
private List<Message> messages;
private Boolean stream;
@Data
public static class Message {
private String role;
private String content;
public Message(String role, String content) {
this.role = role;
this.content = content;
}
}
}
返回参数DeepSeekStreamResponse
java
@Data
public class DeepSeekStreamResponse {
private String id;
private String object;
private String created;
private String model;
private String system_fingerprint;
private List<Choice> choices;
private Usage usage;
@Data
public static class Choice {
private Integer index;
private Message delta;
private String logprobs;
private String finish_reason;
@Data
public static class Message {
private String role;
private String content;
private String reasoning_content;
}
}
@Data
public static class Usage {
private Integer prompt_tokens;
private Integer completion_tokens;
private Integer total_tokens;
private PromptTokensDetails prompt_tokens_details;
private Integer prompt_cache_hit_tokens;
private Integer prompt_cache_miss_tokens;
@Data
public static class PromptTokensDetails {
private Integer cached_tokens;
}
}
}
DeepSeekService
服务
java
import com.alibaba.fastjson2.JSON;
import com.left.domain.DEEPSEEK_MODEL;
import com.left.domain.request.DeepSeekRequest;
import com.left.domain.response.DeepSeekStreamResponse;
import io.netty.channel.ChannelOption;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
import javax.annotation.PostConstruct;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class DeepSeekService {
@Value("${deepseek.api.url}")
private String apiUrl;
@Value("${deepseek.api.key}")
private String apiKey;
private WebClient webClient;
@PostConstruct
private void initClient() {
log.info("初始化WebClient...");
HttpClient httpClient = HttpClient.create(ConnectionProvider
.builder("deepseek-pool")
.maxConnections(100)
.pendingAcquireTimeout(Duration.ofSeconds(120))
.build())
.compress(true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2 * 60 * 1000)
.responseTimeout(Duration.ofSeconds(120));
this.webClient = WebClient.builder()
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1))
.baseUrl(apiUrl)
.clientConnector(new ReactorClientHttpConnector(httpClient))
.defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
}
public Flux<String> callDeepSeek(String message) {
log.info("调用deepseek接口开始");
long start = System.currentTimeMillis();
try {
DeepSeekRequest request = new DeepSeekRequest();
request.setModel(DEEPSEEK_MODEL.R1.name); //r1模型
request.setStream(true); // 流式
List<DeepSeekRequest.Message> list = new ArrayList<>();
//提示库,可根据自己需要修改
list.add(new DeepSeekRequest.Message("system", "你是一位大模型提示词生成专家,请根据用户的需求编写一个智能助手的提示词,来指导大模型进行内容生成,要求:\n" +
"1. 以 Markdown 格式输出\n" +
"2. 贴合用户需求,描述智能助手的定位、能力、知识储备\n" +
"3. 提示词应清晰、精确、易于理解,在保持质量的同时,尽可能简洁\n" +
"4. 只输出提示词,不要输出多余解释"));
list.add(new DeepSeekRequest.Message("user", message));
request.setMessages(list);
return webClient.post()
.uri("/v1/chat/completions")
.bodyValue(request)
.retrieve()
.bodyToFlux(String.class)
.filter(resp -> !resp.startsWith("[DONE]"))
.doOnNext(resp -> {
DeepSeekStreamResponse response = JSON.parseObject(resp, DeepSeekStreamResponse.class);
DeepSeekStreamResponse.Choice choice = response.getChoices().get(0);
DeepSeekStreamResponse.Choice.Message message = choice.getDelta();
if (message != null) {
log.info("deepseek接口返回:{}", message.getContent() != null ? message.getContent() : message.getReasoning_content());
}
}).map(resp -> {
DeepSeekStreamResponse response = JSON.parseObject(resp, DeepSeekStreamResponse.class);
DeepSeekStreamResponse.Choice choice = response.getChoices().get(0);
DeepSeekStreamResponse.Choice.Message message = choice.getDelta();
if (message == null) {
return "";
}
return message.getReasoning_content() != null ? message.getReasoning_content() : message.getContent();
})
.onErrorResume(e -> Flux.just("[ERROR] " + e.getMessage()))
.doFinally(e -> {
log.info("调用deepseek接口结束,耗时:{}ms", System.currentTimeMillis() - start);
});
} catch (Exception e) {
log.error("调用deepseek接口异常", e);
}
return Flux.just("");
}
}
调用
java
@PostMapping("/call")
public Flux<String> call(String message) {
return deepSeekService.callDeepSeek(message);
}
四、返回的原始数据
json
// 1、通用数据
{
"id": "c973449d-6fe7-4eaf-8869-c3db3f9fe747",
"object": "chat.completion.chunk",
"created": 1741004759,
"model": "deepseek-chat",
"system_fingerprint": "fp_3a5770e1b4_prod0225",
"choices": [{
"index": 0,
"delta": {
"content": "详细信息"
},
"logprobs": null,
"finish_reason": null
}]
}
//2、带role标识的数据
{
"id": "c973449d-6fe7-4eaf-8869-c3db3f9fe747",
"object": "chat.completion.chunk",
"created": 1741004759,
"model": "deepseek-chat",
"system_fingerprint": "fp_3a5770e1b4_prod0225",
"choices": [{
"index": 0,
"delta": {
"role": "assistant",
"content": ""
},
"logprobs": null,
"finish_reason": null
}]
}
//3、结束帧
{
"id": "c973449d-6fe7-4eaf-8869-c3db3f9fe747",
"object": "chat.completion.chunk",
"created": 1741004759,
"model": "deepseek-chat",
"system_fingerprint": "fp_3a5770e1b4_prod0225",
"choices": [{
"index": 0,
"delta": {
"content": ""
},
"logprobs": null,
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 130,
"completion_tokens": 451,
"total_tokens": 581,
"prompt_tokens_details": {
"cached_tokens": 128
},
"prompt_cache_hit_tokens": 128,
"prompt_cache_miss_tokens": 2
}
}
其他的api可访问https://api-docs.deepseek.com/zh-cn/
进行查看