Bladeren bron

add chat sources info for knowledges

tycoding 1 jaar geleden
bovenliggende
commit
3ea85b6a58

+ 4 - 3
langchat-common/src/main/java/cn/tycoding/langchat/common/dto/ChatRes.java

@@ -19,7 +19,8 @@ package cn.tycoding.langchat.common.dto;
 import lombok.Data;
 import lombok.experimental.Accessors;
 
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -38,7 +39,7 @@ public class ChatRes {
 
     private long time;
 
-    private Map<String, Object> metadata = new HashMap<>();
+    private List<Map<String, Object>> metadata = new ArrayList<>();
 
     public ChatRes(String message) {
         this.message = message;
@@ -50,7 +51,7 @@ public class ChatRes {
         this.time = System.currentTimeMillis() - startTime;
     }
 
-    public ChatRes(Integer usedToken, long startTime, Map<String, Object> metadata) {
+    public ChatRes(Integer usedToken, long startTime, List<Map<String, Object>> metadata) {
         this.isDone = true;
         this.usedToken = usedToken;
         this.time = System.currentTimeMillis() - startTime;

+ 7 - 7
langchat-core/src/main/java/cn/tycoding/langchat/core/service/impl/EmbeddingStoreContentRetrieverCustom.java

@@ -16,7 +16,6 @@
 
 package cn.tycoding.langchat.core.service.impl;
 
-import dev.langchain4j.data.document.Metadata;
 import dev.langchain4j.data.embedding.Embedding;
 import dev.langchain4j.data.segment.TextSegment;
 import dev.langchain4j.model.embedding.EmbeddingModel;
@@ -31,10 +30,7 @@ import dev.langchain4j.store.embedding.EmbeddingStore;
 import dev.langchain4j.store.embedding.filter.Filter;
 import lombok.Builder;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.function.Function;
 
 import static dev.langchain4j.internal.Utils.getOrDefault;
@@ -150,12 +146,16 @@ public class EmbeddingStoreContentRetrieverCustom implements ContentRetriever {
         return builder().embeddingStore(embeddingStore).build();
     }
 
-    public static Metadata getMetadata(String memoryId) {
+    public static List<Map<String, Object>> getMetadata(String memoryId) {
         List<EmbeddingMatch<TextSegment>> sources = sourceMap.get(memoryId);
         if (sources == null || sources.isEmpty()) {
             return null;
         }
-        return sources.stream().findFirst().get().embedded().metadata();
+        List<Map<String, Object>> list = new ArrayList<>();
+        sources.forEach(i -> {
+            list.add(i.embedded().metadata().toMap());
+        });
+        return list;
     }
 
     @Override

+ 5 - 3
langchat-server/src/main/java/cn/tycoding/langchat/server/service/impl/ChatServiceImpl.java

@@ -29,13 +29,15 @@ import cn.tycoding.langchat.common.utils.StreamEmitter;
 import cn.tycoding.langchat.core.service.LangChatService;
 import cn.tycoding.langchat.core.service.impl.EmbeddingStoreContentRetrieverCustom;
 import cn.tycoding.langchat.server.service.ChatService;
-import dev.langchain4j.data.document.Metadata;
 import dev.langchain4j.model.output.TokenUsage;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * @author tycoding
  * @since 2024/1/4
@@ -75,10 +77,10 @@ public class ChatServiceImpl implements ChatService {
                     })
                     .onComplete((e) -> {
                         TokenUsage tokenUsage = e.tokenUsage();
-                        Metadata metadata = EmbeddingStoreContentRetrieverCustom.getMetadata(req.getConversationId());
+                        List<Map<String, Object>> metadata = EmbeddingStoreContentRetrieverCustom.getMetadata(req.getConversationId());
                         ChatRes res = new ChatRes(tokenUsage.totalTokenCount(), startTime);
                         if (metadata != null) {
-                            res.setMetadata(metadata.toMap());
+                            res.setMetadata(metadata);
                         }
                         emitter.send(res);
                         emitter.complete();

+ 26 - 11
langchat-ui/src/views/chat/Chat.vue

@@ -208,17 +208,27 @@
             v-if="chatStore.metadata != null && chatStore.metadata.length != 0"
             class="w-fit ml-10"
           >
-            <div
-              class="bg-[#f4f6f8] rounded-lg p-2 flex px-4 text-[12px] items-center gap-1 text-gray-500"
-            >
-              <SvgIcon class="text-blue-500 text-[14px]" icon="mingcute:document-2-fill" />
-              <span>引用知识库:</span>
-              <div class="flex items-center gap-2">
-                <span class="hover:bg-gray-200 cursor-pointer rounded-lg">
-                  {{ chatStore.metadata.docsName }}
-                </span>
-              </div>
-            </div>
+            <n-collapse class="bg-[#f4f6f8] rounded-lg px-3 py-0.5 min-collapse pr-4">
+              <n-collapse-item>
+                <template #header>
+                  <div class="text-[12px] text-gray-500 p-2 pl-0 flex items-center gap-1">
+                    <SvgIcon class="text-blue-500 text-[14px]" icon="mingcute:document-2-fill" />
+                    <span>引用知识库文档:{{ chatStore.metadata.length }}条</span>
+                  </div>
+                </template>
+                <div class="pb-2">
+                  <div class="flex flex-col gap-2">
+                    <div
+                      v-for="item in chatStore.metadata"
+                      :key="item"
+                      class="!bg-gray-200 rounded hover:bg-gray-300 cursor-pointer p-2 px-3"
+                    >
+                      {{ item.docsName }}
+                    </div>
+                  </div>
+                </div>
+              </n-collapse-item>
+            </n-collapse>
           </div>
         </div>
       </div>
@@ -269,4 +279,9 @@
       padding-right: 6px !important;
     }
   }
+  ::v-deep(.min-collapse) {
+    .n-collapse-item__content-inner {
+      padding-top: 0 !important;
+    }
+  }
 </style>