|
@@ -1,5 +1,7 @@
|
|
|
package com.backendsys.modules.sdk.deepseek.service.impl;
|
|
|
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.json.JSONArray;
|
|
|
import cn.hutool.json.JSONObject;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
@@ -7,6 +9,7 @@ import com.backendsys.exception.CustException;
|
|
|
import com.backendsys.modules.ai.chat.entity.Chat;
|
|
|
import com.backendsys.modules.ai.chat.entity.ChatResult;
|
|
|
import com.backendsys.modules.ai.chat.entity.ChatSseMessage;
|
|
|
+import com.backendsys.modules.common.config.redis.utils.RedisUtil;
|
|
|
import com.backendsys.modules.sdk.deepseek.entity.DSRequest;
|
|
|
import com.backendsys.modules.sdk.deepseek.entity.DSRequestMessage;
|
|
|
import com.backendsys.modules.sdk.deepseek.service.DeepSeekClient;
|
|
@@ -45,8 +48,14 @@ public class DeepSeekClientImpl implements DeepSeekClient {
|
|
|
private String API_URL;
|
|
|
@Value("${deepseek-api.api-key}")
|
|
|
private String API_KEY;
|
|
|
+
|
|
|
+ @Value("${spring.application.name}")
|
|
|
+ private String APPLICATION_NAME;
|
|
|
+
|
|
|
@Autowired
|
|
|
private SseUtil sseUtil;
|
|
|
+ @Autowired
|
|
|
+ private RedisUtil redisUtil;
|
|
|
|
|
|
/**
|
|
|
* [DeepSeek] 发起对话
|
|
@@ -55,7 +64,12 @@ public class DeepSeekClientImpl implements DeepSeekClient {
|
|
|
@Override
|
|
|
public ChatResult chatCompletion(Long user_id, String model, String prompt, String history_code, List<Chat> chatList) {
|
|
|
|
|
|
- long replyDuration = 0L;
|
|
|
+ // 定义作用于全局的变量
|
|
|
+ Long replyDuration = 0L;
|
|
|
+ Boolean isThinking = false;
|
|
|
+ String requestOfRedisKey = APPLICATION_NAME + "-chat-history-" + history_code;
|
|
|
+ StringBuilder allReplyContent = new StringBuilder();
|
|
|
+ StringBuilder allThinkContent = new StringBuilder();
|
|
|
|
|
|
ChatResult chatResult = new ChatResult();
|
|
|
try {
|
|
@@ -121,21 +135,29 @@ public class DeepSeekClientImpl implements DeepSeekClient {
|
|
|
|
|
|
long thinkStartTime = 0L; // 开始思考时间
|
|
|
long thinkDuration = 0L; // 思考耗时
|
|
|
- Boolean isThinking = false;
|
|
|
+
|
|
|
|
|
|
System.out.println("API 调用耗时: " + apiDuration + " 毫秒");
|
|
|
System.out.println("---- 开始流式回答: ------------------------------------");
|
|
|
|
|
|
// [SSE] 发送消息
|
|
|
- ChatSseMessage chatLoadingSseMessage = new ChatSseMessage("LOADING", "正在思考");
|
|
|
+ ChatSseMessage chatLoadingSseMessage = new ChatSseMessage("LOADING", "正在思考", null, history_code);
|
|
|
sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatLoadingSseMessage).toJsonStr());
|
|
|
|
|
|
- StringBuilder allReplyContent = new StringBuilder();
|
|
|
- StringBuilder allThinkContent = new StringBuilder();
|
|
|
+
|
|
|
|
|
|
String line;
|
|
|
while ((line = reader.readLine()) != null) {
|
|
|
|
|
|
+ // 判断是否中止
|
|
|
+ if (ObjectUtil.isEmpty(redisUtil.getCacheObject(requestOfRedisKey))) {
|
|
|
+ System.out.println("中止!");
|
|
|
+ request.abort();
|
|
|
+ // 流程结束后,删除锁
|
|
|
+ redisUtil.delete(requestOfRedisKey);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
// System.out.println(line);
|
|
|
/*
|
|
|
---------------------- line ----------------------
|
|
@@ -172,7 +194,7 @@ public class DeepSeekClientImpl implements DeepSeekClient {
|
|
|
System.out.println("reasoning_content: " + reasoning_content);
|
|
|
|
|
|
// [SSE] 发送消息
|
|
|
- ChatSseMessage chatSseMessage = new ChatSseMessage("THINK", reasoning_content);
|
|
|
+ ChatSseMessage chatSseMessage = new ChatSseMessage("THINK", reasoning_content, null, history_code);
|
|
|
sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
|
|
|
|
|
|
// 收集推理内容
|
|
@@ -193,13 +215,13 @@ public class DeepSeekClientImpl implements DeepSeekClient {
|
|
|
System.out.println("-----------------------------------------------");
|
|
|
|
|
|
// [SSE] 发送消息
|
|
|
- ChatSseMessage chatSseMessage = new ChatSseMessage("THINK", "[DONE][THINK]", thinkDuration);
|
|
|
+ ChatSseMessage chatSseMessage = new ChatSseMessage("THINK", "[DONE][THINK]", thinkDuration, history_code);
|
|
|
sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
|
|
|
|
|
|
}
|
|
|
|
|
|
// [SSE] 发送消息
|
|
|
- ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", content);
|
|
|
+ ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", content, null, history_code);
|
|
|
sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
|
|
|
|
|
|
// 收集回答内容
|
|
@@ -217,38 +239,55 @@ public class DeepSeekClientImpl implements DeepSeekClient {
|
|
|
System.out.println("全部回答: " + allReplyContent);
|
|
|
System.out.println("总输出耗时: " + replyDuration + " 毫秒");
|
|
|
|
|
|
-// // [SSE] 发送消息
|
|
|
-// ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", "[DONE][REPLY]", replyDuration);
|
|
|
-// sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
|
|
|
-
|
|
|
chatResult.setReasoning_content(allThinkContent.toString());
|
|
|
chatResult.setReasoning_duration(thinkDuration);
|
|
|
chatResult.setContent(allReplyContent.toString());
|
|
|
chatResult.setContent_duration(replyDuration);
|
|
|
+
|
|
|
+ redisUtil.delete(requestOfRedisKey);
|
|
|
+
|
|
|
return chatResult;
|
|
|
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
- System.out.println(e.getMessage());
|
|
|
+ System.out.println("Exception(1): " + e.getMessage());
|
|
|
+ String message = e.getMessage();
|
|
|
+ if (message.contains("Premature end of chunk coded message body: closing chunk expected")) {
|
|
|
+ message = "(请求中止)";
|
|
|
+ }
|
|
|
// [SSE] 发送消息
|
|
|
- ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", e.getMessage(), replyDuration);
|
|
|
+ String contentType = (isThinking ? "THINK_ABORT" : "REPLY_ABORT");
|
|
|
+ ChatSseMessage chatSseMessage = new ChatSseMessage(contentType, e.getMessage(), replyDuration, history_code);
|
|
|
sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
|
|
|
+ redisUtil.delete(requestOfRedisKey);
|
|
|
+
|
|
|
+ // chatResult.setContent(e.getMessage());
|
|
|
+ // 由于中止导致的错误信息叠加 (一并保存进数据库)
|
|
|
+ if (StrUtil.isNotEmpty(allThinkContent.toString())) {
|
|
|
+ if (isThinking) {
|
|
|
+ chatResult.setReasoning_content(allThinkContent.toString() + " " + message);
|
|
|
+ } else {
|
|
|
+ chatResult.setReasoning_content(allThinkContent.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ chatResult.setContent(allReplyContent.toString() + " " + message);
|
|
|
|
|
|
- chatResult.setContent(e.getMessage());
|
|
|
return chatResult;
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
- System.out.println(e.getMessage());
|
|
|
+ System.out.println("Exception(2): " + e.getMessage());
|
|
|
// [SSE] 发送消息
|
|
|
- ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", e.getMessage(), replyDuration);
|
|
|
+ String contentType = (isThinking ? "THINK_ABORT" : "REPLY_ABORT");
|
|
|
+ ChatSseMessage chatSseMessage = new ChatSseMessage(contentType, e.getMessage(), replyDuration, history_code);
|
|
|
sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
|
|
|
-
|
|
|
+ redisUtil.delete(requestOfRedisKey);
|
|
|
chatResult.setContent(e.getMessage());
|
|
|
return chatResult;
|
|
|
} finally {
|
|
|
// [SSE] 发送消息
|
|
|
- ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", "[DONE][REPLY]", replyDuration);
|
|
|
+ ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", "[DONE][REPLY]", replyDuration, history_code);
|
|
|
sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
|
|
|
+ redisUtil.delete(requestOfRedisKey);
|
|
|
}
|
|
|
|
|
|
}
|