package com.zy.ai.service;
|
|
import com.alibaba.fastjson.JSON;
|
import com.zy.ai.entity.ChatCompletionRequest;
|
import com.zy.ai.entity.WcsDiagnosisRequest;
|
import com.zy.ai.utils.AiPromptUtils;
|
import com.zy.ai.utils.AiUtils;
|
import com.zy.common.utils.RedisUtil;
|
import com.zy.core.enums.RedisKeyType;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.stereotype.Service;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
|
@Service
|
@RequiredArgsConstructor
|
public class WcsDiagnosisService {
|
|
private static final long CHAT_TTL_SECONDS = 7L * 24 * 3600;
|
|
@Autowired
|
private LlmChatService llmChatService;
|
@Autowired
|
private RedisUtil redisUtil;
|
@Autowired
|
private AiPromptUtils aiPromptUtils;
|
@Autowired
|
private AiUtils aiUtils;
|
|
/**
|
* 针对“系统不执行任务 / 不知道哪个设备没在运行”的通用 AI 诊断
|
*/
|
public String diagnose(WcsDiagnosisRequest request) {
|
List<ChatCompletionRequest.Message> messages = new ArrayList<>();
|
|
// 1. system:定义专家身份 + 输出结构
|
ChatCompletionRequest.Message system = new ChatCompletionRequest.Message();
|
system.setRole("system");
|
system.setContent(aiPromptUtils.getAiDiagnosePrompt());
|
messages.add(system);
|
|
ChatCompletionRequest.Message user = new ChatCompletionRequest.Message();
|
user.setRole("user");
|
user.setContent(aiUtils.buildDiagnosisUserContent(request));
|
messages.add(user);
|
|
// 调用大模型
|
return llmChatService.chat(messages, 0.2, 2048);
|
}
|
|
public void diagnoseStream(WcsDiagnosisRequest request, SseEmitter emitter) {
|
List<ChatCompletionRequest.Message> messages = new ArrayList<>();
|
|
ChatCompletionRequest.Message system = new ChatCompletionRequest.Message();
|
system.setRole("system");
|
system.setContent(aiPromptUtils.getAiDiagnosePrompt());
|
messages.add(system);
|
|
ChatCompletionRequest.Message user = new ChatCompletionRequest.Message();
|
user.setRole("user");
|
user.setContent(aiUtils.buildDiagnosisUserContent(request));
|
messages.add(user);
|
|
llmChatService.chatStream(messages, 0.2, 2048, s -> {
|
try {
|
String safe = s == null ? "" : s.replace("\r", "").replace("\n", "\\n");
|
if (!safe.isEmpty()) {
|
emitter.send(SseEmitter.event().data(safe));
|
}
|
} catch (Exception ignore) {}
|
}, () -> {
|
try { emitter.complete(); } catch (Exception ignore) {}
|
}, e -> {
|
try { emitter.completeWithError(e); } catch (Exception ignore) {}
|
});
|
}
|
|
public void askStream(WcsDiagnosisRequest request,
|
String prompt,
|
String chatId,
|
boolean reset,
|
SseEmitter emitter) {
|
List<ChatCompletionRequest.Message> base = new ArrayList<>();
|
|
ChatCompletionRequest.Message system = new ChatCompletionRequest.Message();
|
system.setRole("system");
|
system.setContent(aiPromptUtils.getWcsSensorPrompt());
|
base.add(system);
|
|
List<ChatCompletionRequest.Message> history = null;
|
String historyKey = null;
|
String metaKey = null;
|
if (chatId != null && !chatId.isEmpty()) {
|
historyKey = RedisKeyType.AI_CHAT_HISTORY.key + chatId;
|
metaKey = RedisKeyType.AI_CHAT_META.key + chatId;
|
if (reset) {
|
redisUtil.del(historyKey, metaKey);
|
}
|
List<Object> stored = redisUtil.lGet(historyKey, 0, -1);
|
if (stored != null && !stored.isEmpty()) {
|
history = new ArrayList<>(stored.size());
|
for (Object o : stored) {
|
ChatCompletionRequest.Message m = convertToMessage(o);
|
if (m != null) history.add(m);
|
}
|
if (!history.isEmpty()) base.addAll(history);
|
} else {
|
history = new ArrayList<>();
|
}
|
}
|
|
ChatCompletionRequest.Message contextMsg = new ChatCompletionRequest.Message();
|
contextMsg.setRole("user");
|
contextMsg.setContent(aiUtils.buildAskUserContent(request));
|
base.add(contextMsg);
|
|
ChatCompletionRequest.Message questionMsg = new ChatCompletionRequest.Message();
|
questionMsg.setRole("user");
|
questionMsg.setContent("【用户提问】\n" + (prompt == null ? "" : prompt));
|
base.add(questionMsg);
|
|
StringBuilder assistantBuffer = new StringBuilder();
|
final String finalChatId = chatId;
|
final String finalHistoryKey = historyKey;
|
final String finalMetaKey = metaKey;
|
final String finalPrompt = prompt;
|
|
llmChatService.chatStream(base, 0.2, 2048, s -> {
|
try {
|
String safe = s == null ? "" : s.replace("\r", "").replace("\n", "\\n");
|
if (!safe.isEmpty()) {
|
emitter.send(SseEmitter.event().data(safe));
|
assistantBuffer.append(s);
|
}
|
} catch (Exception ignore) {}
|
}, () -> {
|
try {
|
if (finalChatId != null && !finalChatId.isEmpty()) {
|
ChatCompletionRequest.Message q = new ChatCompletionRequest.Message();
|
q.setRole("user");
|
q.setContent(finalPrompt == null ? "" : finalPrompt);
|
ChatCompletionRequest.Message a = new ChatCompletionRequest.Message();
|
a.setRole("assistant");
|
a.setContent(assistantBuffer.toString());
|
redisUtil.lSet(finalHistoryKey, q);
|
redisUtil.lSet(finalHistoryKey, a);
|
redisUtil.expire(finalHistoryKey, CHAT_TTL_SECONDS);
|
Map<Object, Object> old = redisUtil.hmget(finalMetaKey);
|
Long createdAt = old != null && old.get("createdAt") != null ?
|
(old.get("createdAt") instanceof Number ? ((Number) old.get("createdAt")).longValue() : Long.valueOf(String.valueOf(old.get("createdAt"))))
|
: System.currentTimeMillis();
|
Map<String, Object> meta = new java.util.HashMap<>();
|
meta.put("chatId", finalChatId);
|
meta.put("title", buildTitleFromPrompt(finalPrompt));
|
meta.put("createdAt", createdAt);
|
meta.put("updatedAt", System.currentTimeMillis());
|
redisUtil.hmset(finalMetaKey, meta, CHAT_TTL_SECONDS);
|
}
|
emitter.complete();
|
} catch (Exception ignore) {}
|
}, e -> {
|
try { emitter.completeWithError(e); } catch (Exception ignore) {}
|
});
|
}
|
|
public List<Map<String, Object>> listChats() {
|
java.util.Set<String> keys = redisUtil.scanKeys(RedisKeyType.AI_CHAT_META.key, 1000);
|
List<Map<String, Object>> resp = new ArrayList<>();
|
if (keys != null) {
|
for (String key : keys) {
|
Map<Object, Object> m = redisUtil.hmget(key);
|
if (m != null && !m.isEmpty()) {
|
java.util.HashMap<String, Object> item = new java.util.HashMap<>();
|
for (Map.Entry<Object, Object> e : m.entrySet()) {
|
item.put(String.valueOf(e.getKey()), e.getValue());
|
}
|
String chatId = String.valueOf(item.get("chatId"));
|
String historyKey = RedisKeyType.AI_CHAT_HISTORY.key + chatId;
|
item.put("size", redisUtil.lGetListSize(historyKey));
|
resp.add(item);
|
}
|
}
|
}
|
return resp;
|
}
|
|
public boolean deleteChat(String chatId) {
|
if (chatId == null || chatId.isEmpty()) return false;
|
String historyKey = RedisKeyType.AI_CHAT_HISTORY.key + chatId;
|
String metaKey = RedisKeyType.AI_CHAT_META.key + chatId;
|
redisUtil.del(historyKey, metaKey);
|
return true;
|
}
|
|
public List<ChatCompletionRequest.Message> getChatHistory(String chatId) {
|
if (chatId == null || chatId.isEmpty()) return java.util.Collections.emptyList();
|
String historyKey = RedisKeyType.AI_CHAT_HISTORY.key + chatId;
|
List<Object> stored = redisUtil.lGet(historyKey, 0, -1);
|
List<ChatCompletionRequest.Message> result = new ArrayList<>();
|
if (stored != null) {
|
for (Object o : stored) {
|
ChatCompletionRequest.Message m = convertToMessage(o);
|
if (m != null) result.add(m);
|
}
|
}
|
return result;
|
}
|
|
private ChatCompletionRequest.Message convertToMessage(Object o) {
|
if (o instanceof ChatCompletionRequest.Message) {
|
return (ChatCompletionRequest.Message) o;
|
}
|
if (o instanceof Map) {
|
Map<?, ?> map = (Map<?, ?>) o;
|
ChatCompletionRequest.Message m = new ChatCompletionRequest.Message();
|
Object role = map.get("role");
|
Object content = map.get("content");
|
m.setRole(role == null ? null : String.valueOf(role));
|
m.setContent(content == null ? null : String.valueOf(content));
|
return m;
|
}
|
return null;
|
}
|
|
private String buildTitleFromPrompt(String prompt) {
|
if (prompt == null || prompt.isEmpty()) return "未命名会话";
|
String p = prompt.replaceAll("\n", " ").trim();
|
return p.length() > 20 ? p.substring(0, 20) : p;
|
}
|
|
}
|