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");@Datapublic 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;@Datapublic static class Choice {private Delta delta;}@Datapublic 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