From 1a645c6e10e5cd830c70fad47b816f774613e821 Mon Sep 17 00:00:00 2001 From: ageerle <ageerle@163.com> Date: 星期三, 07 五月 2025 17:33:22 +0800 Subject: [PATCH] feat: 接入langchain4j操作向量库 --- /dev/null | 64 ------ ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/WeaviateVectorStoreImpl.java | 412 +++++++--------------------------------- ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java | 14 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/KnowledgeInfoServiceImpl.java | 12 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java | 10 ruoyi-modules-api/ruoyi-knowledge-api/pom.xml | 42 ++++ 6 files changed, 133 insertions(+), 421 deletions(-) diff --git a/ruoyi-modules-api/ruoyi-knowledge-api/pom.xml b/ruoyi-modules-api/ruoyi-knowledge-api/pom.xml index 27e2073..cb35d34 100644 --- a/ruoyi-modules-api/ruoyi-knowledge-api/pom.xml +++ b/ruoyi-modules-api/ruoyi-knowledge-api/pom.xml @@ -16,7 +16,20 @@ <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <langchain4j.version>1.0.0-beta4</langchain4j.version> </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-bom</artifactId> + <version>${langchain4j.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> <dependencies> @@ -47,6 +60,35 @@ <version>4.0.0</version> </dependency> + + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j</artifactId> + </dependency> + + + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-weaviate</artifactId> + </dependency> + + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId> + + </dependency> + + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>weaviate</artifactId> + <version>1.19.6</version> + </dependency> + + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId> + </dependency> + </dependencies> </project> diff --git a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/EmbeddingService.java b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/EmbeddingService.java deleted file mode 100644 index 9884118..0000000 --- a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/EmbeddingService.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.ruoyi.service; - -import java.util.List; - -public interface EmbeddingService { - - void storeEmbeddings(List<String> chunkList, String kid, String docId,List<String> fidList); - - void removeByDocId(String kid,String docId); - - void removeByKid(String kid); - - List<Double> getQueryVector(String query, String kid); - - void createSchema(String kid); - - void removeByKidAndFid(String kid, String fid); - - void saveFragment(String kid, String docId, String fid, String content); -} diff --git a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java index d3294bb..dbc1a9a 100644 --- a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java +++ b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java @@ -2,22 +2,18 @@ import java.util.List; -/** - * 鍚戦噺瀛樺偍 - */ public interface VectorStoreService { - void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList, String kid, String docId, List<String> fidList); + void storeEmbeddings(List<String> chunkList, String kid); - void removeByDocId(String kid, String docId); + void removeByDocId(String kid,String docId); void removeByKid(String kid); - List<String> nearest(List<Double> queryVector, String kid); + List<String> getQueryVector(String query, String kid); - List<String> nearest(String query, String kid); - - void newSchema(String kid); + void createSchema(String kid); void removeByKidAndFid(String kid, String fid); + } diff --git a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/EmbeddingServiceImpl.java b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/EmbeddingServiceImpl.java deleted file mode 100644 index 0065739..0000000 --- a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/EmbeddingServiceImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.ruoyi.service.impl; - -import lombok.AllArgsConstructor; -import org.ruoyi.service.EmbeddingService; -import org.ruoyi.service.VectorStoreService; -import org.ruoyi.service.VectorizationService; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.List; - -@Service -@AllArgsConstructor -public class EmbeddingServiceImpl implements EmbeddingService { - - private final VectorStoreService vectorStore; - private final VectorizationService vectorization; - - /** - * 淇濆瓨鍚戦噺鏁版嵁搴� - * @param chunkList 鏂囨。鎸夎鍒囧垎鐨勭墖娈� - * @param kid 鐭ヨ瘑搴揑D - * @param docId 鏂囨。ID - */ - @Override - public void storeEmbeddings(List<String> chunkList, String kid, String docId,List<String> fidList) { - List<List<Double>> vectorList = vectorization.batchVectorization(chunkList, kid); - vectorStore.storeEmbeddings(chunkList,vectorList,kid,docId,fidList); - } - - @Override - public void removeByDocId(String kid,String docId) { - vectorStore.removeByDocId(kid,docId); - } - - @Override - public void removeByKid(String kid) { - vectorStore.removeByKid(kid); - } - - @Override - public List<Double> getQueryVector(String query, String kid) { - return vectorization.singleVectorization(query,kid); - } - - @Override - public void createSchema(String kid) { - vectorStore.newSchema(kid); - } - - @Override - public void removeByKidAndFid(String kid, String fid) { - vectorStore.removeByKidAndFid(kid,fid); - } - - @Override - public void saveFragment(String kid, String docId, String fid, String content) { - List<String> chunkList = new ArrayList<>(); - List<String> fidList = new ArrayList<>(); - chunkList.add(content); - fidList.add(fid); - storeEmbeddings(chunkList,kid,docId,fidList); - } -} diff --git a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/WeaviateVectorStoreImpl.java b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/WeaviateVectorStoreImpl.java index 994bc72..ca3d6e7 100644 --- a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/WeaviateVectorStoreImpl.java +++ b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/WeaviateVectorStoreImpl.java @@ -1,37 +1,25 @@ package org.ruoyi.service.impl; -import cn.hutool.core.lang.UUID; -import cn.hutool.json.JSONObject; -import com.google.gson.internal.LinkedTreeMap; -import io.weaviate.client.Config; -import io.weaviate.client.WeaviateClient; -import io.weaviate.client.base.Result; -import io.weaviate.client.v1.data.model.WeaviateObject; -import io.weaviate.client.v1.data.replication.model.ConsistencyLevel; -import io.weaviate.client.v1.filters.Operator; -import io.weaviate.client.v1.filters.WhereFilter; -import io.weaviate.client.v1.graphql.model.GraphQLResponse; -import io.weaviate.client.v1.graphql.query.argument.NearTextArgument; -import io.weaviate.client.v1.graphql.query.argument.NearVectorArgument; -import io.weaviate.client.v1.graphql.query.fields.Field; -import io.weaviate.client.v1.misc.model.Meta; -import io.weaviate.client.v1.misc.model.ReplicationConfig; -import io.weaviate.client.v1.misc.model.ShardingConfig; -import io.weaviate.client.v1.misc.model.VectorIndexConfig; -import io.weaviate.client.v1.schema.model.DataType; -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 cn.hutool.core.util.RandomUtil; +import dev.langchain4j.data.embedding.Embedding; +import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.model.openai.OpenAiEmbeddingModel; +import dev.langchain4j.store.embedding.EmbeddingMatch; +import dev.langchain4j.store.embedding.EmbeddingSearchRequest; +import dev.langchain4j.store.embedding.EmbeddingStore; +import dev.langchain4j.store.embedding.filter.Filter; +import dev.langchain4j.store.embedding.filter.comparison.IsEqualTo; +import dev.langchain4j.store.embedding.weaviate.WeaviateEmbeddingStore; 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.ruoyi.domain.vo.KnowledgeInfoVo; -import org.ruoyi.service.IKnowledgeInfoService; import org.ruoyi.service.VectorStoreService; +import org.ruoyi.service.IKnowledgeInfoService; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import org.testcontainers.weaviate.WeaviateContainer; import java.util.ArrayList; import java.util.HashMap; @@ -54,6 +42,8 @@ @Resource private ConfigService configService; + private EmbeddingStore<TextSegment> embeddingStore; + @PostConstruct public void loadConfig() { this.protocol = configService.getConfigValue("weaviate", "protocol"); @@ -61,342 +51,94 @@ this.className = configService.getConfigValue("weaviate", "classname"); } - public WeaviateClient getClient() { - Config config = new Config(protocol, host); - WeaviateClient client = new WeaviateClient(config); - return client; - } - public Result<Meta> getMeta() { - WeaviateClient client = getClient(); - Result<Meta> meta = client.misc().metaGetter().run(); - if (meta.getError() == null) { - System.out.printf("meta.hostname: %s\n", meta.getResult().getHostname()); - System.out.printf("meta.version: %s\n", meta.getResult().getVersion()); - System.out.printf("meta.modules: %s\n", meta.getResult().getModules()); - } else { - System.out.printf("Error: %s\n", meta.getError().getMessages()); - } - return meta; - } - - public Result<Schema> getSchemas() { - WeaviateClient client = getClient(); - Result<Schema> result = client.schema().getter().run(); - if (result.hasErrors()) { - System.out.println(result.getError()); - } else { - System.out.println(result.getResult()); - } - return result; - } - - - public Result<Boolean> createSchema(String kid) { - WeaviateClient client = getClient(); - - VectorIndexConfig vectorIndexConfig = VectorIndexConfig.builder() - .distance("cosine") - .cleanupIntervalSeconds(300) - .efConstruction(128) - .maxConnections(64) - .vectorCacheMaxObjects(500000L) - .ef(-1) - .skip(false) - .dynamicEfFactor(8) - .dynamicEfMax(500) - .dynamicEfMin(100) - .flatSearchCutoff(40000) + @Override + public List<String> getQueryVector(String query, String kid) { + EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder() + .apiKey(System.getenv("OPENAI_API_KEY")) + .baseUrl(System.getenv("OPENAI_BASE_URL")) + .modelName("text-embedding-3-small") .build(); - ShardingConfig shardingConfig = ShardingConfig.builder() - .desiredCount(3) - .desiredVirtualCount(128) - .function("murmur3") - .key("_id") - .strategy("hash") - .virtualPerPhysical(128) + Filter simpleFilter = new IsEqualTo("kid", kid); + + Embedding queryEmbedding = embeddingModel.embed("What is your favourite sport?").content(); + EmbeddingSearchRequest embeddingSearchRequest = EmbeddingSearchRequest.builder() + .queryEmbedding(queryEmbedding) + .maxResults(3) + // 娣诲姞杩囨护鏉′欢 + .filter(simpleFilter) .build(); + List<EmbeddingMatch<TextSegment>> matches = embeddingStore.search(embeddingSearchRequest).matches(); - ReplicationConfig replicationConfig = ReplicationConfig.builder() - .factor(1) - .build(); + List<String> results = new ArrayList<>(); - JSONObject classModuleConfigValue = new JSONObject(); - classModuleConfigValue.put("vectorizeClassName", false); - JSONObject classModuleConfig = new JSONObject(); - classModuleConfig.put("text2vec-transformers", classModuleConfigValue); + matches.forEach(embeddingMatch -> { + results.add(embeddingMatch.embedded().text()); + }); - JSONObject propertyModuleConfigValueSkipTrue = new JSONObject(); - propertyModuleConfigValueSkipTrue.put("vectorizePropertyName", false); - propertyModuleConfigValueSkipTrue.put("skip", true); - JSONObject propertyModuleConfigSkipTrue = new JSONObject(); - propertyModuleConfigSkipTrue.put("text2vec-transformers", propertyModuleConfigValueSkipTrue); - - JSONObject propertyModuleConfigValueSkipFalse = new JSONObject(); - propertyModuleConfigValueSkipFalse.put("vectorizePropertyName", false); - propertyModuleConfigValueSkipFalse.put("skip", false); - JSONObject propertyModuleConfigSkipFalse = new JSONObject(); - propertyModuleConfigSkipFalse.put("text2vec-transformers", propertyModuleConfigValueSkipFalse); - - WeaviateClass clazz = WeaviateClass.builder() - .className(className + kid) - .description("local knowledge") - .vectorIndexType("hnsw") - .vectorizer("text2vec-transformers") - .shardingConfig(shardingConfig) - .vectorIndexConfig(vectorIndexConfig) - .replicationConfig(replicationConfig) - .moduleConfig(classModuleConfig) - .properties(new ArrayList() { - { - add(Property.builder() - .dataType(new ArrayList() { - { - add(DataType.TEXT); - } - }) - .name("content") - .description("The content of the local knowledge,for search") - .moduleConfig(propertyModuleConfigSkipFalse) - .build()); - add(Property.builder() - .dataType(new ArrayList() { - { - add(DataType.TEXT); - } - }) - .name("kid") - .description("The knowledge id of the local knowledge,for search") - .moduleConfig(propertyModuleConfigSkipTrue) - .build()); - add(Property.builder() - .dataType(new ArrayList() { - { - add(DataType.TEXT); - } - }) - .name("docId") - .description("The doc id of the local knowledge,for search") - .moduleConfig(propertyModuleConfigSkipTrue) - .build()); - add(Property.builder() - .dataType(new ArrayList() { - { - add(DataType.TEXT); - } - }) - .name("fid") - .description("The fragment id of the local knowledge,for search") - .moduleConfig(propertyModuleConfigSkipTrue) - .build()); - add(Property.builder() - .dataType(new ArrayList() { - { - add(DataType.TEXT); - } - }) - .name("uuid") - .description("The uuid id of the local knowledge fragment(same with id properties),for search") - .moduleConfig(propertyModuleConfigSkipTrue) - .build()); - } }) - .build(); - - Result<Boolean> result = client.schema().classCreator().withClass(clazz).run(); - if (result.hasErrors()) { - System.out.println(result.getError()); - } - System.out.println(result.getResult()); - return result; + return results; } @Override - public void newSchema(String kid) { - createSchema(kid); - } - - @Override - public void removeByKidAndFid(String kid, String fid) { - List<String> resultList = new ArrayList<>(); - WeaviateClient client = getClient(); - Field fieldId = Field.builder().name("uuid").build(); - WhereFilter where = WhereFilter.builder() - .path(new String[]{"fid"}) - .operator(Operator.Equal) - .valueString(fid) + public void createSchema(String kid) { + WeaviateContainer weaviate = new WeaviateContainer(protocol); + weaviate.start(); + this.embeddingStore = WeaviateEmbeddingStore.builder() + .scheme("http") + .host(host) + .objectClass(className+kid) + .scheme(protocol) + .avoidDups(true) + .consistencyLevel("ALL") .build(); - Result<GraphQLResponse> result = client.graphQL().get() - .withClassName(className + kid) - .withFields(fieldId) - .withWhere(where) - .run(); - LinkedTreeMap<String, Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData(); - LinkedTreeMap<String, ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get"); - ArrayList<LinkedTreeMap> m = l.get(className + kid); - for (LinkedTreeMap linkedTreeMap : m) { - String uuid = linkedTreeMap.get("uuid").toString(); - resultList.add(uuid); - } - for (String uuid : resultList) { - Result<Boolean> deleteResult = client.data().deleter() - .withID(uuid) - .withClassName(className + kid) - .withConsistencyLevel(ConsistencyLevel.ALL) // default QUORUM - .run(); - } } @Override - public void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList, String kid, String docId, List<String> fidList) { - WeaviateClient client = getClient(); - - for (int i = 0; i < Math.min(chunkList.size(), vectorList.size()); i++) { - List<Double> vector = vectorList.get(i); - Float[] vf = vector.stream().map(Double::floatValue).toArray(Float[]::new); - + public void storeEmbeddings(List<String> chunkList,String kid) { + EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder() + .apiKey(System.getenv("OPENAI_API_KEY")) + .baseUrl(System.getenv("OPENAI_BASE_URL")) + .modelName("text-embedding-3-small") + .build(); + // 鐢熸垚鏂囨。id + String docId = RandomUtil.randomString(10); + chunkList.forEach(chunk -> { + // 鐢熸垚鐭ヨ瘑鍧梚d + String fid = RandomUtil.randomString(10); Map<String, Object> dataSchema = new HashMap<>(); - dataSchema.put("content", chunkList.get(i)); dataSchema.put("kid", kid); dataSchema.put("docId", docId); - dataSchema.put("fid", fidList.get(i)); - String uuid = UUID.randomUUID().toString(); - dataSchema.put("uuid", uuid); + dataSchema.put("fid", fid); + TextSegment segment = TextSegment.from(chunk); + segment.metadata().putAll(dataSchema); + Embedding content = embeddingModel.embed(segment).content(); + embeddingStore.add(content); + }); + } - Result<WeaviateObject> result = client.data().creator() - .withClassName(className + kid) - .withID(uuid) - .withVector(vf) - .withProperties(dataSchema) - .run(); - } + @Override + public void removeByKid(String kid) { + // 鏍规嵁鏉′欢鍒犻櫎鍚戦噺鏁版嵁 + Filter simpleFilter = new IsEqualTo("kid", kid); + embeddingStore.removeAll(simpleFilter); } @Override public void removeByDocId(String kid, String docId) { - List<String> resultList = new ArrayList<>(); - WeaviateClient client = getClient(); - Field fieldId = Field.builder().name("uuid").build(); - WhereFilter where = WhereFilter.builder() - .path(new String[]{"docId"}) - .operator(Operator.Equal) - .valueString(docId) - .build(); - Result<GraphQLResponse> result = client.graphQL().get() - .withClassName(className + kid) - .withFields(fieldId) - .withWhere(where) - .run(); - LinkedTreeMap<String, Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData(); - LinkedTreeMap<String, ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get"); - ArrayList<LinkedTreeMap> m = l.get(className + kid); - for (LinkedTreeMap linkedTreeMap : m) { - String uuid = linkedTreeMap.get("uuid").toString(); - resultList.add(uuid); - } - for (String uuid : resultList) { - Result<Boolean> deleteResult = client.data().deleter() - .withID(uuid) - .withClassName(className + kid) - .withConsistencyLevel(ConsistencyLevel.ALL) // default QUORUM - .run(); - } + // 鏍规嵁鏉′欢鍒犻櫎鍚戦噺鏁版嵁 + Filter simpleFilterByDocId = new IsEqualTo("docId", docId); + embeddingStore.removeAll(simpleFilterByDocId); } @Override - public void removeByKid(String kid) { - WeaviateClient client = getClient(); - Result<Boolean> result = client.schema().classDeleter().withClassName(className + kid).run(); - if (result.hasErrors()) { - System.out.println("鍒犻櫎schema澶辫触" + result.getError()); - } else { - System.out.println("鍒犻櫎schema鎴愬姛" + result.getResult()); - } - log.info("drop schema by kid, result = {}", result); + public void removeByKidAndFid(String kid, String fid) { + // 鏍规嵁鏉′欢鍒犻櫎鍚戦噺鏁版嵁 + Filter simpleFilterByKid = new IsEqualTo("kid", kid); + Filter simpleFilterFid = new IsEqualTo("fid", fid); + Filter simpleFilterByAnd = Filter.and(simpleFilterFid, simpleFilterByKid); + embeddingStore.removeAll(simpleFilterByAnd); } - @Override - public List<String> nearest(List<Double> queryVector, String kid) { - if (StringUtils.isBlank(kid)) { - return new ArrayList<String>(); - } - List<String> resultList = new ArrayList<>(); - Float[] vf = new Float[queryVector.size()]; - for (int j = 0; j < queryVector.size(); j++) { - Double value = queryVector.get(j); - vf[j] = value.floatValue(); - } - WeaviateClient client = getClient(); - Field contentField = Field.builder().name("content").build(); - Field _additional = Field.builder() - .name("_additional") - .fields(new Field[]{ - Field.builder().name("distance").build() - }).build(); - NearVectorArgument nearVector = NearVectorArgument.builder() - .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(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"); - ArrayList<LinkedTreeMap> m = l.get(className + kid); - for (LinkedTreeMap linkedTreeMap : m) { - String content = linkedTreeMap.get("content").toString(); - resultList.add(content); - } - return resultList; - } - - @Override - public List<String> nearest(String query, String kid) { - if (StringUtils.isBlank(kid)) { - return new ArrayList<String>(); - } - List<String> resultList = new ArrayList<>(); - WeaviateClient client = getClient(); - Field contentField = Field.builder().name("content").build(); - Field _additional = Field.builder() - .name("_additional") - .fields(new Field[]{ - Field.builder().name("distance").build() - }).build(); - NearTextArgument nearText = client.graphQL().arguments().nearTextArgBuilder() - .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(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"); - ArrayList<LinkedTreeMap> m = l.get(className + kid); - for (LinkedTreeMap linkedTreeMap : m) { - String content = linkedTreeMap.get("content").toString(); - resultList.add(content); - } - return resultList; - } - - public Result<Boolean> deleteSchema(String kid) { - WeaviateClient client = getClient(); - Result<Boolean> result = client.schema().classDeleter().withClassName(className + kid).run(); - if (result.hasErrors()) { - System.out.println(result.getError()); - } else { - System.out.println(result.getResult()); - } - return result; - } } 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 ccf9f3a..8dabcc2 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 @@ -24,13 +24,11 @@ import org.ruoyi.common.core.utils.file.FileUtils; import org.ruoyi.common.core.utils.file.MimeTypeUtils; import org.ruoyi.common.redis.utils.RedisUtils; -import org.ruoyi.domain.ChatSession; import org.ruoyi.domain.bo.ChatSessionBo; import org.ruoyi.domain.vo.ChatModelVo; -import org.ruoyi.service.EmbeddingService; +import org.ruoyi.service.VectorStoreService; import org.ruoyi.service.IChatModelService; import org.ruoyi.service.IChatSessionService; -import org.ruoyi.service.VectorStoreService; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; @@ -56,7 +54,7 @@ private final OpenAiStreamClient openAiStreamClient; - private final EmbeddingService embeddingService; + private final VectorStoreService vectorStoreService; private final VectorStoreService vectorStore; @@ -184,9 +182,7 @@ if(StringUtils.isNotEmpty(chatRequest.getKid())){ 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()); + List<String> nearestList = vectorStoreService.getQueryVector(content, chatRequest.getKid()); for (String prompt : nearestList) { Message userMessage = Message.builder().content(prompt).role(Message.Role.USER).build(); knMessages.add(userMessage); diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/KnowledgeInfoServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/KnowledgeInfoServiceImpl.java index 7a489a6..33d9c11 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/KnowledgeInfoServiceImpl.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/KnowledgeInfoServiceImpl.java @@ -23,7 +23,7 @@ import org.ruoyi.mapper.KnowledgeAttachMapper; import org.ruoyi.mapper.KnowledgeFragmentMapper; import org.ruoyi.mapper.KnowledgeInfoMapper; -import org.ruoyi.service.EmbeddingService; +import org.ruoyi.service.VectorStoreService; import org.ruoyi.service.IKnowledgeInfoService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -44,7 +44,7 @@ private final KnowledgeInfoMapper baseMapper; - private final EmbeddingService embeddingService; + private final VectorStoreService vectorStoreService; private final ResourceLoaderFactory resourceLoaderFactory; @@ -150,7 +150,7 @@ knowledgeInfo.setUid(LoginHelper.getLoginUser().getUserId()); } baseMapper.insert(knowledgeInfo); - embeddingService.createSchema(String.valueOf(knowledgeInfo.getId())); + vectorStoreService.createSchema(String.valueOf(knowledgeInfo.getId())); }else { baseMapper.updateById(knowledgeInfo); } @@ -165,7 +165,7 @@ check(knowledgeInfoList); // 鍒犻櫎鍚戦噺搴撲俊鎭� knowledgeInfoList.forEach(knowledgeInfoVo -> { - embeddingService.removeByKid(String.valueOf(knowledgeInfoVo.getId())); + vectorStoreService.removeByKid(String.valueOf(knowledgeInfoVo.getId())); }); // 鍒犻櫎闄勪欢鍜岀煡璇嗙墖娈� fragmentMapper.deleteByMap(map); @@ -197,7 +197,7 @@ List<KnowledgeFragment> knowledgeFragmentList = new ArrayList<>(); if (CollUtil.isNotEmpty(chunkList)) { for (int i = 0; i < chunkList.size(); i++) { - String fid = RandomUtil.randomString(16); + String fid = RandomUtil.randomString(10); fids.add(fid); KnowledgeFragment knowledgeFragment = new KnowledgeFragment(); knowledgeFragment.setKid(kid); @@ -216,7 +216,7 @@ knowledgeAttach.setContent(content); knowledgeAttach.setCreateTime(new Date()); attachMapper.insert(knowledgeAttach); - embeddingService.storeEmbeddings(chunkList,kid,docId,fids); + vectorStoreService.storeEmbeddings(chunkList,kid); } -- Gitblit v1.9.3