diff --git a/service-ai/pom.xml b/service-ai/pom.xml
index 6ccfe6a..f54116c 100644
--- a/service-ai/pom.xml
+++ b/service-ai/pom.xml
@@ -25,6 +25,7 @@
3.4.3
2024.0.1
1.0.0
+ 3.3.1
11.1.0
5.1.0
5.8.27
@@ -136,6 +137,16 @@
liteflow-spring-boot-starter
2.13.2
+
+ org.noear
+ solon-ai
+ ${solon-ai.version}
+
+
+ org.noear
+ solon-ai-dialect-openai
+ ${solon-ai.version}
+
diff --git a/service-ai/service-ai-knowledge/pom.xml b/service-ai/service-ai-knowledge/pom.xml
index 92caba7..380f8ac 100644
--- a/service-ai/service-ai-knowledge/pom.xml
+++ b/service-ai/service-ai-knowledge/pom.xml
@@ -54,6 +54,14 @@
org.springframework.ai
spring-ai-pdf-document-reader
+
+ org.noear
+ solon-ai
+
+
+ org.noear
+ solon-ai-dialect-openai
+
diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/SolonConfiguration.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/SolonConfiguration.java
new file mode 100644
index 0000000..b255233
--- /dev/null
+++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/SolonConfiguration.java
@@ -0,0 +1,21 @@
+package com.lanyuanxiaoyao.service.ai.knowledge.configuration;
+
+import cn.hutool.core.util.StrUtil;
+import org.noear.solon.ai.reranking.RerankingModel;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author lanyuanxiaoyao
+ * @version 20250604
+ */
+@Configuration
+public class SolonConfiguration {
+ @Bean
+ public RerankingModel rerankingModel(SolonProperties solonProperties) {
+ return RerankingModel.of(StrUtil.format("{}{}", solonProperties.getBaseUrl(), solonProperties.getRerank().getEndpoint()))
+ .apiKey(solonProperties.getApiKey())
+ .model(solonProperties.getRerank().getModel())
+ .build();
+ }
+}
diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/SolonProperties.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/SolonProperties.java
new file mode 100644
index 0000000..399c219
--- /dev/null
+++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/SolonProperties.java
@@ -0,0 +1,78 @@
+package com.lanyuanxiaoyao.service.ai.knowledge.configuration;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author lanyuanxiaoyao
+ * @version 20250604
+ */
+@Configuration
+@ConfigurationProperties(prefix = "solon")
+public class SolonProperties {
+ private String baseUrl;
+ private String apiKey;
+ private Rerank rerank;
+
+ public String getBaseUrl() {
+ return baseUrl;
+ }
+
+ public void setBaseUrl(String baseUrl) {
+ this.baseUrl = baseUrl;
+ }
+
+ public String getApiKey() {
+ return apiKey;
+ }
+
+ public void setApiKey(String apiKey) {
+ this.apiKey = apiKey;
+ }
+
+ public Rerank getRerank() {
+ return rerank;
+ }
+
+ public void setRerank(Rerank rerank) {
+ this.rerank = rerank;
+ }
+
+ @Override
+ public String toString() {
+ return "SolonProperties{" +
+ "baseUrl='" + baseUrl + '\'' +
+ ", apiKey='" + apiKey + '\'' +
+ ", rerank=" + rerank +
+ '}';
+ }
+
+ public static final class Rerank {
+ private String model;
+ private String endpoint;
+
+ public String getModel() {
+ return model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ public String getEndpoint() {
+ return endpoint;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ @Override
+ public String toString() {
+ return "Rerank{" +
+ "model='" + model + '\'' +
+ ", endpoint='" + endpoint + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/KnowledgeController.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/KnowledgeBaseController.java
similarity index 85%
rename from service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/KnowledgeController.java
rename to service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/KnowledgeBaseController.java
index c757195..168fcd3 100644
--- a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/KnowledgeController.java
+++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/KnowledgeBaseController.java
@@ -5,7 +5,8 @@ import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisMapResponse;
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisResponse;
import com.lanyuanxiaoyao.service.ai.knowledge.entity.vo.SegmentVO;
import com.lanyuanxiaoyao.service.ai.knowledge.service.EmbeddingService;
-import com.lanyuanxiaoyao.service.ai.knowledge.service.KnowledgeService;
+import com.lanyuanxiaoyao.service.ai.knowledge.service.KnowledgeBaseService;
+import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList;
@@ -24,14 +25,14 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
@RequestMapping("knowledge")
-public class KnowledgeController {
- private static final Logger logger = LoggerFactory.getLogger(KnowledgeController.class);
+public class KnowledgeBaseController {
+ private static final Logger logger = LoggerFactory.getLogger(KnowledgeBaseController.class);
- private final KnowledgeService knowledgeService;
+ private final KnowledgeBaseService knowledgeBaseService;
private final EmbeddingService embeddingService;
- public KnowledgeController(KnowledgeService knowledgeService, EmbeddingService embeddingService) {
- this.knowledgeService = knowledgeService;
+ public KnowledgeBaseController(KnowledgeBaseService knowledgeBaseService, EmbeddingService embeddingService) {
+ this.knowledgeBaseService = knowledgeBaseService;
this.embeddingService = embeddingService;
}
@@ -40,23 +41,23 @@ public class KnowledgeController {
@RequestParam("name") String name,
@RequestParam("strategy") String strategy
) throws ExecutionException, InterruptedException {
- knowledgeService.add(name, strategy);
+ knowledgeBaseService.add(name, strategy);
}
@GetMapping("name")
public AmisMapResponse name(@RequestParam("id") Long id) {
return AmisResponse.responseMapData()
- .setData("name", knowledgeService.getName(id));
+ .setData("name", knowledgeBaseService.getName(id));
}
@GetMapping("list")
public AmisResponse> list() {
- return AmisResponse.responseCrudData(knowledgeService.list());
+ return AmisResponse.responseCrudData(knowledgeBaseService.list());
}
@GetMapping("delete")
public void delete(@RequestParam("id") Long id) throws ExecutionException, InterruptedException {
- knowledgeService.remove(id);
+ knowledgeBaseService.remove(id);
}
@PostMapping("preview_text")
@@ -114,7 +115,7 @@ public class KnowledgeController {
@RequestParam(value = "limit", defaultValue = "5") Integer limit,
@RequestParam(value = "threshold", defaultValue = "0.6") Double threshold,
@RequestBody String text
- ) throws ExecutionException, InterruptedException {
- return knowledgeService.query(id, text, limit, threshold);
+ ) throws ExecutionException, InterruptedException, IOException {
+ return knowledgeBaseService.query(id, text, limit, threshold);
}
}
diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/EmbeddingService.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/EmbeddingService.java
index 268cfb9..0b4be14 100644
--- a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/EmbeddingService.java
+++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/EmbeddingService.java
@@ -29,15 +29,15 @@ public class EmbeddingService {
private final DataFileService dataFileService;
private final FlowExecutor executor;
- private final KnowledgeService knowledgeService;
+ private final KnowledgeBaseService knowledgeBaseService;
private final GroupService groupService;
private final ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
- public EmbeddingService(DataFileService dataFileService, FlowExecutor executor, KnowledgeService knowledgeService, GroupService groupService) {
+ public EmbeddingService(DataFileService dataFileService, FlowExecutor executor, KnowledgeBaseService knowledgeBaseService, GroupService groupService) {
this.dataFileService = dataFileService;
this.executor = executor;
- this.knowledgeService = knowledgeService;
+ this.knowledgeBaseService = knowledgeBaseService;
this.groupService = groupService;
}
@@ -63,7 +63,7 @@ public class EmbeddingService {
public void submit(Long id, String mode, String content) {
executors.submit(() -> {
- Knowledge knowledge = knowledgeService.get(id);
+ Knowledge knowledge = knowledgeBaseService.get(id);
Long groupId = groupService.add(knowledge.getId(), StrUtil.format("文本-{}", IdUtil.nanoId(10)));
EmbeddingContext context = EmbeddingContext.builder()
.vectorSourceId(knowledge.getVectorSourceId())
@@ -80,7 +80,7 @@ public class EmbeddingService {
public void submit(Long id, String mode, ImmutableList ids) {
executors.submit(() -> {
- Knowledge knowledge = knowledgeService.get(id);
+ Knowledge knowledge = knowledgeBaseService.get(id);
List> vos = Lists.mutable.empty();
for (String fileId : ids) {
DataFileVO vo = dataFileService.downloadFile(Long.parseLong(fileId));
diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/GroupService.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/GroupService.java
index bad5e28..7f3329a 100644
--- a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/GroupService.java
+++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/GroupService.java
@@ -102,7 +102,7 @@ public class GroupService {
public void remove(Long groupId) throws ExecutionException, InterruptedException {
Long vectorSourceId = template.queryForObject(
SqlBuilder.select("k.vector_source_id")
- .from(Alias.of(GROUP_TABLE_NAME, "g"), Alias.of(KnowledgeService.KNOWLEDGE_TABLE_NAME, "k"))
+ .from(Alias.of(GROUP_TABLE_NAME, "g"), Alias.of(KnowledgeBaseService.KNOWLEDGE_TABLE_NAME, "k"))
.whereEq("g.knowledge_id", Column.as("k.id"))
.andEq("g.id", groupId)
.precompileSql(),
diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/KnowledgeService.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/KnowledgeBaseService.java
similarity index 88%
rename from service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/KnowledgeService.java
rename to service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/KnowledgeBaseService.java
index 09ab7ad..cf85fb8 100644
--- a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/KnowledgeService.java
+++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/KnowledgeBaseService.java
@@ -9,11 +9,13 @@ import com.lanyuanxiaoyao.service.ai.knowledge.entity.vo.KnowledgeVO;
import com.lanyuanxiaoyao.service.common.Constants;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.Collections;
+import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList;
+import org.noear.solon.ai.reranking.RerankingModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
@@ -31,9 +33,9 @@ import org.springframework.transaction.annotation.Transactional;
* @version 20250522
*/
@Service
-public class KnowledgeService {
+public class KnowledgeBaseService {
public static final String KNOWLEDGE_TABLE_NAME = Constants.DATABASE_NAME + ".service_ai_knowledge";
- private static final Logger logger = LoggerFactory.getLogger(KnowledgeService.class);
+ private static final Logger logger = LoggerFactory.getLogger(KnowledgeBaseService.class);
private static final RowMapper knowledgeMapper = (rs, row) -> {
Knowledge knowledge = new Knowledge();
knowledge.setId(rs.getLong(1));
@@ -48,12 +50,14 @@ public class KnowledgeService {
private final EmbeddingModel model;
private final QdrantClient client;
private final GroupService groupService;
+ private final RerankingModel rerankingModel;
- public KnowledgeService(JdbcTemplate template, EmbeddingModel model, VectorStore vectorStore, GroupService groupService) {
+ public KnowledgeBaseService(JdbcTemplate template, EmbeddingModel model, VectorStore vectorStore, GroupService groupService, RerankingModel rerankingModel) {
this.template = template;
this.model = model;
this.client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
this.groupService = groupService;
+ this.rerankingModel = rerankingModel;
}
public Knowledge get(Long id) {
@@ -166,7 +170,8 @@ public class KnowledgeService {
Long id,
String text,
Integer limit,
- Double threshold) throws ExecutionException, InterruptedException {
+ Double threshold
+ ) throws ExecutionException, InterruptedException, IOException {
Knowledge knowledge = get(id);
Boolean exists = client.collectionExistsAsync(String.valueOf(knowledge.getVectorSourceId())).get();
if (!exists) {
@@ -183,7 +188,13 @@ public class KnowledgeService {
.similarityThreshold(threshold)
.build()
);
- return Lists.immutable.ofAll(documents)
- .collect(Document::getText);
+ List rerankDocuments = rerankingModel.rerank(
+ text,
+ documents.stream()
+ .map(doc -> new org.noear.solon.ai.rag.Document(doc.getId(), doc.getText(), doc.getMetadata(), doc.getScore()))
+ .toList()
+ );
+ return Lists.immutable.ofAll(rerankDocuments)
+ .collect(org.noear.solon.ai.rag.Document::getContent);
}
}
\ No newline at end of file
diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/SegmentService.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/SegmentService.java
index 54fbd69..700cc06 100644
--- a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/SegmentService.java
+++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/service/SegmentService.java
@@ -23,16 +23,16 @@ import org.springframework.stereotype.Service;
public class SegmentService {
private static final Logger logger = LoggerFactory.getLogger(SegmentService.class);
- private final KnowledgeService knowledgeService;
+ private final KnowledgeBaseService knowledgeBaseService;
private final QdrantClient client;
- public SegmentService(KnowledgeService knowledgeService, VectorStore vectorStore) {
- this.knowledgeService = knowledgeService;
+ public SegmentService(KnowledgeBaseService knowledgeBaseService, VectorStore vectorStore) {
+ this.knowledgeBaseService = knowledgeBaseService;
this.client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
}
public ImmutableList list(Long id, Long groupId) throws ExecutionException, InterruptedException {
- Knowledge knowledge = knowledgeService.get(id);
+ Knowledge knowledge = knowledgeBaseService.get(id);
Points.ScrollResponse response = client.scrollAsync(
Points.ScrollPoints.newBuilder()
.setCollectionName(String.valueOf(knowledge.getVectorSourceId()))
@@ -59,7 +59,7 @@ public class SegmentService {
}
public void remove(Long knowledgeId, Long segmentId) throws ExecutionException, InterruptedException {
- Knowledge knowledge = knowledgeService.get(knowledgeId);
+ Knowledge knowledge = knowledgeBaseService.get(knowledgeId);
client.deletePayloadAsync(
String.valueOf(knowledgeId),
List.of(String.valueOf(segmentId)),
diff --git a/service-ai/service-ai-knowledge/src/main/resources/application.yml b/service-ai/service-ai-knowledge/src/main/resources/application.yml
index 41a042a..f223948 100644
--- a/service-ai/service-ai-knowledge/src/main/resources/application.yml
+++ b/service-ai/service-ai-knowledge/src/main/resources/application.yml
@@ -22,3 +22,9 @@ liteflow:
rule-source: config/flow.xml
print-banner: false
check-node-exists: false
+solon:
+ base-url: http://132.121.206.65:10086
+ api-key: ENC(K+Hff9QGC+fcyi510VIDd9CaeK/IN5WBJ9rlkUsHEdDgIidW+stHHJlsK0lLPUXXREha+ToQZqqDXJrqSE+GUKCXklFhelD8bRHFXBIeP/ZzT2cxhzgKUXgjw3S0Qw2R)
+ rerank:
+ model: 'Bge-reranker-v2-vllm'
+ endpoint: '/v1/rerank'
\ No newline at end of file