.editorconfig
ÎļþÒÑɾ³ý ruoyi-admin/src/main/java/org/ruoyi/controller/KnowledgeController.java
@@ -81,7 +81,7 @@ List<Message> messages = chatRequest.getMessages(); String content = messages.get(messages.size() - 1).getContent().toString(); List<String> nearestList; List<Double> queryVector = embeddingService.getQueryVector(content); List<Double> queryVector = embeddingService.getQueryVector(content, chatRequest.getKid()); nearestList = vectorStore.nearest(queryVector,chatRequest.getKid()); for (String prompt : nearestList) { Message sysMessage = Message.builder().content(prompt).role(Message.Role.USER).build(); ruoyi-admin/src/main/resources/application-dev.yml
@@ -27,7 +27,7 @@ driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://43.139.70.230:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true username: ruoyi-ai password: ruoyi-ai password: eCaZ278N62k6fhYj hikari: # æå¤§è¿æ¥æ± æ°é ruoyi-admin/src/main/resources/application.yml
@@ -310,11 +310,6 @@ # ä¼ä¸å¾®ä¿¡åºç¨ wechat: # æ¯å¦ä½¿ç¨å¾®ä¿¡ true/false enable: true # çæçç»å½äºç»´ç è·¯å¾ é»è®¤ä¸é¡¹ç®å级 qrPath: "./" # ä¼ä¸å¾®ä¿¡åºç¨ cp: corpId: appConfigs: @@ -323,28 +318,5 @@ token: '' aesKey: '' # ç¥è¯åºé ç½® chain: split: chunk: endspliter: "<STOP>" # ååææ¬å¤§å° size: 200 overlay: 30 qaspliter: "###" # ç¥è¯åºä¸æ£ç´¢çæ¡æ° limits: 5 vector: model: 'text-embedding-3-small' store: type: weaviate weaviate: protocol: http host: 127.0.0.1:6038 classname: LocalKnowledge milvus: host: 127.0.0.1 port: 19530 dimension: 1536 collection: LocalKnowledge ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/CodeFileLoader.java
@@ -31,7 +31,7 @@ return stringBuffer.toString(); } @Override public List<String> getChunkList(String content){ return textSplitter.split(content); public List<String> getChunkList(String content, String kid){ return textSplitter.split(content, kid); } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/CsvFileLoader.java
@@ -10,7 +10,7 @@ } @Override public List<String> getChunkList(String content) { public List<String> getChunkList(String content, String kid) { return null; } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/FolderLoader.java
@@ -10,7 +10,7 @@ } @Override public List<String> getChunkList(String content) { public List<String> getChunkList(String content, String kid) { return null; } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/GithubLoader.java
@@ -10,7 +10,7 @@ } @Override public List<String> getChunkList(String content) { public List<String> getChunkList(String content, String kid) { return null; } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/JsonFileLoader.java
@@ -10,7 +10,7 @@ } @Override public List<String> getChunkList(String content) { public List<String> getChunkList(String content, String kid) { return null; } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/MarkDownFileLoader.java
@@ -31,7 +31,7 @@ return stringBuffer.toString(); } @Override public List<String> getChunkList(String content){ return textSplitter.split(content); public List<String> getChunkList(String content, String kid){ return textSplitter.split(content, kid); } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/PdfFileLoader.java
@@ -28,7 +28,7 @@ } @Override public List<String> getChunkList(String content) { return characterTextSplitter.split(content); public List<String> getChunkList(String content, String kid) { return characterTextSplitter.split(content, kid); } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/ResourceLoader.java
@@ -7,6 +7,8 @@ * èµæºè½½å ¥ */ public interface ResourceLoader { String getContent(InputStream inputStream); List<String> getChunkList(String content); List<String> getChunkList(String content, String kid); } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/TextFileLoader.java
@@ -31,7 +31,7 @@ return stringBuffer.toString(); } @Override public List<String> getChunkList(String content){ return textSplitter.split(content); public List<String> getChunkList(String content, String kid){ return textSplitter.split(content, kid); } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/loader/WordLoader.java
@@ -30,8 +30,8 @@ } @Override public List<String> getChunkList(String content) { return textSplitter.split(content); public List<String> getChunkList(String content, String kid) { return textSplitter.split(content, kid); } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/retrieve/PromptRetrieverProperties.java
ÎļþÒÑɾ³ý ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/split/CharacterTextSplitter.java
@@ -1,7 +1,10 @@ package org.ruoyi.knowledge.chain.split; import lombok.AllArgsConstructor; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; import org.ruoyi.knowledge.service.IKnowledgeInfoService; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -10,38 +13,46 @@ import java.util.List; @Component @AllArgsConstructor @Slf4j @Primary public class CharacterTextSplitter implements TextSplitter{ private final SplitterProperties splitterProperties; public class CharacterTextSplitter implements TextSplitter { @Lazy @Resource private IKnowledgeInfoService knowledgeInfoService; @Override public List<String> split(String content) { public List<String> split(String content, String kid) { // ä»ç¥è¯åºè¡¨ä¸è·åé ç½® KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid)); String knowledgeSeparator = knowledgeInfoVo.getKnowledgeSeparator(); int textBlockSize = knowledgeInfoVo.getTextBlockSize(); int overlapChar = knowledgeInfoVo.getOverlapChar(); List<String> chunkList = new ArrayList<>(); if (content.contains(splitterProperties.getEndspliter())){ if (content.contains(knowledgeSeparator)) { // æèªå®ä¹åé符åå String[] chunks = content.split(splitterProperties.getEndspliter()); String[] chunks = content.split(knowledgeSeparator); chunkList.addAll(Arrays.asList(chunks)); }else { } else { int indexMin = 0; int len = content.length(); int i = 0; int right = 0; while (true) { if (len > right ){ int begin = i*splitterProperties.getSize() - splitterProperties.getOverlay(); if (begin < indexMin){ if (len > right) { int begin = i * textBlockSize - overlapChar; if (begin < indexMin) { begin = indexMin; } int end = splitterProperties.getSize()*(i+1) + splitterProperties.getOverlay(); if (end > len){ int end = textBlockSize * (i + 1) + overlapChar; if (end > len) { end = len; } String chunk = content.substring(begin,end); String chunk = content.substring(begin, end); chunkList.add(chunk); i++; right = right + splitterProperties.getSize(); }else { right = right + textBlockSize; } else { break; } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/split/CodeTextSplitter.java
@@ -11,7 +11,7 @@ @Slf4j public class CodeTextSplitter implements TextSplitter{ @Override public List<String> split(String content) { public List<String> split(String content, String kid) { return null; } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/split/MarkdownTextSplitter.java
@@ -11,7 +11,7 @@ @Slf4j public class MarkdownTextSplitter implements TextSplitter{ @Override public List<String> split(String content) { public List<String> split(String content, String kid) { return null; } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/split/SplitterProperties.java
ÎļþÒÑɾ³ý ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/split/TextSplitter.java
@@ -7,5 +7,12 @@ */ public interface TextSplitter { List<String> split(String content); /** * ææ¬åå * * @param content ææ¬å 容 * @param kid ç¥è¯åºid * @return åååçææ¬å表 */ List<String> split(String content, String kid); } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/split/TokenTextSplitter.java
@@ -11,7 +11,7 @@ @Slf4j public class TokenTextSplitter implements TextSplitter{ @Override public List<String> split(String content) { public List<String> split(String content, String kid) { return null; } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/vectorizer/OpenAiVectorization.java
@@ -1,5 +1,6 @@ package org.ruoyi.knowledge.chain.vectorizer; import jakarta.annotation.Resource; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -8,7 +9,10 @@ import org.ruoyi.common.chat.entity.embeddings.EmbeddingResponse; import org.ruoyi.common.chat.openai.OpenAiStreamClient; import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; import org.ruoyi.knowledge.service.IKnowledgeInfoService; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.math.BigDecimal; @@ -20,8 +24,9 @@ @RequiredArgsConstructor public class OpenAiVectorization implements Vectorization { @Value("${chain.vector.model}") private String embeddingModel; @Lazy @Resource private IKnowledgeInfoService knowledgeInfoService; @Getter private OpenAiStreamClient openAiStreamClient; @@ -29,12 +34,12 @@ private final ChatConfig chatConfig; @Override public List<List<Double>> batchVectorization(List<String> chunkList) { public List<List<Double>> batchVectorization(List<String> chunkList, String kid) { openAiStreamClient = chatConfig.getOpenAiStreamClient(); KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid)); Embedding embedding = Embedding.builder() .input(chunkList) .model(embeddingModel) .model(knowledgeInfoVo.getVectorModel()) .build(); EmbeddingResponse embeddings = openAiStreamClient.embeddings(embedding); List<List<Double>> vectorList = new ArrayList<>(); @@ -50,10 +55,10 @@ } @Override public List<Double> singleVectorization(String chunk) { public List<Double> singleVectorization(String chunk, String kid) { List<String> chunkList = new ArrayList<>(); chunkList.add(chunk); List<List<Double>> vectorList = batchVectorization(chunkList); List<List<Double>> vectorList = batchVectorization(chunkList, kid); return vectorList.get(0); } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/vectorizer/Vectorization.java
@@ -6,6 +6,7 @@ * åéå */ public interface Vectorization { List<List<Double>> batchVectorization(List<String> chunkList); List<Double> singleVectorization(String chunk); List<List<Double>> batchVectorization(List<String> chunkList, String kid); List<Double> singleVectorization(String chunk, String kid); } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/vectorizer/VectorizationWrapper.java
@@ -15,14 +15,14 @@ private final VectorizationFactory vectorizationFactory; @Override public List<List<Double>> batchVectorization(List<String> chunkList) { public List<List<Double>> batchVectorization(List<String> chunkList, String kid) { Vectorization embedding = vectorizationFactory.getEmbedding(); return embedding.batchVectorization(chunkList); return embedding.batchVectorization(chunkList, kid); } @Override public List<Double> singleVectorization(String chunk) { public List<Double> singleVectorization(String chunk, String kid) { Vectorization embedding = vectorizationFactory.getEmbedding(); return embedding.singleVectorization(chunk); return embedding.singleVectorization(chunk, kid); } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/vectorstore/MilvusVectorStore.java
@@ -19,8 +19,10 @@ import io.milvus.response.QueryResultsWrapper; import io.milvus.response.SearchResultsWrapper; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.ruoyi.common.core.service.ConfigService; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -32,26 +34,27 @@ @Slf4j public class MilvusVectorStore implements VectorStore{ @Value("${chain.vector.store.milvus.host}") private String milvusHost; @Value("${chain.vector.store.milvus.port}") private Integer milvausPort; @Value("${chain.vector.store.milvus.dimension}") private Integer dimension; @Value("${chain.vector.store.milvus.collection}") private String collectionName; private volatile Integer dimension; private volatile String collectionName; private MilvusServiceClient milvusServiceClient; @Resource private ConfigService configService; @PostConstruct public void loadConfig() { this.dimension = Integer.parseInt(configService.getConfigValue("milvus", "dimension")); this.collectionName = configService.getConfigValue("milvus", "collection"); } @PostConstruct public void init(){ String milvusHost = configService.getConfigValue("milvus", "host"); String milvausPort = configService.getConfigValue("milvus", "port"); milvusServiceClient = new MilvusServiceClient( ConnectParam.newBuilder() .withHost(milvusHost) .withPort(milvausPort) .withPort(Integer.parseInt(milvausPort)) .withDatabaseName("default") .build() ); ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/vectorstore/VectorStoreFactory.java
@@ -1,29 +1,37 @@ package org.ruoyi.knowledge.chain.vectorstore; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.ruoyi.knowledge.domain.KnowledgeInfo; import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; import org.ruoyi.knowledge.mapper.KnowledgeInfoMapper; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.List; import java.util.Map; @Component @Slf4j @RequiredArgsConstructor public class VectorStoreFactory { @Value("${chain.vector.store.type}") private String type; private final WeaviateVectorStore weaviateVectorStore; private final MilvusVectorStore milvusVectorStore; public VectorStoreFactory(WeaviateVectorStore weaviateVectorStore, MilvusVectorStore milvusVectorStore) { this.weaviateVectorStore = weaviateVectorStore; this.milvusVectorStore = milvusVectorStore; } private final KnowledgeInfoMapper knowledgeInfoMapper; public VectorStore getVectorStore(){ if ("weaviate".equals(type)){ public VectorStore getVectorStore(String kid){ KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoMapper.selectVoOne( new LambdaQueryWrapper<KnowledgeInfo>().eq(KnowledgeInfo::getKid,kid) ); String vectorModel = knowledgeInfoVo.getVector(); if ("weaviate".equals(vectorModel)){ return weaviateVectorStore; }else if ("milvus".equals(type)){ }else if ("milvus".equals(vectorModel)){ return milvusVectorStore; } return null; ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/vectorstore/VectorStoreWrapper.java
@@ -16,43 +16,43 @@ private final VectorStoreFactory vectorStoreFactory; @Override public void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList, String kid, String docId, List<String> fidList) { VectorStore vectorStore = vectorStoreFactory.getVectorStore(); VectorStore vectorStore = vectorStoreFactory.getVectorStore(kid); vectorStore.storeEmbeddings(chunkList, vectorList, kid, docId, fidList); } @Override public void removeByDocId(String kid, String docId) { VectorStore vectorStore = vectorStoreFactory.getVectorStore(); VectorStore vectorStore = vectorStoreFactory.getVectorStore(kid); vectorStore.removeByDocId(kid,docId); } @Override public void removeByKid(String kid) { VectorStore vectorStore = vectorStoreFactory.getVectorStore(); VectorStore vectorStore = vectorStoreFactory.getVectorStore(kid); vectorStore.removeByKid(kid); } @Override public List<String> nearest(List<Double> queryVector, String kid) { VectorStore vectorStore = vectorStoreFactory.getVectorStore(); VectorStore vectorStore = vectorStoreFactory.getVectorStore(kid); return vectorStore.nearest(queryVector,kid); } @Override public List<String> nearest(String query, String kid) { VectorStore vectorStore = vectorStoreFactory.getVectorStore(); VectorStore vectorStore = vectorStoreFactory.getVectorStore(kid); return vectorStore.nearest(query, kid); } @Override public void newSchema(String kid) { VectorStore vectorStore = vectorStoreFactory.getVectorStore(); VectorStore vectorStore = vectorStoreFactory.getVectorStore(kid); vectorStore.newSchema(kid); } @Override public void removeByKidAndFid(String kid, String fid) { VectorStore vectorStore = vectorStoreFactory.getVectorStore(); VectorStore vectorStore = vectorStoreFactory.getVectorStore(kid); vectorStore.removeByKidAndFid(kid, fid); } } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/chain/vectorstore/WeaviateVectorStore.java
@@ -22,10 +22,15 @@ import io.weaviate.client.v1.schema.model.Property; import io.weaviate.client.v1.schema.model.Schema; import io.weaviate.client.v1.schema.model.WeaviateClass; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.ruoyi.knowledge.chain.retrieve.PromptRetrieverProperties; import org.ruoyi.common.core.service.ConfigService; import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; import org.ruoyi.knowledge.service.IKnowledgeInfoService; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -37,18 +42,23 @@ @Slf4j public class WeaviateVectorStore implements VectorStore{ @Value("${chain.vector.store.weaviate.protocol}") private String protocol; @Value("${chain.vector.store.weaviate.host}") private String host; private volatile String protocol; private volatile String host; private volatile String className; @Value("${chain.vector.store.weaviate.classname}") private String className; @Lazy @Resource private IKnowledgeInfoService knowledgeInfoService; private final PromptRetrieverProperties promptRetrieverProperties; @Lazy @Resource private ConfigService configService; public WeaviateVectorStore(PromptRetrieverProperties promptRetrieverProperties) { this.promptRetrieverProperties = promptRetrieverProperties; @PostConstruct public void loadConfig() { this.protocol = configService.getConfigValue("weaviate", "protocol"); this.host = configService.getConfigValue("weaviate", "host"); this.className = configService.getConfigValue("weaviate", "classname"); } public WeaviateClient getClient(){ @@ -309,11 +319,12 @@ .vector(vf) .distance(1.6f) // certainty = 1f - distance /2f .build(); KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid)); Result<GraphQLResponse> result = client.graphQL().get() .withClassName(className + kid) .withFields(contentField,_additional) .withNearVector(nearVector) .withLimit(promptRetrieverProperties.getLimits()) .withLimit(knowledgeInfoVo.getRetrieveLimit()) .run(); LinkedTreeMap<String,Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData(); LinkedTreeMap<String,ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get"); @@ -342,12 +353,12 @@ .concepts(new String[]{ query }) .distance(1.6f) // certainty = 1f - distance /2f .build(); KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid)); Result<GraphQLResponse> result = client.graphQL().get() .withClassName(className + kid) .withFields(contentField,_additional) .withNearText(nearText) .withLimit(promptRetrieverProperties.getLimits()) .withLimit(knowledgeInfoVo.getRetrieveLimit()) .run(); LinkedTreeMap<String,Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData(); LinkedTreeMap<String,ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get"); ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/domain/KnowledgeInfo.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import jakarta.validation.constraints.NotBlank; import lombok.Data; import java.io.Serial; @@ -44,6 +45,11 @@ private String kname; /** * ç¥è¯åºåç§° */ private String share; /** * æè¿° */ private String description; @@ -59,5 +65,38 @@ */ private Date createTime; /** * ç¥è¯åé符 */ private String knowledgeSeparator; /** * æé®åé符 */ private String questionSeparator; /** * éå åç¬¦æ° */ private Integer overlapChar; /** * ç¥è¯åºä¸æ£ç´¢çæ¡æ° */ private Integer retrieveLimit; /** * ææ¬åå¤§å° */ private Integer textBlockSize; /** * åéåº */ private String vector; /** * å鿍¡å */ private String vectorModel; } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/domain/bo/KnowledgeInfoBo.java
@@ -44,10 +44,56 @@ private String kname; /** * ç¥è¯åºåç§° */ @NotBlank(message = "æ¯å¦å ¬å¼ç¥è¯åº") private String share; /** * æè¿° */ @NotBlank(message = "æè¿°ä¸è½ä¸ºç©º") private String description; /** * ç¥è¯åé符 */ @NotBlank(message = "ç¥è¯åé符ä¸è½ä¸ºç©º") private String knowledgeSeparator; /** * æé®åé符 */ @NotBlank(message = "æé®åé符ä¸è½ä¸ºç©º") private String questionSeparator; /** * éå åç¬¦æ° */ @NotNull(message = "éå å符æ°ä¸è½ä¸ºç©º") private Integer overlapChar; /** * ç¥è¯åºä¸æ£ç´¢çæ¡æ° */ @NotNull(message = "ç¥è¯åºä¸æ£ç´¢çæ¡æ°ä¸è½ä¸ºç©º") private Integer retrieveLimit; /** * ææ¬åå¤§å° */ @NotNull(message = "ææ¬å大å°ä¸è½ä¸ºç©º") private Integer textBlockSize; /** * åéåº */ @NotBlank(message = "åéåºä¸è½ä¸ºç©º") private String vector; /** * å鿍¡å */ @NotBlank(message = "å鿍¡åä¸è½ä¸ºç©º") private String vectorModel; } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/domain/vo/KnowledgeInfoVo.java
@@ -48,10 +48,55 @@ private String kname; /** * ç¥è¯åºåç§° */ private String share; /** * æè¿° */ @ExcelProperty(value = "æè¿°") private String description; /** * ç¥è¯åé符 */ @ExcelProperty(value = "ç¥è¯åé符") private String knowledgeSeparator; /** * æé®åé符 */ @ExcelProperty(value = "æé®åé符") private String questionSeparator; /** * éå åç¬¦æ° */ @ExcelProperty(value = "éå å符æ°") private Integer overlapChar; /** * ç¥è¯åºä¸æ£ç´¢çæ¡æ° */ @ExcelProperty(value = "ç¥è¯åºä¸æ£ç´¢çæ¡æ°") private Integer retrieveLimit; /** * ææ¬åå¤§å° */ @ExcelProperty(value = "ææ¬å大å°") private Integer textBlockSize; /** * åéåº */ @ExcelProperty(value = "åéåº") private String vector; /** * å鿍¡å */ @ExcelProperty(value = "å鿍¡å") private String vectorModel; } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/service/EmbeddingService.java
@@ -10,7 +10,7 @@ void removeByKid(String kid); List<Double> getQueryVector(String query); List<Double> getQueryVector(String query, String kid); void createSchema(String kid); ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/service/IKnowledgeInfoService.java
@@ -55,4 +55,10 @@ * å é¤ç¥è¯åº */ void removeKnowledge(String id); /** * æ£æ¥æ¯å¦æå 餿é * @param knowledgeInfoList ç¥è¯å表 */ void check(List<KnowledgeInfoVo> knowledgeInfoList); } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/service/impl/EmbeddingServiceImpl.java
@@ -24,7 +24,7 @@ */ @Override public void storeEmbeddings(List<String> chunkList, String kid, String docId,List<String> fidList) { List<List<Double>> vectorList = vectorization.batchVectorization(chunkList); List<List<Double>> vectorList = vectorization.batchVectorization(chunkList, kid); vectorStore.storeEmbeddings(chunkList,vectorList,kid,docId,fidList); } @@ -39,8 +39,8 @@ } @Override public List<Double> getQueryVector(String query) { List<Double> queryVector = vectorization.singleVectorization(query); public List<Double> getQueryVector(String query, String kid) { List<Double> queryVector = vectorization.singleVectorization(query,kid); return queryVector; } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/service/impl/KnowledgeAttachServiceImpl.java
@@ -4,16 +4,21 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.ruoyi.common.core.domain.model.LoginUser; import org.ruoyi.common.core.utils.MapstructUtils; import org.ruoyi.common.core.utils.StringUtils; import org.ruoyi.common.mybatis.core.page.PageQuery; import org.ruoyi.common.mybatis.core.page.TableDataInfo; import org.ruoyi.common.satoken.utils.LoginHelper; import org.ruoyi.knowledge.domain.KnowledgeAttach; import org.ruoyi.knowledge.domain.bo.KnowledgeAttachBo; import org.ruoyi.knowledge.domain.vo.KnowledgeAttachVo; import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; import org.ruoyi.knowledge.mapper.KnowledgeAttachMapper; import org.ruoyi.knowledge.mapper.KnowledgeFragmentMapper; import org.ruoyi.knowledge.mapper.KnowledgeInfoMapper; import org.ruoyi.knowledge.service.IKnowledgeAttachService; import org.ruoyi.knowledge.service.IKnowledgeInfoService; import org.springframework.stereotype.Service; import java.util.Collection; @@ -34,6 +39,11 @@ private final KnowledgeAttachMapper baseMapper; private final KnowledgeFragmentMapper fragmentMapper; private final KnowledgeInfoMapper knowledgeInfoMapper; private final IKnowledgeInfoService knowledgeInfoService; /** * æ¥è¯¢ç¥è¯åºéä»¶ @@ -117,8 +127,12 @@ @Override public void removeKnowledgeAttach(String kid) { HashMap<String, Object> map = new HashMap<>(); map.put("kid", kid); LoginUser loginUser = LoginHelper.getLoginUser(); Map<String,Object> map = new HashMap<>(); map.put("kid",kid); List<KnowledgeInfoVo> knowledgeInfoList = knowledgeInfoMapper.selectVoByMap(map); knowledgeInfoService.check(knowledgeInfoList); baseMapper.deleteByMap(map); fragmentMapper.deleteByMap(map); } ruoyi-modules/ruoyi-knowledge/src/main/java/org/ruoyi/knowledge/service/impl/KnowledgeInfoServiceImpl.java
@@ -1,16 +1,16 @@ package org.ruoyi.knowledge.service.impl; import cn.hutool.core.util.RandomUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.github.ollama4j.OllamaAPI; import io.github.ollama4j.exceptions.OllamaBaseException; import io.github.ollama4j.models.chat.OllamaChatMessageRole; import io.github.ollama4j.models.chat.OllamaChatRequestBuilder; import io.github.ollama4j.models.chat.OllamaChatRequestModel; import io.github.ollama4j.models.chat.OllamaChatResult; import lombok.RequiredArgsConstructor; import org.ruoyi.common.core.domain.model.LoginUser; import org.ruoyi.common.core.utils.MapstructUtils; import org.ruoyi.common.core.utils.StringUtils; import org.ruoyi.common.mybatis.core.page.PageQuery; @@ -21,8 +21,6 @@ import org.ruoyi.knowledge.domain.KnowledgeAttach; import org.ruoyi.knowledge.domain.KnowledgeFragment; import org.ruoyi.knowledge.domain.KnowledgeInfo; import org.ruoyi.knowledge.domain.bo.KnowledgeAttachBo; import org.ruoyi.knowledge.domain.bo.KnowledgeFragmentBo; import org.ruoyi.knowledge.domain.bo.KnowledgeInfoBo; import org.ruoyi.knowledge.domain.req.KnowledgeInfoUploadRequest; import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; @@ -30,14 +28,11 @@ import org.ruoyi.knowledge.mapper.KnowledgeFragmentMapper; import org.ruoyi.knowledge.mapper.KnowledgeInfoMapper; import org.ruoyi.knowledge.service.EmbeddingService; import org.ruoyi.knowledge.service.IKnowledgeAttachService; import org.ruoyi.knowledge.service.IKnowledgeFragmentService; import org.ruoyi.knowledge.service.IKnowledgeInfoService; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.time.LocalDateTime; import java.util.*; /** @@ -88,12 +83,13 @@ } private LambdaQueryWrapper<KnowledgeInfo> buildQueryWrapper(KnowledgeInfoBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery(); lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeInfo::getKid, bo.getKid()); lqw.eq(bo.getUid() != null, KnowledgeInfo::getUid, bo.getUid()); lqw.like(StringUtils.isNotBlank(bo.getKname()), KnowledgeInfo::getKname, bo.getKname()); lqw.eq(StringUtils.isNotBlank(bo.getDescription()), KnowledgeInfo::getDescription, bo.getDescription()); // æ¥è¯¢å ¬å¼çç¥è¯åº lqw.or(wrapper -> wrapper.eq(KnowledgeInfo::getShare, "1")); return lqw; } @@ -151,7 +147,7 @@ List<String> fids = new ArrayList<>(); try { content = resourceLoader.getContent(file.getInputStream()); chunkList = resourceLoader.getChunkList(content); chunkList = resourceLoader.getChunkList(content, kid); for (int i = 0; i < chunkList.size(); i++) { String fid = RandomUtil.randomString(16); fids.add(fid); @@ -179,6 +175,8 @@ Map<String,Object> map = new HashMap<>(); map.put("kid",id); List<KnowledgeInfoVo> knowledgeInfoList = baseMapper.selectVoByMap(map); check(knowledgeInfoList); // å é¤ç¥è¯åº baseMapper.deleteByMap(map); // å é¤éä»¶åç¥è¯ç段 @@ -188,31 +186,13 @@ embeddingService.removeByKid(id); } /** * å°ææ¬å转æ¢ä¸ºé¢è®ç»æ°æ® * @param chunk è§£æææ¬å */ public String convertTextBlockToPretrainData(String chunk){ String host = "http://localhost:11434/"; OllamaAPI ollama = new OllamaAPI(host); OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance("qwen2.5:7b"); // è®¾ç½®è¶ æ¶æ¶é´ ollama.setRequestTimeoutSeconds(100); // create first user question String json = "instruction:ç¨æ·æä»¤,æ ¹æ®è¯ä¹æåä¸ä¸ªå ³é®è¯;input:ç¨æ·è¾å ¥,æ ¹æ®è¯ä¹æåå¤ä¸ªå ³é®è¯;output:è¾åºææ¬å 容"; OllamaChatRequestModel requestModel = builder.withMessage (OllamaChatMessageRole.USER, "ææ¬ï¼"+chunk+"çè§£ææ¬å 容ï¼å¹¶ä¸å°ææ¬å 容转æ¢ä¸º:"+json+",è¾åºJSONæ ¼å¼ï¼ä¸è¦å å«å ¶ä»æ å ³å 容,å é¨ä½¿ç¨æ éè±æ") .build(); // start conversation with model OllamaChatResult chatResult = null; try { chatResult = ollama.chat(requestModel); } catch (Exception e) { System.out.println("è§£æå¤±è´¥!"); @Override public void check(List<KnowledgeInfoVo> knowledgeInfoList){ LoginUser loginUser = LoginHelper.getLoginUser(); for (KnowledgeInfoVo knowledgeInfoVo : knowledgeInfoList) { if(!knowledgeInfoVo.getUid().equals(loginUser.getUserId())){ throw new SecurityException("æéä¸è¶³"); } return chatResult.getResponse(); } } } ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/ChatConfigController.java
@@ -36,8 +36,8 @@ */ @GetMapping("/list") @SaCheckPermission("system:config:list") public List<ChatConfigVo> list(ChatConfigBo bo) { return chatConfigService.queryList(bo); public R<List<ChatConfigVo>> list(ChatConfigBo bo) { return R.ok(chatConfigService.queryList(bo)); } /** ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/request/translation/TranslationRequest.java
@@ -22,13 +22,8 @@ private String model; /** * æºè¯è¨ */ private String sourceLanguage; /** * ç®æ è¯è¨ */ private String targetLanguage; private String targetLanguage; } ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java
@@ -553,7 +553,21 @@ List<Message> messageList = new ArrayList<>(); Message sysMessage = Message.builder().role(Message.Role.SYSTEM).content("ä½ä¸ºè±æ±ç¿»è¯ï¼æ¨ç任塿¯åç¡®å°å¨ä¸¤ç§è¯è¨ä¹é´ç¿»è¯ææ¬ãç¿»è¯æ¶ï¼è¯·æ³¨æä¸ä¸æï¼å确解éæè¯åè°è¯ã妿è¿ç»æ¶å°å¤ä¸ªè±æåè¯ï¼è¯·é»è®¤å°å ¶ç¿»è¯æä¸æå¥åãä½å¦æå颿'phrase:âï¼ååºç¿»è¯ä¸ºçè¯;妿æ'norma!:'ï¼åç¿»è¯ä¸ºå¤ä¸ªæ å ³çåè¯ãæ¨çç¿»è¯åºæ¥è¿æ¯è¯è çæ°´å¹³ï¼å¹¶èèç¨æ·è¦æ±çç¹å®è¯è¨é£æ ¼æè¯æ°ãé¿å 使ç¨åç¯æ§è¯æ±ï¼å¿ è¦æ¶ç¨xæ¿æ¢ãæä¾ç¿»è¯æ¶ï¼è¯·ç¨ä¸æè§£éæ¯å¥è¯çæ¶æãä»å¥ã主è¯ãè°è¯ã宾è¯ãç¹æ®çè¯åè°è¯å¯¹äºéè¦ç¿»è¯ççè¯æåè¯ï¼è¯·æä¾æ¥æº(è¯å ¸)ãå¦æè¦æ±ç¿»è¯å¤ä¸ªçè¯ï¼è¯·ç¨|符å·åéã请记ä½:æ¨æ¯è±æ±ç¿»è¯ï¼ä¸æ¯æ±æ±ç¿»è¯æè±è±ç¿»è¯ãæäº¤å请ä»ç»æ£æ¥åä¿®è®¢çæ¡,å夿§å¶å¨50å以å ").build(); Message sysMessage = Message.builder().role(Message.Role.SYSTEM).content("ä½ æ¯ä¸åç¿»è¯èå¸\n" + "\n" + "请å°ç¨æ·è¾å ¥è¯è¯ç¿»è¯æ{" + translationRequest.getTargetLanguage() + "}\n" + "\n" + "让æä»¬ä¸æ¥ä¸æ¥æ¥æè\n" + "==示ä¾è¾åº==\n" + "**ç¿»è¯** : <è¿éæ¾ç¤ºç¿»è¯æè±è¯çç»æ>\n" + "\n" + "**é å¥** : What's the weather like today? Use the 'Weather Query' plugin to find out instantly! <é ä¸ä¸ªè±è¯å¥å>\n" + "\n" + "**åä¹è¯** : Add-onãExtensionãModule <è¿éæ¾ç¤º1-3ä¸ªè±æçåä¹è¯>\n" + "\n" + "==示ä¾ç»æ==\n" + "\n" + "注æï¼è¯·ä¸¥æ ¼æç¤ºä¾è¿è¡è¾åº").build(); messageList.add(sysMessage); Message message = Message.builder().role(Message.Role.USER).content(translationRequest.getPrompt()).build(); messageList.add(message); script/sql/update/update20250302.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1 @@ ALTER TABLE `knowledge_info` ADD COLUMN `share` tinyint(4) NULL DEFAULT NULL COMMENT 'æ¯å¦å ¬å¼ç¥è¯åºï¼0 å¦ 1æ¯ï¼' AFTER `kname`;