DeepSeek API 调用 - Spring Boot 实现
1. 项目依赖
在 pom.xml
中添加以下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
2. 项目结构
deepseek-project/
├── src/main/java/com/example/deepseek/
│ ├── DeepSeekApplication.java
│ ├── config/
│ │ └── DeepSeekConfig.java
│ ├── model/
│ │ ├── ChatRequest.java
│ │ ├── ChatResponse.java
│ │ └── Message.java
│ └── service/
│ └── DeepSeekService.java
└── conversation.txt
3. 完整代码实现
3.1 配置类 DeepSeekConfig.java
package com.example.deepseek.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
@Getter
public class DeepSeekConfig {
@Value("${deepseek.api.url}")
private String apiUrl;
@Value("${deepseek.api.key}")
private String apiKey;
}
3.2 请求/响应模型
Message.java
:
package com.example.deepseek.model;
import lombok.Data;
@Data
public class Message {
private String role;
private String content;
}
ChatRequest.java
:
package com.example.deepseek.model;
import lombok.Data;
import java.util.List;
@Data
public class ChatRequest {
private String model = "deepseek-ai/DeepSeek-V3";
private List<Message> messages;
private boolean stream = true;
private int max_tokens = 2048;
private double temperature = 0.7;
private double top_p = 0.7;
private int top_k = 50;
private double frequency_penalty = 0.5;
private int n = 1;
private ResponseFormat response_format = new ResponseFormat("text");
@Data
public static class ResponseFormat {
private String type;
public ResponseFormat(String type) {
this.type = type;
}
}
}
ChatResponse.java
:
package com.example.deepseek.model;
import lombok.Data;
import java.util.List;
@Data
public class ChatResponse {
private List<Choice> choices;
@Data
public static class Choice {
private Delta delta;
}
@Data
public static class Delta {
private String content;
}
}
3.3 服务类 DeepSeekService.java
package com.example.deepseek.service;
import com.example.deepseek.config.DeepSeekConfig;
import com.example.deepseek.model.ChatRequest;
import com.example.deepseek.model.ChatResponse;
import com.example.deepseek.model.Message;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Scanner;
@Service
@RequiredArgsConstructor
public class DeepSeekService {
private final DeepSeekConfig config;
private final WebClient.Builder webClientBuilder;
private final ObjectMapper objectMapper = new ObjectMapper();
public void startInteractiveChat() {
try (Scanner scanner = new Scanner(System.in);
PrintWriter fileWriter = new PrintWriter(new FileWriter("conversation.txt", true))) {
while (true) {
System.out.print("\n请输入您的问题 (输入 q 退出): ");
String question = scanner.nextLine().trim();
if ("q".equalsIgnoreCase(question)) {
System.out.println("程序已退出");
break;
}
// 保存问题
saveToFile(fileWriter, question, true);
// 发起对话请求
Flux<String> responseFlux = sendChatRequest(question);
StringBuilder fullResponse = new StringBuilder();
responseFlux
.doOnNext(chunk -> {
System.out.print(chunk);
fullResponse.append(chunk);
})
.doOnComplete(() -> {
// 保存完整回复
saveToFile(fileWriter, fullResponse.toString(), false);
System.out.println("\n----------------------------------------");
fileWriter.println("\n----------------------------------------");
fileWriter.flush();
})
.blockLast();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private Flux<String> sendChatRequest(String question) {
ChatRequest request = new ChatRequest();
Message userMessage = new Message();
userMessage.setRole("user");
userMessage.setContent(question);
request.setMessages(Collections.singletonList(userMessage));
return webClientBuilder.build()
.post()
.uri(config.getApiUrl())
.header("Authorization", "Bearer " + config.getApiKey())
.header("Content-Type", "application/json")
.bodyValue(request)
.retrieve()
.bodyToFlux(String.class)
.filter(line -> line.startsWith("data: ") && !line.equals("data: [DONE]"))
.map(line -> {
try {
String jsonStr = line.substring(6);
ChatResponse response = objectMapper.readValue(jsonStr, ChatResponse.class);
return response.getChoices().get(0).getDelta().getContent();
} catch (Exception e) {
return "";
}
})
.filter(content -> !content.isEmpty());
}
private void saveToFile(PrintWriter fileWriter, String content, boolean isQuestion) {
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
if (isQuestion) {
fileWriter.printf("\n[%s] Question:\n%s\n\n[%s] Answer:\n", timestamp, content, timestamp);
} else {
fileWriter.print(content);
}
fileWriter.flush();
}
}
3.4 主应用类 DeepSeekApplication.java
package com.example.deepseek;
import com.example.deepseek.service.DeepSeekService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class DeepSeekApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DeepSeekApplication.class, args);
DeepSeekService deepSeekService = context.getBean(DeepSeekService.class);
deepSeekService.startInteractiveChat();
}
}
3.5 配置文件 application.properties
deepseek.api.url=https://api.siliconflow.cn/v1/chat/completions
deepseek.api.key=YOUR_API_KEY
4. 代码详解
4.1 关键特性
- 使用 Spring WebFlux 的响应式编程模型
- 流式处理 API 响应
- 文件记录对话
- 错误处理和异常管理
4.2 主要组件
DeepSeekConfig
: 管理 API 配置DeepSeekService
: 处理对话逻辑和 API 交互- 模型类: 定义请求和响应结构
5. 使用方法
- 替换
application.properties
中的YOUR_API_KEY
- 运行
DeepSeekApplication
- 在控制台输入问题
- 输入 ‘q’ 退出程序
- 查看
conversation.txt
获取对话记录
6. 性能和可扩展性
- 使用响应式编程提高并发性能
- 灵活的配置管理
- 易于扩展和定制
7. 注意事项
- 确保正确配置 API Key
- 处理网络异常
- 注意内存使用
总结
Spring Boot 实现提供了一个健壮、可扩展的 DeepSeek API 调用方案,利用响应式编程提供高效的流式对话体验。
立即体验
快来体验 DeepSeek:https://cloud.siliconflow.cn/i/vnCCfVaQ