feat: 本地知识库功能优化

This commit is contained in:
ageer
2025-03-24 23:35:45 +08:00
parent 567498654e
commit e893110ee5
4 changed files with 33 additions and 19 deletions

View File

@@ -33,6 +33,7 @@ import org.ruoyi.knowledge.service.IKnowledgeAttachService;
import org.ruoyi.knowledge.service.IKnowledgeFragmentService; import org.ruoyi.knowledge.service.IKnowledgeFragmentService;
import org.ruoyi.knowledge.service.IKnowledgeInfoService; import org.ruoyi.knowledge.service.IKnowledgeInfoService;
import org.ruoyi.system.listener.SSEEventSourceListener; import org.ruoyi.system.listener.SSEEventSourceListener;
import org.ruoyi.system.service.ISseService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.ruoyi.knowledge.chain.vectorstore.VectorStore; import org.ruoyi.knowledge.chain.vectorstore.VectorStore;
@@ -68,11 +69,14 @@ public class KnowledgeController extends BaseController {
private final ChatConfig chatConfig; private final ChatConfig chatConfig;
private final ISseService sseService;
/** /**
* 知识库对话 * 知识库对话
*/ */
@PostMapping("/send") @PostMapping("/send")
public SseEmitter send(@RequestBody @Valid ChatRequest chatRequest) { public SseEmitter send(@RequestBody @Valid ChatRequest chatRequest) {
openAiStreamClient = chatConfig.getOpenAiStreamClient(); openAiStreamClient = chatConfig.getOpenAiStreamClient();
SseEmitter sseEmitter = new SseEmitter(0L); SseEmitter sseEmitter = new SseEmitter(0L);
SSEEventSourceListener openAIEventSourceListener = new SSEEventSourceListener(sseEmitter); SSEEventSourceListener openAIEventSourceListener = new SSEEventSourceListener(sseEmitter);
@@ -87,6 +91,10 @@ public class KnowledgeController extends BaseController {
} }
Message userMessage = Message.builder().content(content + (nearestList.size() > 0 ? "\n\n注意回答问题时须严格根据我给你的系统上下文内容原文进行回答请不要自己发挥,回答时保持原来文本的段落层级" : "") ).role(Message.Role.USER).build(); Message userMessage = Message.builder().content(content + (nearestList.size() > 0 ? "\n\n注意回答问题时须严格根据我给你的系统上下文内容原文进行回答请不要自己发挥,回答时保持原来文本的段落层级" : "") ).role(Message.Role.USER).build();
messages.add(userMessage); messages.add(userMessage);
if (chatRequest.getModel().startsWith("ollama")) {
return sseService.ollamaChat(chatRequest);
}
ChatCompletion completion = ChatCompletion ChatCompletion completion = ChatCompletion
.builder() .builder()
.messages(messages) .messages(messages)

View File

@@ -43,7 +43,7 @@ import java.util.List;
@RequestMapping("/chat") @RequestMapping("/chat")
public class ChatController { public class ChatController {
private final ISseService ISseService; private final ISseService sseService;
private final IChatMessageService chatMessageService; private final IChatMessageService chatMessageService;
@@ -54,9 +54,9 @@ public class ChatController {
@ResponseBody @ResponseBody
public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest, HttpServletRequest request) { public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest, HttpServletRequest request) {
if (chatRequest.getModel().startsWith("ollama")) { if (chatRequest.getModel().startsWith("ollama")) {
return ISseService.ollamaChat(chatRequest); return sseService.ollamaChat(chatRequest);
} }
return ISseService.sseChat(chatRequest,request); return sseService.sseChat(chatRequest,request);
} }
@@ -66,7 +66,7 @@ public class ChatController {
@PostMapping("/upload") @PostMapping("/upload")
@ResponseBody @ResponseBody
public UploadFileResponse upload(@RequestPart("file") MultipartFile file) { public UploadFileResponse upload(@RequestPart("file") MultipartFile file) {
return ISseService.upload(file); return sseService.upload(file);
} }
@@ -78,7 +78,7 @@ public class ChatController {
@PostMapping("/audio") @PostMapping("/audio")
@ResponseBody @ResponseBody
public WhisperResponse audio(@RequestParam("file") MultipartFile file) { public WhisperResponse audio(@RequestParam("file") MultipartFile file) {
WhisperResponse whisperResponse = ISseService.speechToTextTranscriptionsV2(file); WhisperResponse whisperResponse = sseService.speechToTextTranscriptionsV2(file);
return whisperResponse; return whisperResponse;
} }
@@ -90,7 +90,7 @@ public class ChatController {
@PostMapping("/speech") @PostMapping("/speech")
@ResponseBody @ResponseBody
public ResponseEntity<Resource> speech(@RequestBody TextToSpeech textToSpeech) { public ResponseEntity<Resource> speech(@RequestBody TextToSpeech textToSpeech) {
return ISseService.textToSpeed(textToSpeech); return sseService.textToSpeed(textToSpeech);
} }
/** /**
@@ -101,13 +101,13 @@ public class ChatController {
@PostMapping("/translation") @PostMapping("/translation")
@ResponseBody @ResponseBody
public String translation(@RequestBody TranslationRequest translationRequest) { public String translation(@RequestBody TranslationRequest translationRequest) {
return ISseService.translation(translationRequest); return sseService.translation(translationRequest);
} }
@PostMapping("/dall3") @PostMapping("/dall3")
@ResponseBody @ResponseBody
public R<List<Item>> dall3(@RequestBody @Valid Dall3Request request) { public R<List<Item>> dall3(@RequestBody @Valid Dall3Request request) {
return R.ok(ISseService.dall3(request)); return R.ok(sseService.dall3(request));
} }
/** /**

View File

@@ -229,21 +229,19 @@ public class WeaviateVectorStore implements VectorStore{
@Override @Override
public void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList,String kid, String docId,List<String> fidList) { public void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList,String kid, String docId,List<String> fidList) {
WeaviateClient client = getClient(); WeaviateClient client = getClient();
for (int i = 0; i < chunkList.size(); i++) { if (vectorList != null) {
if (vectorList != null) { for (int i = 0; i < Math.min(chunkList.size(), vectorList.size()); i++) {
List<Double> vector = vectorList.get(i); List<Double> vector = vectorList.get(i);
Float[] vf = new Float[vector.size()]; Float[] vf = vector.stream().map(Double::floatValue).toArray(Float[]::new);
for (int j = 0; j < vector.size(); j++) {
Double value = vector.get(j);
vf[j] = value.floatValue();
}
Map<String, Object> dataSchema = new HashMap<>(); Map<String, Object> dataSchema = new HashMap<>();
dataSchema.put("content", chunkList.get(i)); dataSchema.put("content", chunkList.get(i));
dataSchema.put("kid", kid); dataSchema.put("kid", kid);
dataSchema.put("docId", docId); dataSchema.put("docId", docId);
dataSchema.put("fid", fidList.get(i)); dataSchema.put("fid", fidList.get(i));
String uuid = UUID.randomUUID(true).toString(); String uuid = UUID.randomUUID().toString();
dataSchema.put("uuid", uuid); dataSchema.put("uuid", uuid);
Result<WeaviateObject> result = client.data().creator() Result<WeaviateObject> result = client.data().creator()
.withClassName(className + kid) .withClassName(className + kid)
.withID(uuid) .withID(uuid)

View File

@@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhipu.oapi.ClientV4; import com.zhipu.oapi.ClientV4;
import com.zhipu.oapi.service.v4.tools.*; import com.zhipu.oapi.service.v4.tools.*;
import io.github.ollama4j.OllamaAPI; import io.github.ollama4j.OllamaAPI;
import io.github.ollama4j.models.chat.OllamaChatMessage;
import io.github.ollama4j.models.chat.OllamaChatMessageRole; import io.github.ollama4j.models.chat.OllamaChatMessageRole;
import io.github.ollama4j.models.chat.OllamaChatRequestBuilder; import io.github.ollama4j.models.chat.OllamaChatRequestBuilder;
import io.github.ollama4j.models.chat.OllamaChatRequestModel; import io.github.ollama4j.models.chat.OllamaChatRequestModel;
@@ -626,13 +627,20 @@ public class SseServiceImpl implements ISseService {
final SseEmitter emitter = new SseEmitter(); final SseEmitter emitter = new SseEmitter();
String host = sysModel.getApiHost(); String host = sysModel.getApiHost();
List<Message> msgList = chatRequest.getMessages(); List<Message> msgList = chatRequest.getMessages();
Message message = msgList.get(msgList.size() - 1); List<OllamaChatMessage> messages = new ArrayList<>();
for (Message message : msgList) {
OllamaChatMessage ollamaChatMessage = new OllamaChatMessage();
ollamaChatMessage.setRole(OllamaChatMessageRole.USER);
ollamaChatMessage.setContent(message.getContent().toString());
messages.add(ollamaChatMessage);
}
OllamaAPI api = new OllamaAPI(host); OllamaAPI api = new OllamaAPI(host);
api.setRequestTimeoutSeconds(100); api.setRequestTimeoutSeconds(100);
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(parts[1]); OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(parts[1]);
OllamaChatRequestModel requestModel = builder OllamaChatRequestModel requestModel = builder
.withMessage(OllamaChatMessageRole.USER, .withMessages(messages)
message.getContent().toString())
.build(); .build();
// 异步执行 OllAma API 调用 // 异步执行 OllAma API 调用