|
@@ -6,6 +6,8 @@ import com.alibaba.fastjson.JSONObject;
|
|
|
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.sdk.deepseek.entity.DSRequest;
|
|
|
+import com.backendsys.modules.sdk.deepseek.entity.DSRequestMessage;
|
|
|
import com.backendsys.modules.sse.entity.SseResponse;
|
|
|
import com.backendsys.modules.sse.entity.SseResponseEnum;
|
|
|
import com.backendsys.modules.sse.utils.SseUtil;
|
|
@@ -22,9 +24,7 @@ import org.springframework.stereotype.Component;
|
|
|
import java.io.BufferedReader;
|
|
|
import java.io.InputStreamReader;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
|
|
/**
|
|
@@ -48,7 +48,7 @@ public class OllamaUtil {
|
|
|
/**
|
|
|
* 流式对话
|
|
|
*/
|
|
|
- public ChatResult chatDeepSeek(Long user_id, String model, String prompt, List<Chat> chatList) {
|
|
|
+ public ChatResult chatDeepSeek(Long user_id, String model, String prompt, String history_code, List<Chat> chatList) {
|
|
|
|
|
|
long contentDuration = 0L;
|
|
|
|
|
@@ -59,22 +59,80 @@ public class OllamaUtil {
|
|
|
// 记录请求开始时间
|
|
|
long allStartTime = System.currentTimeMillis();
|
|
|
|
|
|
+
|
|
|
+
|
|
|
// 加入上下文历史对话
|
|
|
- System.out.println("---------------------- 历史对话: ----------------------");
|
|
|
- System.out.println("-----------------------------------------------------");
|
|
|
+ System.out.println("---- 历史对话 (history_code): " + history_code + " ----");
|
|
|
+
|
|
|
+ List<DSRequestMessage> messages = new ArrayList<>();
|
|
|
+ if (chatList != null && !chatList.isEmpty()) {
|
|
|
+ chatList.stream().forEach(chat -> {
|
|
|
+ if (!"THINK".equals(chat.getContent_type())) {
|
|
|
+ messages.add(new DSRequestMessage(chat.getRole(), chat.getContent()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 反转列表
|
|
|
+ Collections.reverse(messages);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 新的对话内容
|
|
|
+ messages.add(new DSRequestMessage("user", prompt));
|
|
|
+
|
|
|
+ // 输出全部对话内容
|
|
|
+ messages.stream().forEach(msg -> {
|
|
|
+ System.out.println("[" + msg.getRole() + "]: " + msg.getContent());
|
|
|
+ });
|
|
|
+ System.out.println("---------------------------------------------------------------------");
|
|
|
|
|
|
|
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
try (CloseableHttpClient client = HttpClients.createDefault()) {
|
|
|
|
|
|
- HttpPost request = new HttpPost(DOMAIN + "/api/generate");
|
|
|
- Map<String, Object> requestMap = new HashMap<>();
|
|
|
- requestMap.put("model", model);
|
|
|
- requestMap.put("prompt", prompt);
|
|
|
- requestMap.put("stream", true);
|
|
|
+ /*
|
|
|
+ 【/api/generate】
|
|
|
+ 它是一个相对基础的文本生成端点,主要用于根据给定的提示信息生成一段连续的文本。
|
|
|
+ 这个端点会基于输入的提示,按照模型的语言生成能力输出一段完整的内容,更侧重于单纯的文本生成任务。
|
|
|
+ 生成过程不依赖于上下文的历史对话信息,每次请求都是独立的,模型仅依据当前输入的提示进行文本生成。
|
|
|
+ {
|
|
|
+ "model": "llama2", "prompt": "请描述一下美丽的海滩", "num_predict": 200, "temperature": 0.7
|
|
|
+ }
|
|
|
+
|
|
|
+ 【/api/chat】
|
|
|
+ 该端点专为模拟聊天场景设计,具备处理对话上下文的能力。它可以跟踪对话的历史记录,理解对话的上下文信息,从而生成更符合对话逻辑和连贯性的回复。
|
|
|
+ 更注重模拟真实的人机对话交互,能够根据历史对话和当前输入生成合适的回应,适用于构建聊天机器人等交互式应用。
|
|
|
+ {
|
|
|
+ "model": "deepseek-r1:1.5b",
|
|
|
+ "messages": [
|
|
|
+ {
|
|
|
+ "role": "system",
|
|
|
+ "content": "你是一个能够理解中文指令并帮助完成任务的智能助手。你的任务是根据用户的需求生成合适的分类任务或生成任务,并准确判断这些任务的类型。请确保你的回答简洁、准确且符合中英文语境。"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "role": "user",
|
|
|
+ "content": "写一个简单的 Python 函数,用于计算两个数的和"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "stream": false
|
|
|
+ }
|
|
|
+ */
|
|
|
+
|
|
|
+ // [Chat] 构建请求体
|
|
|
+ HttpPost request = new HttpPost(DOMAIN + "/api/chat");
|
|
|
+ DSRequest body = new DSRequest();
|
|
|
+ body.setModel(model);
|
|
|
+ body.setMessages(messages);
|
|
|
+ body.setStream(true);
|
|
|
+ String requestBody = objectMapper.writeValueAsString(body);
|
|
|
+
|
|
|
+// // [Generate] 构建请求体
|
|
|
+// HttpPost request = new HttpPost(DOMAIN + "/api/generate");
|
|
|
+// Map<String, Object> requestMap = new HashMap<>();
|
|
|
+// requestMap.put("model", model);
|
|
|
+// requestMap.put("prompt", prompt);
|
|
|
+// requestMap.put("stream", true);
|
|
|
+// String requestBody = objectMapper.writeValueAsString(requestMap);
|
|
|
|
|
|
- String requestBody = objectMapper.writeValueAsString(requestMap);
|
|
|
request.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
|
|
|
|
|
|
try (CloseableHttpResponse response = client.execute(request);
|
|
@@ -87,7 +145,7 @@ public class OllamaUtil {
|
|
|
Boolean isThinking = false;
|
|
|
|
|
|
System.out.println("API 调用耗时: " + apiDuration + " 毫秒");
|
|
|
- System.out.println("-------------------- 开始流式回答: --------------------");
|
|
|
+ System.out.println("---- 开始流式回答: ------------------------------------");
|
|
|
|
|
|
// [SSE] 发送消息
|
|
|
ChatSseMessage chatLoadingSseMessage = new ChatSseMessage("LOADING", "正在思考");
|
|
@@ -101,15 +159,26 @@ public class OllamaUtil {
|
|
|
|
|
|
System.out.println(line);
|
|
|
/*
|
|
|
- ---------------------- line ----------------------
|
|
|
+ ---------------------- [Chat] line ----------------------
|
|
|
+ {"model":"deepseek-r1:1.5b","created_at":"2025-03-18T07:37:06.483163789Z","message":{"role":"assistant","content":"\u003cthink\u003e"},"done":false}
|
|
|
+ ---------------------- [Generate] line ----------------------
|
|
|
{"model":"deepseek-r1:1.5b","created_at":"2025-03-05T10:51:17.443189986Z","response":"\u003cthink\u003e","done":false}
|
|
|
{"model":"deepseek-r1:1.5b","created_at":"2025-03-06T11:08:30.9219611Z","response":"\n\n","done":false}
|
|
|
- --------------------------------------------------
|
|
|
+ -------------------------------------------------------------
|
|
|
*/
|
|
|
|
|
|
// 每行数据可以是一个JSON对象,根据实际情况处理
|
|
|
JSONObject resJson = JSONObject.parseObject(line);
|
|
|
- String content = resJson.getString("response");
|
|
|
+
|
|
|
+ // --------------------------------------------------------------
|
|
|
+ // [Chat]
|
|
|
+ JSONObject resJsonMessage = resJson.getJSONObject("message");
|
|
|
+ String content = resJsonMessage.getString("content");
|
|
|
+
|
|
|
+// // [Generate]
|
|
|
+// String content = resJson.getString("response");
|
|
|
+ // --------------------------------------------------------------
|
|
|
+
|
|
|
|
|
|
// System.out.println("content: " + content);
|
|
|
// content: \n\n
|
|
@@ -126,7 +195,7 @@ public class OllamaUtil {
|
|
|
isThinking = false;
|
|
|
thinkDuration = thinkStartTime - allStartTime;
|
|
|
System.out.println("推理耗时: " + thinkDuration + "毫秒");
|
|
|
- System.out.println("-----------------------------------------------");
|
|
|
+ System.out.println("-----------------------------------------------------");
|
|
|
|
|
|
if (allThinkContent.length() > 0){
|
|
|
// [SSE] 发送消息
|
|
@@ -201,6 +270,8 @@ public class OllamaUtil {
|
|
|
sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
|
|
|
|
|
|
chatResult.setContent(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+
|
|
|
return chatResult;
|
|
|
}
|
|
|
} catch (Exception e) {
|