From efeb0bd6fb60a6216cb3626df204100546466b23 Mon Sep 17 00:00:00 2001
From: ageerle <ageerle@163.com>
Date: 星期五, 11 四月 2025 12:05:13 +0800
Subject: [PATCH] fix: ollama兼容联网查询 知识库检索

---
 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java |  152 ++++++++++++++++++++++++++++++--------------------
 1 files changed, 91 insertions(+), 61 deletions(-)

diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java
index 357280d..6cf19b4 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java
@@ -84,11 +84,9 @@
 
     private final IChatCostService chatCostService;
 
-    private static final String requestIdTemplate = "mycompany-%d";
+    private static final String requestIdTemplate = "company-%d";
 
     private static final ObjectMapper mapper = new ObjectMapper();
-
-    private OpenAiStreamClient openAiModelStreamClient;
 
     @Override
     public SseEmitter sseChat(ChatRequest chatRequest, HttpServletRequest request) {
@@ -96,65 +94,33 @@
         SSEEventSourceListener openAIEventSourceListener = new SSEEventSourceListener(sseEmitter);
         // 鑾峰彇瀵硅瘽娑堟伅鍒楄〃
         List<Message> messages = chatRequest.getMessages();
-        // 鐢ㄦ埛瀵硅瘽鍐呭
-        String chatString = null;
         try {
-            if (StpUtil.isLogin()) {
-                // 閫氳繃妯″瀷鍚嶇О鏌ヨ妯″瀷淇℃伅
-                ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
-                if(chatModelVo!=null){
-                    // 閫氳繃妯″瀷淇℃伅鏋勫缓璇锋眰瀹㈡埛绔�
-                    openAiModelStreamClient = chatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey());
-                }else {
-                    // 浣跨敤榛樿瀹㈡埛绔�
-                    openAiModelStreamClient  = openAiStreamClient;
-                }
+            // 鏌ヨ妯″瀷淇℃伅
+            ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
+
+            OpenAiStreamClient openAiModelStreamClient;
+            if(chatModelVo!=null){
+                // 寤鸿姹傚鎴风
+                openAiModelStreamClient = chatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey());
                 // 璁剧疆榛樿鎻愮ず璇�
-                Message sysMessage = Message.builder().content(chatModelVo.getSystemPrompt()).role(Message.Role.SYSTEM).build();
-                messages.add(0,sysMessage);
-
-                // 鏌ヨ鍚戦噺搴撶浉鍏充俊鎭姞鍏ュ埌涓婁笅鏂�
-                if(chatRequest.getKid()!=null){
-                    List<Message> knMessages = new ArrayList<>();
-                    String content = messages.get(messages.size() - 1).getContent().toString();
-                    List<String> nearestList;
-                    List<Double> queryVector = embeddingService.getQueryVector(content, chatRequest.getKid());
-                    nearestList = vectorStore.nearest(queryVector, chatRequest.getKid());
-                    for (String prompt : nearestList) {
-                        Message userMessage = Message.builder().content(prompt).role(Message.Role.USER).build();
-                        knMessages.add(userMessage);
-                    }
-                    Message userMessage = Message.builder().content(content + (!nearestList.isEmpty() ? "\n\n娉ㄦ剰锛氬洖绛旈棶棰樻椂锛岄』涓ユ牸鏍规嵁鎴戠粰浣犵殑绯荤粺涓婁笅鏂囧唴瀹瑰師鏂囪繘琛屽洖绛旓紝璇蜂笉瑕佽嚜宸卞彂鎸�,鍥炵瓟鏃朵繚鎸佸師鏉ユ枃鏈殑娈佃惤灞傜骇" : "")).role(Message.Role.USER).build();
-                    knMessages.add(userMessage);
-                    messages.addAll(knMessages);
-                }
-
-                // 鑾峰彇鐢ㄦ埛瀵硅瘽淇℃伅
-                Object content = messages.get(messages.size() - 1).getContent();
-                if (content instanceof List<?> listContent) {
-                    if (CollectionUtil.isNotEmpty(listContent)) {
-                        chatString = listContent.get(0).toString();
-                    }
-                } else if (content instanceof String) {
-                    chatString = (String) content;
-                }
-
-                // 鍔犺浇鑱旂綉淇℃伅
-                if(chatRequest.getSearch()){
-                    Message message = Message.builder().role(Message.Role.ASSISTANT).content("鑱旂綉淇℃伅:"+webSearch(chatString)).build();
-                    messages.add(message);
-                }
+                chatRequest.setSysPrompt(chatModelVo.getSystemPrompt());
             }else {
-                // 鏈櫥褰曠敤鎴烽檺鍒跺璇濇鏁�
-                String clientIp = IpUtil.getClientIp(request);
+                // 浣跨敤榛樿瀹㈡埛绔�
+                openAiModelStreamClient = openAiStreamClient;
+            }
+            // 鏋勫缓娑堟伅鍒楄〃澧炲姞鑱旂綉銆佺煡璇嗗簱绛夊唴瀹�
+            buildChatMessageList(chatRequest);
 
+            // 鏍规嵁妯″瀷鍚嶇О鍓嶇紑璋冪敤涓嶅悓鐨勫鐞嗛�昏緫
+            switchModelAndHandle(chatRequest);
+
+            // 鏈櫥褰曠敤鎴烽檺鍒跺璇濇鏁�
+            if (!StpUtil.isLogin()) {
+                String clientIp = IpUtil.getClientIp(request);
                 // 璁垮姣忓ぉ榛樿鍙兘瀵硅瘽5娆�
                 int timeWindowInSeconds = 5;
-
                 String redisKey = "clientIp:" + clientIp;
-
                 int count = 0;
-
                 if (RedisUtils.getCacheObject(redisKey) == null) {
                     // 缂撳瓨鏈夋晥鏃堕棿1澶�
                     RedisUtils.setCacheObject(redisKey, count, Duration.ofSeconds(86400));
@@ -175,6 +141,7 @@
                     .stream(chatRequest.getStream())
                     .build();
             openAiModelStreamClient.streamChatCompletion(completion, openAIEventSourceListener);
+
             // 淇濆瓨娑堟伅璁板綍 骞舵墸闄よ垂鐢�
             chatCostService.deductToken(chatRequest);
         } catch (Exception e) {
@@ -185,6 +152,69 @@
         return sseEmitter;
     }
 
+    /**
+     *  鏍规嵁妯″瀷鍚嶇О鍓嶇紑璋冪敤涓嶅悓鐨勫鐞嗛�昏緫
+     */
+    private void switchModelAndHandle(ChatRequest chatRequest) {
+        String model = chatRequest.getModel();
+        // 濡傛灉妯″瀷鍚嶇О浠llama寮�澶达紝鍒欒皟鐢╫llama涓儴缃茬殑鏈湴妯″瀷
+        if (model.startsWith("ollama-")) {
+            String[] parts = chatRequest.getModel().split("ollama-", 2); // 闄愬埗鍒嗗壊娆℃暟涓�2
+            if (parts.length > 1) {
+                chatRequest.setModel(parts[1]);
+                ollamaChat(chatRequest);
+            } else {
+                throw new IllegalArgumentException("Invalid ollama model name: " + chatRequest.getModel());
+            }
+        } else if (model.startsWith("gpt-4-gizmo")) {
+            chatRequest.setModel("gpt-4-gizmo");
+        }
+    }
+
+    /**
+     *  鏋勫缓娑堟伅鍒楄〃
+     */
+    private void buildChatMessageList(ChatRequest chatRequest){
+        // 鑾峰彇瀵硅瘽娑堟伅鍒楄〃
+        List<Message> messages = chatRequest.getMessages();
+        // 璁剧疆绯荤粺榛樿鎻愮ず璇�
+        Message sysMessage = Message.builder().content(chatRequest.getSysPrompt()).role(Message.Role.SYSTEM).build();
+        messages.add(0,sysMessage);
+
+        // 鏌ヨ鍚戦噺搴撶浉鍏充俊鎭姞鍏ュ埌涓婁笅鏂�
+        if(chatRequest.getKid()!=null){
+            List<Message> knMessages = new ArrayList<>();
+            String content = messages.get(messages.size() - 1).getContent().toString();
+            List<String> nearestList;
+            List<Double> queryVector = embeddingService.getQueryVector(content, chatRequest.getKid());
+            nearestList = vectorStore.nearest(queryVector, chatRequest.getKid());
+            for (String prompt : nearestList) {
+                Message userMessage = Message.builder().content(prompt).role(Message.Role.USER).build();
+                knMessages.add(userMessage);
+            }
+            Message userMessage = Message.builder().content(content + (!nearestList.isEmpty() ? "\n\n娉ㄦ剰锛氬洖绛旈棶棰樻椂锛岄』涓ユ牸鏍规嵁鎴戠粰浣犵殑绯荤粺涓婁笅鏂囧唴瀹瑰師鏂囪繘琛屽洖绛旓紝璇蜂笉瑕佽嚜宸卞彂鎸�,鍥炵瓟鏃朵繚鎸佸師鏉ユ枃鏈殑娈佃惤灞傜骇" : "")).role(Message.Role.USER).build();
+            knMessages.add(userMessage);
+            messages.addAll(knMessages);
+        }
+        // 鐢ㄦ埛瀵硅瘽鍐呭
+        String chatString = null;
+        // 鑾峰彇鐢ㄦ埛瀵硅瘽淇℃伅
+        Object content = messages.get(messages.size() - 1).getContent();
+        if (content instanceof List<?> listContent) {
+            if (CollectionUtil.isNotEmpty(listContent)) {
+                chatString = listContent.get(0).toString();
+            }
+        } else if (content instanceof String) {
+            chatString = (String) content;
+        }
+        // 璁剧疆瀵硅瘽淇℃伅
+        chatRequest.setPrompt(chatString);
+        // 鍔犺浇鑱旂綉淇℃伅
+        if(chatRequest.getSearch()){
+            Message message = Message.builder().role(Message.Role.ASSISTANT).content("鑱旂綉淇℃伅:"+webSearch(chatString)).build();
+            messages.add(message);
+        }
+    }
 
     /**
      * 鍙戦�丼SE閿欒浜嬩欢鐨勫皝瑁呮柟娉�
@@ -295,13 +325,13 @@
 
     @Override
     public SseEmitter ollamaChat(ChatRequest chatRequest) {
-        String[] parts = chatRequest.getModel().split("ollama-");
+
         ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
         final SseEmitter emitter = new SseEmitter();
         String host = chatModelVo.getApiHost();
         List<Message> msgList = chatRequest.getMessages();
-        List<OllamaChatMessage> messages = new ArrayList<>();
 
+        List<OllamaChatMessage> messages = new ArrayList<>();
         for (Message message : msgList) {
             OllamaChatMessage ollamaChatMessage = new OllamaChatMessage();
             ollamaChatMessage.setRole(OllamaChatMessageRole.USER);
@@ -310,7 +340,7 @@
         }
         OllamaAPI api = new OllamaAPI(host);
         api.setRequestTimeoutSeconds(100);
-        OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(parts[1]);
+        OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(chatRequest.getModel());
 
         OllamaChatRequestModel requestModel = builder
             .withMessages(messages)
@@ -356,11 +386,11 @@
 
     @Override
     public String webSearch (String prompt) {
-        String zhipuValue = configService.getConfigValue("zhipu", "key");
-        if(StringUtils.isEmpty(zhipuValue)){
-            throw new IllegalStateException("zhipu config value is empty,璇峰湪chat_config涓厤缃畓hipu key淇℃伅");
+        String zpValue = configService.getConfigValue("zhipu", "key");
+        if(StringUtils.isEmpty(zpValue)){
+            throw new IllegalStateException("璇峰湪chat_config涓厤缃櫤璋眐ey淇℃伅");
         }else {
-            ClientV4 client = new ClientV4.Builder(zhipuValue)
+            ClientV4 client = new ClientV4.Builder(zpValue)
                     .networkConfig(300, 100, 100, 100, TimeUnit.SECONDS)
                     .connectionPool(new okhttp3.ConnectionPool(8, 1, TimeUnit.SECONDS))
                     .build();

--
Gitblit v1.9.3