|
|
@@ -1,17 +1,17 @@
|
|
|
package org.springblade.common.utils;
|
|
|
|
|
|
-import okhttp3.*;
|
|
|
import com.google.gson.Gson;
|
|
|
import com.google.gson.JsonObject;
|
|
|
import com.google.gson.JsonParser;
|
|
|
-import org.springblade.common.vo.DeepSeekResponse;
|
|
|
+import okhttp3.*;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
-import java.util.Collections;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@Component
|
|
|
public class DeepSeekClient {
|
|
|
@@ -21,90 +21,66 @@ public class DeepSeekClient {
|
|
|
|
|
|
private static final String API_URL = "https://api.deepseek.com/v1/chat/completions";
|
|
|
|
|
|
- private final OkHttpClient client = new OkHttpClient();
|
|
|
+ private final OkHttpClient client;
|
|
|
private final Gson gson = new Gson();
|
|
|
|
|
|
+ public DeepSeekClient() {
|
|
|
+ this.client = new OkHttpClient.Builder()
|
|
|
+ .connectTimeout(30, TimeUnit.SECONDS)
|
|
|
+ .readTimeout(60, TimeUnit.SECONDS)
|
|
|
+ .writeTimeout(30, TimeUnit.SECONDS)
|
|
|
+ .build();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 请求 DeepSeek API
|
|
|
- * @param prompt 需要发送的文字
|
|
|
- * @return API 响应
|
|
|
- * @throws IOException
|
|
|
*/
|
|
|
public String callDeepSeek(String prompt) throws IOException {
|
|
|
- // 使用 V3 模型
|
|
|
DeepSeekRequest request = new DeepSeekRequest(prompt, "deepseek-chat");
|
|
|
-
|
|
|
- // 构造请求体
|
|
|
String requestJson = gson.toJson(request);
|
|
|
- logger.debug("Sending request to DeepSeek: {}", requestJson);
|
|
|
|
|
|
- RequestBody body = RequestBody.create(
|
|
|
- requestJson,
|
|
|
- MediaType.parse("application/json")
|
|
|
- );
|
|
|
+ logger.debug("Sending request to DeepSeek: {}", requestJson);
|
|
|
|
|
|
- // 构造请求
|
|
|
Request httpRequest = new Request.Builder()
|
|
|
.url(API_URL)
|
|
|
- .post(body)
|
|
|
+ .post(RequestBody.create(requestJson, MediaType.parse("application/json")))
|
|
|
.addHeader("Authorization", "Bearer " + API_KEY)
|
|
|
.addHeader("Content-Type", "application/json")
|
|
|
.addHeader("Accept", "application/json")
|
|
|
.build();
|
|
|
|
|
|
- // 发送请求并获取响应
|
|
|
try (Response response = client.newCall(httpRequest).execute()) {
|
|
|
if (!response.isSuccessful()) {
|
|
|
String errorBody = response.body() != null ? response.body().string() : "No error body";
|
|
|
logger.error("API request failed with code: {}, Body: {}", response.code(), errorBody);
|
|
|
- throw new IOException("API request failed with code: " + response.code() + ", Body: " + errorBody);
|
|
|
+ throw new IOException("API request failed with code: " + response.code());
|
|
|
}
|
|
|
-
|
|
|
- String responseBody = response.body().string();
|
|
|
- logger.debug("Received response from DeepSeek: {}", responseBody);
|
|
|
- return responseBody;
|
|
|
+ return response.body().string();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 解析响应获取结果
|
|
|
- * @param responseJson 请求 deepseek 返回响应值
|
|
|
- * @return 消息内容
|
|
|
*/
|
|
|
public String analysisResponse(String responseJson) {
|
|
|
try {
|
|
|
- // 使用 JsonParser 替代 Gson.fromJson 以便更好的错误处理
|
|
|
JsonObject jsonObject = JsonParser.parseString(responseJson).getAsJsonObject();
|
|
|
|
|
|
- // 检查是否有错误
|
|
|
if (jsonObject.has("error")) {
|
|
|
JsonObject error = jsonObject.getAsJsonObject("error");
|
|
|
String errorMsg = error.get("message").getAsString();
|
|
|
logger.error("API returned error: {}", errorMsg);
|
|
|
- return "API Error: " + errorMsg;
|
|
|
+ return "Error: " + errorMsg;
|
|
|
}
|
|
|
|
|
|
- // 解析为对象
|
|
|
DeepSeekResponse response = gson.fromJson(jsonObject, DeepSeekResponse.class);
|
|
|
|
|
|
- // 安全地获取 content 内容
|
|
|
- if (response == null) {
|
|
|
- logger.error("Failed to parse response JSON");
|
|
|
- return "Error: Failed to parse response";
|
|
|
- }
|
|
|
-
|
|
|
- if (response.getChoices() == null || response.getChoices().isEmpty()) {
|
|
|
- logger.error("No choices in response");
|
|
|
- return "Error: No choices in response";
|
|
|
- }
|
|
|
-
|
|
|
- DeepSeekResponse.Choice firstChoice = response.getChoices().get(0);
|
|
|
- if (firstChoice.getMessage() == null) {
|
|
|
- logger.error("No message in choice");
|
|
|
- return "Error: No message in choice";
|
|
|
+ if (response == null || response.getChoices() == null || response.getChoices().isEmpty()) {
|
|
|
+ logger.error("Invalid response structure");
|
|
|
+ return "Error: Invalid response structure";
|
|
|
}
|
|
|
|
|
|
- return firstChoice.getMessage().getContent();
|
|
|
+ return response.getChoices().get(0).getMessage().getContent();
|
|
|
} catch (Exception e) {
|
|
|
logger.error("Error parsing response: {}", e.getMessage());
|
|
|
return "Error: " + e.getMessage();
|
|
|
@@ -112,9 +88,7 @@ public class DeepSeekClient {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 直接获取精简后的内容(一步完成调用和解析)
|
|
|
- * @param prompt 提示词
|
|
|
- * @return 精简后的内容
|
|
|
+ * 直接获取精简后的内容
|
|
|
*/
|
|
|
public String getSimplifiedContent(String prompt) {
|
|
|
try {
|
|
|
@@ -126,33 +100,128 @@ public class DeepSeekClient {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 请求参数类 - 支持多种模型
|
|
|
static class DeepSeekRequest {
|
|
|
- String model;
|
|
|
- Message[] messages;
|
|
|
- double temperature = 0.7;
|
|
|
- int max_tokens = 2000;
|
|
|
- boolean stream = false;
|
|
|
+ private String model;
|
|
|
+ private Message[] messages;
|
|
|
+ private double temperature = 0.7;
|
|
|
+ private int max_tokens = 2000;
|
|
|
+ private boolean stream = false;
|
|
|
|
|
|
- public DeepSeekRequest(String prompt) {
|
|
|
- this(prompt, "deepseek-chat"); // 默认使用 V3 模型
|
|
|
+ // 构造函数
|
|
|
+ public DeepSeekRequest(String prompt, String model) {
|
|
|
+ this.model = model;
|
|
|
+ this.messages = new Message[]{new Message("user", prompt)};
|
|
|
}
|
|
|
|
|
|
- public DeepSeekRequest(String prompt, String model) {
|
|
|
+ // Getters and Setters
|
|
|
+ public String getModel() {
|
|
|
+ return model;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setModel(String model) {
|
|
|
this.model = model;
|
|
|
- this.messages = new Message[]{
|
|
|
- new Message("user", prompt)
|
|
|
- };
|
|
|
+ }
|
|
|
+
|
|
|
+ public Message[] getMessages() {
|
|
|
+ return messages;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setMessages(Message[] messages) {
|
|
|
+ this.messages = messages;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getTemperature() {
|
|
|
+ return temperature;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setTemperature(double temperature) {
|
|
|
+ this.temperature = temperature;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getMax_tokens() {
|
|
|
+ return max_tokens;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setMax_tokens(int max_tokens) {
|
|
|
+ this.max_tokens = max_tokens;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean isStream() {
|
|
|
+ return stream;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setStream(boolean stream) {
|
|
|
+ this.stream = stream;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static class Message {
|
|
|
- String role;
|
|
|
- String content;
|
|
|
+ private String role;
|
|
|
+ private String content;
|
|
|
|
|
|
+ // 构造函数
|
|
|
public Message(String role, String content) {
|
|
|
this.role = role;
|
|
|
this.content = content;
|
|
|
}
|
|
|
+
|
|
|
+ // Getters and Setters
|
|
|
+ public String getRole() {
|
|
|
+ return role;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setRole(String role) {
|
|
|
+ this.role = role;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getContent() {
|
|
|
+ return content;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setContent(String content) {
|
|
|
+ this.content = content;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static class DeepSeekResponse {
|
|
|
+ private List<Choice> choices;
|
|
|
+
|
|
|
+ public List<Choice> getChoices() {
|
|
|
+ return choices;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setChoices(List<Choice> choices) {
|
|
|
+ this.choices = choices;
|
|
|
+ }
|
|
|
+
|
|
|
+ static class Choice {
|
|
|
+ private Message message;
|
|
|
+ private int index;
|
|
|
+ private String finish_reason;
|
|
|
+
|
|
|
+ public Message getMessage() {
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setMessage(Message message) {
|
|
|
+ this.message = message;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getIndex() {
|
|
|
+ return index;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setIndex(int index) {
|
|
|
+ this.index = index;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getFinish_reason() {
|
|
|
+ return finish_reason;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setFinish_reason(String finish_reason) {
|
|
|
+ this.finish_reason = finish_reason;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|