diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/conversation/ConversationController.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/conversation/ConversationController.java index cb4cd11ec..8c5e2f640 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/conversation/ConversationController.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/conversation/ConversationController.java @@ -110,7 +110,6 @@ public class ConversationController { public SseEmitter streamChat (@Valid @RequestBody ChatReqVO chatReqVO, HttpServletResponse response) { log.info("收到对话推理请求,请求参数: {}", chatReqVO); SseEmitter emitter = new SseEmitter(120_0000L); - // 异步处理,避免阻塞主线程 CompletableFuture.runAsync(() -> { try { @@ -129,6 +128,29 @@ public class ConversationController { return emitter; } + @PostMapping("/stream-chat-modal") + public SseEmitter streamChatModal (@Valid @RequestBody ChatReqVO chatReqVO, HttpServletResponse response) { + log.info("收到对话推理请求,请求参数: {}", chatReqVO); + SseEmitter emitter = new SseEmitter(120_0000L); + + // 异步处理,避免阻塞主线程 + CompletableFuture.runAsync(() -> { + try { + conversationService.chatStreamModal(chatReqVO, emitter, response); + emitter.complete(); + } catch (Exception e) { + log.error("处理对话推理请求时发生异常:{}", e.getMessage()); + try { + emitter.completeWithError(e); + } catch (Exception ex) { + log.error("无法完成 SseEmitter 错误处理", ex); + } + } + }); + + return emitter; + } + @GetMapping("/paragraphHitRate") @Operation(summary = "获得大模型对话记录分页") @PreAuthorize("@ss.hasPermission('llm:conversation:query')") diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/conversation/vo/ChatReqVO.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/conversation/vo/ChatReqVO.java index 561e1651b..3ec3478c4 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/conversation/vo/ChatReqVO.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/conversation/vo/ChatReqVO.java @@ -5,6 +5,7 @@ import lombok.Data; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.util.List; @Schema(description = "管理后台 - 大模型对话推理聊天 Request VO") @Data @@ -35,4 +36,6 @@ public class ChatReqVO { private Double topP; @Schema(description = "分组id") private String groupId; + + private List imagesList; } diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/dataset/DatasetController.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/dataset/DatasetController.java index 0f56468fb..ddd0f6e2e 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/dataset/DatasetController.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/dataset/DatasetController.java @@ -171,6 +171,8 @@ public class DatasetController { return new FileInfoVO("dataset_example_csv.csv", "text/csv"); case 4: return new FileInfoVO("dataset_example_json.json", "application/json"); + case 5: + return new FileInfoVO("VL_test.zip", "application/zip"); default: throw new IllegalArgumentException("无效的 type 参数"); } diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/dataset/vo/DatasetRespVO.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/dataset/vo/DatasetRespVO.java index b8801e370..17dcab27f 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/dataset/vo/DatasetRespVO.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/dataset/vo/DatasetRespVO.java @@ -68,4 +68,6 @@ public class DatasetRespVO { private String jobId; private String fileUrl; + + private Integer datasetParentType; } diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/modelservice/ModelServiceController.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/modelservice/ModelServiceController.java index 48e8ae788..790ea312e 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/modelservice/ModelServiceController.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/controller/admin/modelservice/ModelServiceController.java @@ -108,7 +108,13 @@ public class ModelServiceController { // @PreAuthorize("@ss.hasPermission('llm:model-service:query')") public CommonResult> getModelServiceList() { List list = modelServiceService.getModelServiceList(); - return success(BeanUtils.toBean(list, ModelServiceRespVO.class)); + List modelServiceRespVOS = BeanUtils.toBean(list, ModelServiceRespVO.class); + modelServiceRespVOS.stream().forEach(result ->{ + Long id=result.getFineTuningTask(); + BaseModelDO basemodel = baseModelService.getById(id); + result.setModelType(basemodel.getModelType()); + }); + return success(modelServiceRespVOS); } @DeleteMapping("/delete") diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/framework/backend/config/LLMBackendProperties.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/framework/backend/config/LLMBackendProperties.java index b4d7fa760..f2364dcda 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/framework/backend/config/LLMBackendProperties.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/framework/backend/config/LLMBackendProperties.java @@ -75,6 +75,8 @@ public class LLMBackendProperties { @NotNull(message = "创建微调任务 POST") private String finetuningCreate; + @NotNull(message = "创建微调任务多模态 POST") + private String finetuningCreateModal; @NotNull(message = "停止微调任务 POST") private String stopFinetuning; @@ -145,4 +147,6 @@ public class LLMBackendProperties { * 获取调优检查点列表 */ private String checkFileList; + + private String datasetMoreModalApi; } diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/async/AsyncDataSetService.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/async/AsyncDataSetService.java index d7a406601..e350fa28f 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/async/AsyncDataSetService.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/async/AsyncDataSetService.java @@ -1,14 +1,20 @@ package cn.iocoder.yudao.module.llm.service.async; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.http.HttpUtils; import cn.iocoder.yudao.module.llm.controller.admin.dataset.vo.DatasetQuestionRespVO; import cn.iocoder.yudao.module.llm.dal.dataobject.dataset.DatasetDO; +import cn.iocoder.yudao.module.llm.dal.dataobject.dataset.DatasetFilesDO; +import cn.iocoder.yudao.module.llm.dal.mysql.dataset.DatasetFilesMapper; import cn.iocoder.yudao.module.llm.dal.mysql.dataset.DatasetMapper; import cn.iocoder.yudao.module.llm.framework.backend.config.LLMBackendProperties; +import cn.iocoder.yudao.module.llm.service.dataset.DatasetFilesService; import cn.iocoder.yudao.module.llm.service.dataset.vo.AigcDatasetVo; import cn.iocoder.yudao.module.llm.service.http.TrainHttpService; import cn.iocoder.yudao.module.llm.service.http.vo.AigcDatasetFileRespV0; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,6 +38,9 @@ public class AsyncDataSetService { @Resource private LLMBackendProperties llmBackendProperties; + + @Resource + private DatasetFilesMapper datasetFilesMapper; private static final Logger log = LoggerFactory.getLogger(AsyncKnowledgeBase.class); @Async @@ -75,6 +84,17 @@ public class AsyncDataSetService { } } + @Async + public void sendDatasetModal(Long datasetid,String datasetName){ + List datasetFilesDOS = datasetFilesMapper.selectList(Wrappers.lambdaQuery().eq(DatasetFilesDO::getDatasetId, datasetid)); + JSONObject param=new JSONObject(); + param.put("url",datasetFilesDOS.get(0).getDatasetFileUrl()); + param.put("dataset_name",datasetName); + HttpUtils.post(llmBackendProperties.getDatasetMoreModalApi(),null,param.toString()); + //llmBackendProperties.getDatasetMoreModalApi() + + } + public String JsonFileWriteFine (String hostUrl, DatasetDO datasetDO, List datasetQuestionList) { try { diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/async/AsyncFineTuningTaskService.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/async/AsyncFineTuningTaskService.java index bccc9148d..588db41cc 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/async/AsyncFineTuningTaskService.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/async/AsyncFineTuningTaskService.java @@ -122,7 +122,14 @@ public class AsyncFineTuningTaskService { // 调用模型服务创建微调任务 log.info("正在调用模型服务创建微调任务..."); - AigcFineTuningCreateRespVO resp = fineTuningTaskHttpService.finetuningCreate(new HashMap<>(), serverNameDO.getHost(), req); + AigcFineTuningCreateRespVO resp=null; + String modelType = baseModelDO.getModelType(); + if("1".equals(modelType)){ + resp = fineTuningTaskHttpService.finetuningCreate(new HashMap<>(), serverNameDO.getHost(), req); + }else{ + resp = fineTuningTaskHttpService.finetuningCreateModal(new HashMap<>(), serverNameDO.getHost(), req); + } + // 更新任务状态 FineTuningTaskDO updateObj = new FineTuningTaskDO(); diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/conversation/ConversationService.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/conversation/ConversationService.java index 3cc229fe7..15e8d876d 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/conversation/ConversationService.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/conversation/ConversationService.java @@ -75,6 +75,8 @@ public interface ConversationService { */ void chatStream (@Valid ChatReqVO chatReqVO, SseEmitter emitter, HttpServletResponse response); + void chatStreamModal(ChatReqVO chatReqVO, SseEmitter emitter, HttpServletResponse response); + /** * 获取段落命中率 * @param uuid diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/conversation/ConversationServiceImpl.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/conversation/ConversationServiceImpl.java index edb88d5b7..9a20b4e4f 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/conversation/ConversationServiceImpl.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/conversation/ConversationServiceImpl.java @@ -13,11 +13,9 @@ import cn.iocoder.yudao.module.llm.controller.admin.application.vo.ApplicationSa import cn.iocoder.yudao.module.llm.controller.admin.conversation.vo.*; import cn.iocoder.yudao.module.llm.controller.admin.conversation.vo.ChatReqVO; import cn.iocoder.yudao.module.llm.controller.admin.datarefluxdata.vo.DataRefluxDataSaveReqVO; -import cn.iocoder.yudao.module.llm.controller.admin.knowledgebase.vo.KnowledgeBaseSaveReqVO; import cn.iocoder.yudao.module.llm.controller.admin.knowledgebase.vo.KnowledgeHitRateTestReqVO; import cn.iocoder.yudao.module.llm.controller.admin.knowledgebase.vo.KnowledgeHitRateTestResultVO; import cn.iocoder.yudao.module.llm.controller.admin.prompttemplates.vo.PromptTemplatesRespVO; -import cn.iocoder.yudao.module.llm.controller.admin.prompttemplates.vo.PromptTemplatesSaveReqVO; import cn.iocoder.yudao.module.llm.dal.dataobject.basemodel.BaseModelDO; import cn.iocoder.yudao.module.llm.dal.dataobject.conversation.ConversationDO; import cn.iocoder.yudao.module.llm.dal.dataobject.knowledgedocuments.KnowledgeDocumentsDO; @@ -341,6 +339,49 @@ public class ConversationServiceImpl implements ConversationService { publicModelChatStream(chatReqVO, emitter); } + @Override + public void chatStreamModal(ChatReqVO chatReqVO, SseEmitter emitter, HttpServletResponse response) { + log.info("开始处理对话请求,请求参数: {}", chatReqVO); + // 检查系统提示信息,如果为空则尝试从应用中获取 + if (chatReqVO.getSystemPrompt() == null || chatReqVO.getSystemPrompt().isEmpty()) { + if (chatReqVO.getApplicationId() != null) { + log.info("系统提示信息为空,尝试从应用中获取,应用 ID: {}", chatReqVO.getApplicationId()); + ApplicationRespVO application = applicationService.getApplication(chatReqVO.getApplicationId()); + List messageHistoryList = stringRedisTemplate.opsForList().range(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), 0, -1); + if (CollectionUtils.isEmpty(messageHistoryList)) { + log.info("聊天历史记录为空,更新应用聊天计数"); + application.setChatCount(application.getChatCount() + 1); + ApplicationSaveReqVO applicationSaveReqVO = BeanUtil.toBean(application, ApplicationSaveReqVO.class); + applicationService.updateApplication(applicationSaveReqVO); + } + + + // 知识库ID + if (application.getModelServiceId() != null) { + chatReqVO.setKnowledge(application.getModelServiceId()); + } + + if (!org.apache.commons.lang3.StringUtils.isBlank(application.getPrompt())) { + chatReqVO.setSystemPrompt(application.getPrompt()); + if (chatReqVO.getSystemPrompt() == null || chatReqVO.getSystemPrompt().isEmpty()) { + log.info("应用中未找到系统提示信息,使用默认提示信息"); + chatReqVO.setSystemPrompt(PROMPT); + } + } + + Optional.ofNullable(application.getPromptId()).ifPresent(promptId -> { + PromptTemplatesRespVO promptTemplates = promptTemplatesService.getPromptTemplates(promptId); + int count = Math.max(1, Optional.ofNullable(promptTemplates.getUseCount()).orElse(0) + 1); + promptTemplatesService.updatePromptTemplatesUseCount(Math.toIntExact(promptId),count); + }); + + log.info("已更新系统提示信息为: {}", chatReqVO.getSystemPrompt()); + } + } + // 调用公共模型聊天流式处理方法 + publicModelChatStreamModal(chatReqVO, emitter); + } + /** * 获取段落命中率 * @@ -547,6 +588,180 @@ public class ConversationServiceImpl implements ConversationService { log.info("数据回流信息保存完成"); } + public void publicModelChatStreamModal(ChatReqVO chatReqVO, SseEmitter emitter) { + log.info("开始公共模型聊天流式处理,请求参数: {}", chatReqVO); + // 检查 UUID 是否为空,若为空则生成一个 + String uuid = chatReqVO.getUuid(); + if (StrUtil.isBlank(uuid)) { + log.info("UUID 为空,生成新的 UUID"); + uuid = UUID.randomUUID().toString(); + chatReqVO.setUuid(uuid); + } + + // 为每一次对话设置ID + String groupId = UUID.randomUUID().toString(); + chatReqVO.setGroupId(groupId); + + String model = null; + String selfModelUrl = ""; + // 根据模型类型获取模型信息 + if (Objects.equals(1, chatReqVO.getModelType())) { + log.info("使用预制模型,模型 ID: {}", chatReqVO.getModelId()); + BaseModelDO baseModelDO = baseModelService.getBaseModel(chatReqVO.getModelId()); + if (baseModelDO == null) { + log.error("预制模型不存在,模型 ID: {}", chatReqVO.getModelId()); + try { + emitter.completeWithError(new RuntimeException("BASE_MODEL_NOT_EXISTS")); + } catch (Exception e) { + log.error("无法完成 SseEmitter 错误处理", e); + } + return; + } + selfModelUrl = baseModelDO.getChatUrl(); + model = baseModelDO.getAigcModelName(); + log.info("获取到预制模型信息,模型名称: {}, 聊天 URL: {}", model, selfModelUrl); + } else if (Objects.equals(0, chatReqVO.getModelType())) { + log.info("使用自定义模型,模型 ID: {}", chatReqVO.getModelId()); + ModelServiceDO modelServiceDO = modelServiceMapper.selectById(chatReqVO.getModelId()); + if (modelServiceDO == null) { + log.error("自定义模型服务不存在,模型 ID: {}", chatReqVO.getModelId()); + try { + emitter.completeWithError(new RuntimeException("MODEL_SERVICE_NOT_EXISTS")); + } catch (Exception e) { + log.error("无法完成 SseEmitter 错误处理", e); + } + return; + } + model = modelServiceDO.getBaseModelName(); + selfModelUrl = modelServiceDO.getModelUrl(); + log.info("获取到自定义模型信息,模型名称: {}, 模型 URL: {}", model, selfModelUrl); + } else { + log.error("无效的模型类型,模型类型: {}", chatReqVO.getModelType()); + try { + emitter.completeWithError(new RuntimeException("BASE_MODEL_NOT_EXISTS")); + } catch (Exception e) { + log.error("无法完成 SseEmitter 错误处理", e); + } + return; + } + + List messages = new ArrayList<>(); + String systemPrompt = ""; + String knowledgeBaseString = ""; + if (chatReqVO.getKnowledge() != null) { + StringBuilder knowledgeBase = getKnowledgeBase(chatReqVO); + knowledgeBaseString = knowledgeBase.toString(); + + // 处理 knowledgeBaseString + if (StringUtils.isNotBlank(knowledgeBaseString)) { + knowledgeBaseString = "" + knowledgeBaseString + ""; + } else { + knowledgeBaseString = "" + ""; + } + + // 处理 systemPrompt + systemPrompt = StringUtils.isBlank(chatReqVO.getSystemPrompt()) + ? PROMPT + : chatReqVO.getSystemPrompt() + " \n " + PROMPT; + } + String mess = systemPrompt + " \n " + knowledgeBaseString; + + if (chatReqVO.getKnowledge() != null) { + log.info("不存在聊天历史记录,创建新的系统消息"); + ModelCompletionsModalReqVO.ModelCompletionsMessageModal systemMessage = new ModelCompletionsModalReqVO.ModelCompletionsMessageModal(); + systemMessage.setRole("system"); + com.alibaba.fastjson.JSONArray jsonarray=new com.alibaba.fastjson.JSONArray(); + jsonarray.add(mess); + systemMessage.setContent(jsonarray); + stringRedisTemplate.opsForList().rightPush(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), JsonUtils.toJsonString(systemMessage)); +// messages.add(systemMessage); + } else { + // 查询历史记录消息,并将查询出来的知识信息放入到 role = system 的消息中 + List messageHistoryList = stringRedisTemplate.opsForList().range(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), 0, -1); + if (messageHistoryList != null && !messageHistoryList.isEmpty()) { + log.info("存在聊天历史记录,处理历史记录消息"); + for (String messageHistory : messageHistoryList) { + ModelCompletionsModalReqVO.ModelCompletionsMessageModal modelCompletionsMessage = JsonUtils.parseObject(messageHistory, ModelCompletionsModalReqVO.ModelCompletionsMessageModal.class); + if ("system".equals(modelCompletionsMessage.getRole())) { + com.alibaba.fastjson.JSONArray jsonarray=new com.alibaba.fastjson.JSONArray(); + jsonarray.add(mess); + modelCompletionsMessage.setContent(jsonarray); + stringRedisTemplate.opsForList().set(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), 0, JsonUtils.toJsonString(modelCompletionsMessage)); + } +// messages.add(modelCompletionsMessage); + } + } +// else { +// log.info("不存在聊天历史记录,创建新的系统消息"); +// ModelCompletionsReqVO.ModelCompletionsMessage systemMessage = new ModelCompletionsReqVO.ModelCompletionsMessage(); +// systemMessage.setRole("system"); +// systemMessage.setContent(mess); +// stringRedisTemplate.opsForList().rightPush(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), JsonUtils.toJsonString(systemMessage)); +// messages.add(systemMessage); +// } + } + + + // 创建用户消息 + ModelCompletionsModalReqVO.ModelCompletionsMessageModal message = new ModelCompletionsModalReqVO.ModelCompletionsMessageModal(); + message.setRole("user"); + com.alibaba.fastjson.JSONArray contentJsonArray=new com.alibaba.fastjson.JSONArray(); + JSONObject textcontentJson=new JSONObject(); + textcontentJson.put("type","text"); + String msg=""; + if(!"".equals(systemPrompt)){ + msg=msg+systemPrompt; + } + if(!"".equals(knowledgeBaseString)){ + msg=msg+"知识信息:{"+knowledgeBaseString+"}"; + } + textcontentJson.put("text",msg+chatReqVO.getPrompt()); + contentJsonArray.add(textcontentJson); + List imagesList = chatReqVO.getImagesList(); + if(imagesList!=null&&imagesList.size()>0){ + JSONObject imagecontentJson=new JSONObject(); + imagecontentJson.put("type","image_url"); + JSONObject imageurljson=new JSONObject(); + imageurljson.put("url",imagesList.get(0)); + imagecontentJson.put("image_url",imageurljson); + contentJsonArray.add(imagecontentJson); + } + message.setContent(contentJsonArray); + messages.add(message); + + // 构建模型补全请求对象 + ModelCompletionsModalReqVO modelCompletionsReqVO = new ModelCompletionsModalReqVO(); + modelCompletionsReqVO.setMessages(messages); + modelCompletionsReqVO.setModel(model); + modelCompletionsReqVO.setTemperature(chatReqVO.getTemperature()); + modelCompletionsReqVO.setTop_p(chatReqVO.getTopP()); + modelCompletionsReqVO.setMax_tokens(chatReqVO.getMaxTokens()); + // log.info("构建模型补全请求对象,请求参数1: {}", modelCompletionsReqVO); + System.out.println("-----------------整体请求参数"+JSONObject.toJSON(modelCompletionsReqVO)); + // 调用模型服务进行流式处理 + ModelCompletionsRespVO modelCompletionsRespVO = modelService.modelCompletionsStreamModal(selfModelUrl, modelCompletionsReqVO, emitter, chatReqVO.getUuid(), chatReqVO.getGroupId(), knowledgeBaseString); + if (modelCompletionsRespVO == null) { + throw exception(MODEL_COMPLETIONS_ERROR); + } + // 将用户消息存入缓存 + stringRedisTemplate.opsForList().rightPush(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), JsonUtils.toJsonString(message)); + ModelCompletionsReqVO.ModelCompletionsMessage responseMessage = new ModelCompletionsReqVO.ModelCompletionsMessage(); + responseMessage.setRole("assistant"); + responseMessage.setContent(modelCompletionsRespVO.getAnswer()); + stringRedisTemplate.opsForList().rightPush(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), JsonUtils.toJsonString(responseMessage)); + // 保存数据回流信息 + DataRefluxDataSaveReqVO dataRefluxDataSaveReqVO = new DataRefluxDataSaveReqVO(); + dataRefluxDataSaveReqVO.setModelServiceId(chatReqVO.getModelId()); + dataRefluxDataSaveReqVO.setModelType(chatReqVO.getModelType()); + dataRefluxDataSaveReqVO.setPrompt(chatReqVO.getPrompt()); + dataRefluxDataSaveReqVO.setSystem(modelCompletionsRespVO.getSystem()); + dataRefluxDataSaveReqVO.setResponse(modelCompletionsRespVO.getAnswer().replaceAll("(?s).*?", "").trim()); + dataRefluxDataSaveReqVO.setMaxTokens(chatReqVO.getMaxTokens()); + dataRefluxDataSaveReqVO.setTemperature(chatReqVO.getTemperature()); + dataRefluxDataService.saveDataRefluxData(dataRefluxDataSaveReqVO); + log.info("数据回流信息保存完成"); + } + @NotNull private StringBuilder getKnowledgeBase(ChatReqVO chatReqVO) { final String LOG_PREFIX = "[KnowledgeBase]"; @@ -582,7 +797,9 @@ public class ConversationServiceImpl implements ConversationService { log.info("{} 知识库构建完成,内容长度: {}", LOG_PREFIX, knowledgeBase.length()); } catch (Exception e) { + log.error("{} 知识库处理异常: {}", LOG_PREFIX, e.getMessage(), e); + e.printStackTrace(); throw new ServiceException(100, "知识库处理失败,请稍后重试"); } diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/dataset/DatasetServiceImpl.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/dataset/DatasetServiceImpl.java index 5155c75af..1247891af 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/dataset/DatasetServiceImpl.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/dataset/DatasetServiceImpl.java @@ -199,6 +199,7 @@ public class DatasetServiceImpl implements DatasetService { List datasetFiles = createReqVO.getDatasetFiles(); // 插入 DatasetDO dataset = BeanUtils.toBean(createReqVO, DatasetDO.class); + dataset.setStatus(2); datasetMapper.insert(dataset); if (CollectionUtils.isNotEmpty(datasetFiles)) { @@ -288,6 +289,7 @@ public class DatasetServiceImpl implements DatasetService { qdo.setQuestion(question); qdo.setCreateTime(LocalDateTime.now()); qdo.setQuestionFrom(questionFrom); + qdo.setStatus(2); datasetQuestionMapper.insert(qdo); //获取回答数据 JSONObject conversationsAnswerJson=conversationsJsonArray.getJSONObject(j+1); diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/dataset/DatasetTaskSyncService.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/dataset/DatasetTaskSyncService.java index 9e749815d..85c34d941 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/dataset/DatasetTaskSyncService.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/dataset/DatasetTaskSyncService.java @@ -34,8 +34,17 @@ public class DatasetTaskSyncService { List datasetList = datasetMapper.selectList(wrapper); log.info("[syncDatasetAigcTask][开始同步任务,数据集数量:{}]", datasetList.size()); datasetList.forEach(datasetDO -> { - List datasetQuestionList = datasetQuestionService.getDatasetQuestionList(datasetDO.getId()); - dataSetService.JsonFileWrite(datasetDO,datasetQuestionList); + Integer datasetParentType = datasetDO.getDatasetParentType(); + //文本数据集 + if(datasetParentType==1){ + List datasetQuestionList = datasetQuestionService.getDatasetQuestionList(datasetDO.getId()); + dataSetService.JsonFileWrite(datasetDO,datasetQuestionList); + }else{ + String dataname=datasetDO.getDatasetName(); + //获取多模态数据集上传zip文件的路径地址 + dataSetService.sendDatasetModal(datasetDO.getId(),dataname); + } + }); } } diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/FineTuningTaskHttpService.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/FineTuningTaskHttpService.java index 632eafa6f..3024df286 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/FineTuningTaskHttpService.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/FineTuningTaskHttpService.java @@ -103,6 +103,42 @@ public class FineTuningTaskHttpService { // 发起 HTTP 请求 log.debug("正在发起 HTTP POST 请求..."); + System.out.println("---------------请求参数"+JSON.toJSONString(req)); + String res = HttpUtils.post(requestUrl, headers, JSON.toJSONString(req)); + log.info("HTTP 请求完成。响应内容: {}", res); + + // 解析响应 + log.debug("正在解析响应内容..."); + AigcRespVO aigcRespVO = JSON.parseObject(res, AigcRespVO.class); + AigcFineTuningCreateRespVO aigcFineTuningCreateRespVO = JSON.parseObject(res, AigcFineTuningCreateRespVO.class); + log.info("响应解析完成。微调任务创建结果: {}", JSON.toJSONString(aigcFineTuningCreateRespVO)); + + // 返回结果 + return aigcFineTuningCreateRespVO; + + } catch (Exception e) { + log.error("创建微调任务时发生异常。请求URL: {}", requestUrl, e); + handleHttpException(e); + } + return null; + } + + public AigcFineTuningCreateRespVO finetuningCreateModal (Map headers, String url, AigcFineTuningCreateReqVO req) { + // login(headers); + // TODO: 在上个方法中已经将数据集的文件id赋予,调试时需要写死再放开 + // String fileId = "6237ed4d-a046-479c-80d6-8579a0283994"; + // req.setFileId(fileId); + String requestUrl = url + llmBackendProperties.getFinetuningCreateModal(); + try { + // 记录请求信息 + log.info("开始创建微调任务,请求URL: {}", requestUrl); + log.info("请求头: {}", headers); + log.info("请求体: {}", JSON.toJSONString(req)); + + // 发起 HTTP 请求 + log.debug("正在发起 HTTP POST 请求..."); + log.debug("请求参数为:---------------------------------"+JSON.toJSONString(req)); + System.out.println("请求参数为:---------------------------------"+JSON.toJSONString(req)); String res = HttpUtils.post(requestUrl, headers, JSON.toJSONString(req)); log.info("HTTP 请求完成。响应内容: {}", res); diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/ModelService.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/ModelService.java index 27cefc1f7..b300e93a2 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/ModelService.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/ModelService.java @@ -22,7 +22,7 @@ import org.apache.http.impl.client.HttpClients; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; - +import com.alibaba.fastjson.parser.Feature; import javax.annotation.Resource; import java.io.BufferedReader; import java.io.IOException; @@ -216,6 +216,169 @@ public class ModelService { return respVO; } + + public ModelCompletionsRespVO modelCompletionsStreamModal (String url, ModelCompletionsModalReqVO req, SseEmitter emitter, String uuid, String groupId,String knowledgeBaseString) { + req.setStream(true); + log.info("开始处理模型补全请求"); + + // 检查模型是否为空,若为空则设置默认模型 + if (StringUtils.isBlank(req.getModel())) { + log.debug("模型ID为空,设置为默认模型: {}", DEFAULT_MODEL_ID); + req.setModel(DEFAULT_MODEL_ID); + } + + // 记录请求信息 + log.info("请求参数: {}", JSON.toJSONString(req)); + if (StringUtils.isBlank(url)) { + log.info("URL为空,使用默认URL: {}", llmBackendProperties.getModelCompletions()); + url = llmBackendProperties.getModelCompletions(); + } else { + log.info("使用指定URL: {}", url); + } + + String answer = ""; + try { + String jsonString = JSON.toJSONString(req); + JSONObject reqjson = new JSONObject(true); + reqjson.put("model", req.getModel()); + + JSONArray messageJsonArray = new JSONArray(); + List messages = req.getMessages(); + ModelCompletionsModalReqVO.ModelCompletionsMessageModal modelCompletionsMessageModal = messages.get(0); + + JSONObject messagejson = new JSONObject(true); + messagejson.put("role", modelCompletionsMessageModal.getRole()); + +// content 保持字段顺序:type > text > image_url + JSONArray contentjsonarray = new JSONArray(); + JSONArray contentJsonArray = modelCompletionsMessageModal.getContent(); + + for (int i = 0; i < contentJsonArray.size(); i++) { + JSONObject jsonObject = contentJsonArray.getJSONObject(i); + + // 用 LinkedHashMap 保证字段顺序 + Map orderedContent = new LinkedHashMap<>(); + + if (jsonObject.containsKey("type")) { + orderedContent.put("type", jsonObject.getString("type")); + } + if (jsonObject.containsKey("text")) { + orderedContent.put("text", jsonObject.getString("text")); + } + if (jsonObject.containsKey("image_url")) { + JSONObject imageUrl = jsonObject.getJSONObject("image_url"); + orderedContent.put("image_url", imageUrl); + } + + // 创建顺序保留的 JSONObject + JSONObject orderedJsonObject = new JSONObject(orderedContent); + contentjsonarray.add(orderedJsonObject); + } + + messagejson.put("content", contentjsonarray); + messageJsonArray.add(messagejson); + + reqjson.put("messages", messageJsonArray); + reqjson.put("max_tokens", req.getMax_tokens()); + reqjson.put("temperature", req.getTemperature()); + reqjson.put("top_p",req.getTop_p()); + String reqparam=JSON.toJSONString(reqjson); + answer = sendPostRequest(url, reqparam, emitter, uuid, groupId,knowledgeBaseString); + } catch (Exception e) { + emitter.completeWithError(e); + + } + + // + // // 解析响应内容 + // log.info("正在解析响应内容..."); + // ChatCompletion chatCompletion = JSON.parseObject(result, ChatCompletion.class); + // + // // 检查响应内容是否包含错误信息 + // if (StringUtils.isBlank(chatCompletion.getDetail())) { + // log.info("响应内容无错误信息,提取回答内容..."); + // + // // 提取回答内容 + // String respContent = chatCompletion.getChoices().get(0).getMessage().getContent(); + // String patternString = "(.*?)"; + // Pattern pattern = Pattern.compile(patternString, Pattern.DOTALL); + // Matcher matcher = pattern.matcher(respContent); + // String answerContent = matcher.replaceAll(""); + // + // // 构建返回对象 + // ModelCompletionsRespVO respVO = new ModelCompletionsRespVO(); + // respVO.setSystem("助手"); + // respVO.setQuestion(req.getMessages().get(req.getMessages().size() - 1).getContent()); + // respVO.setAnswer(answer); + // + // log.info("模型补全请求处理成功。返回结果: {}", JSON.toJSONString(respVO)); + // return respVO; + // + // } else { + // log.warn("响应内容包含错误信息,返回 null"); + // return null; + // } + // return null; + + // 构建返回对象 + ModelCompletionsRespVO respVO = new ModelCompletionsRespVO(); + respVO.setSystem("助手"); + respVO.setQuestion(req.getMessages().get(req.getMessages().size() - 1).getContent().getString(0)); + respVO.setAnswer(answer); + + return respVO; + } + + + public static void main(String[] args) { + String a="{\"max_tokens\":1024,\"temperature\":0.7,\"messages\":[{\"role\":\"user\",\"content\":[{\"text\":\"Use the following context as your learned knowledge, inside XML tags.When answer to user:\\\\n- If you don't know, just say that you don't know.\\\\n- If you don't know when you are not sure, ask for clarification.\\\\nAvoid mentioning that you obtained the information from the context.\\\\nAnd answer according to the language of the user's question.\\\\n\\\\n知识信息:{39(十)消除影响、恢复名誉; \\n(十一)赔礼道歉。 \\n法律规定惩罚性赔偿的,依照其规定。 \\n本条规定的承担民事责任的方式,可以单独适用,也可以合\\n并适用。 \\n第一百八十条 因不可抗力不能履行民事义务的,不承担民\\n事责任。法律另有规定的,依照其规定。 \\n不可抗力是不能预见、不能避免 且不能克服的客观情况。 \\n第一百八十一条 因正当防 卫造成损害的,不承担民事责任。 \\n正当防卫超过必要的限度,造成不应有的损害的,正当防卫\\n人应当承担适当的民事责任。 \\n第一百八十二条 因紧急避 险造成损害的,由引起险情发生\\n的人承担民事责任。 \\n危险由自然原因引起的,紧急避险人不承担民事责任,可以\\n给予适当补偿。 \\n紧急避险采取措施不当或者超过 必要的限度,造成不应有的\\n损害的,紧急避险人应当承担适当的民事责任。 \\n第一百八十三条 因保护他 人民事权益使自己受到损害的,\\n由侵权人承担民事责任, 受益人可以给予适当补偿。 没有侵权人、\\n侵权人逃逸或者无力承担民事责 任,受害人请求补偿的,受益人\\n应当给予适当补偿。 \\n第一百八十四条 因自愿实 施紧急救助行为造成受助人损害218承担侵权责任。 \\n第一千一百七十六条 自愿参加具有一定风险的文体活动,\\n因其他参加者的行为受到损害的 ,受害人不得请求其他参加者承\\n担侵权责任;但是,其他参加者 对损害的发生有故意或者重大过\\n失的除外。 \\n活动组织者的责任适用本法第一 千一百九十八条至第一千\\n二百零一条的规定。 \\n第一千一百七十七条 合法权益受到侵害,情况紧迫且不能\\n及时获得国家机关保护,不立即 采取措施将使其合法权益受到难\\n以弥补的损害的,受害人可以在 保护自己合法权益的必要范围内\\n采取扣留侵权人的财物等合理措 施;但是,应当立即请求有关国\\n家机关处理。 \\n受害人采取的措施不当造成他人 损害的,应当承担侵权责\\n任。 \\n第一千一百七十八条 本法和其他法律对不承担责任或者减\\n轻责任的情形另有规定的,依照其规定。 \\n第二章 损害赔偿 \\n第一千一百七十九条 侵害他人造成人身损害的,应当赔偿\\n医疗费、护理费、交通费、营养 费、住院伙食补助费等为治疗和\\n康复支出的合理费用,以及因误 工减少的收入。造成残疾的,还\\n应当赔偿辅助器具费和残疾赔偿 金;造成死亡的,还应当赔偿丧\\n葬费和死亡赔偿金。38第八章 民事责任 \\n第一百七十六条 民事主体 依照法律规定或者按照当事人约\\n定,履行民事义务,承担民事责任。 \\n第一百七十七条 二人以上 依法承担按份责任,能够确定责\\n任大小的,各自承担相应的责任 ;难以确定责任大小的,平均承\\n担责任。 \\n第一百七十八条 二人以上 依法承担连带责任的,权利人有\\n权请求部分或者全部连带责任人承担责任。 \\n连带责任人的责任份额根据各自责任大小确定;难以确定责\\n任大小的,平均承担责任。实际 承担责任超过自己责任份额的连\\n带责任人,有权向其他连带责任人追偿。 \\n连带责任,由法律规定或者当事人约定。 \\n第一百七十九条 承担民事责任的方式主要有: \\n(一)停止侵害; \\n(二)排除妨碍; \\n(三)消除危险; \\n(四)返还财产; \\n(五)恢复原状; \\n(六)修理、重作、更换; \\n(七)继续履行; \\n(八)赔偿损失; \\n(九)支付违约金;217第一千一百六十八条 二人以上共同实施侵权行为,造成他\\n人损害的,应当承担连带责任。 \\n第一千一百六十九条 教唆、帮助他人实施侵权行为的,应\\n当与行为人承担连带责任。 \\n教唆、帮助无民事行为能力人、限制民事行为能力人实施侵\\n权行为的,应当承担侵权责任; 该无民事行为能力人、限制民事\\n行为能力人的监护人未尽到监护职责的 ,应当承担相应的责任。 \\n第一千一百七十条 二人以 上实施危及他人人身、财产安全\\n的行为,其中一人或者数人的行 为造成他人损害,能够确定具体\\n侵权人的,由侵权人承担责任; 不能确定具体侵权人的,行为人\\n承担连带责任。 \\n第一千一百七十一条 二人以上分别实施侵权行为造成同一\\n损害,每个人的侵权行为都足以 造成全部损害的,行为人承担连\\n带责任。 \\n第一千一百七十二条 二人以上分别实施侵权行为造成同一\\n损害,能够确定责任大小的,各 自承担相应的责任;难以确定责\\n任大小的,平均承担责任。 \\n第一千一百七十三条 被侵权人对同一损害的发生或者扩大\\n有过错的,可以减轻侵权人的责任。 \\n第一千一百七十四条 损害是因受害人故意造成的,行为人\\n不承担责任。 \\n第一千一百七十五条 损害是因第三人造成的,第三人应当}正当防卫\",\"type\":\"text\"},{\"image_url\":{\"url\":\"http://221.238.217.216:4185/api/v1/buckets/xhllm/objects/download?prefix=/0b7e46efb27c8a14379fcf47e9baef935896e768ad8e98f3b38bf48de9004d3d.jpg\"},\"type\":\"image_url\"}]}],\"model\":\"Qwen2.5-VL-7B-Instruct\"}"; + JSONObject jo=JSONObject.parseObject(a); + ModelCompletionsModalReqVO req = JSONObject.toJavaObject(jo, ModelCompletionsModalReqVO.class); + JSONObject reqjson = new JSONObject(true); + reqjson.put("model", req.getModel()); + + JSONArray messageJsonArray = new JSONArray(); + List messages = req.getMessages(); + ModelCompletionsModalReqVO.ModelCompletionsMessageModal modelCompletionsMessageModal = messages.get(0); + + JSONObject messagejson = new JSONObject(true); + messagejson.put("role", modelCompletionsMessageModal.getRole()); + +// content 保持字段顺序:type > text > image_url + JSONArray contentjsonarray = new JSONArray(); + JSONArray contentJsonArray = modelCompletionsMessageModal.getContent(); + + for (int i = 0; i < contentJsonArray.size(); i++) { + JSONObject jsonObject = contentJsonArray.getJSONObject(i); + + // 用 LinkedHashMap 保证字段顺序 + Map orderedContent = new LinkedHashMap<>(); + + if (jsonObject.containsKey("type")) { + orderedContent.put("type", jsonObject.getString("type")); + } + if (jsonObject.containsKey("text")) { + orderedContent.put("text", jsonObject.getString("text")); + } + if (jsonObject.containsKey("image_url")) { + orderedContent.put("image_url", jsonObject.getString("image_url")); + } + + // 创建顺序保留的 JSONObject + JSONObject orderedJsonObject = new JSONObject(orderedContent); + contentjsonarray.add(orderedJsonObject); + } + + messagejson.put("content", contentjsonarray); + messageJsonArray.add(messagejson); + + reqjson.put("messages", messageJsonArray); + reqjson.put("max_tokens", req.getMax_tokens()); + reqjson.put("temperature", req.getTemperature()); + System.out.println(JSON.toJSONString(reqjson)); + } + + /** * 发送 POST 请求并处理响应 * diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/RagHttpService.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/RagHttpService.java index b31fc85a8..2789f729f 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/RagHttpService.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/RagHttpService.java @@ -777,14 +777,14 @@ public class RagHttpService { // 遍历 JSON 数组 for (int i = 0; i < jsonArray.size(); i++) { - JSONArray pairArray = jsonArray.getJSONArray(i); + JSONObject jsonObject = jsonArray.getJSONObject(i); // 解析文档信息 - JSONObject documentJson = pairArray.getJSONObject(0); - DocumentInfoVO document = JSON.parseObject(documentJson.toJSONString(), DocumentInfoVO.class); +// JSONObject documentJson = jsonArray.getJSONObject(0); + DocumentInfoVO document = JSON.parseObject(jsonObject.toJSONString(), DocumentInfoVO.class); // 解析命中率 - Double rate = pairArray.getDoubleValue(1); + Double rate = jsonObject.getDoubleValue("score"); if (rate >= score) { QueryResultPairVO pair = new QueryResultPairVO(); @@ -805,6 +805,61 @@ public class RagHttpService { return results; } +// private static List parseHitRateTestResults (String json, Double score) { +// boolean array = json.trim().startsWith("["); +// // 先判断 JSON 是否是一个数组 +// +// if (!array) { +// // 判断是否存在 detail 字段 +// JSONObject jsonObject = JSON.parseObject(json); +// if (jsonObject.containsKey("detail")) { +// String detail = jsonObject.getString("detail"); +// +// if (detail.contains("No documents found for the given query")) { +// throw exception(new ErrorCode(100_100_1, "未找到符合条件的文档,请检查查询条件!")); +// } +// return new ArrayList<>(); +// } +// } +// +// +// // 将 JSON 转换为 List +// // 解析 JSON 数组 +// JSONArray jsonArray = JSON.parseArray(json); +// +// // 创建结果列表 +// List results = new ArrayList<>(); +// +// // 遍历 JSON 数组 +// for (int i = 0; i < jsonArray.size(); i++) { +// JSONArray pairArray = jsonArray.getJSONArray(i); +// +// // 解析文档信息 +// JSONObject documentJson = pairArray.getJSONObject(0); +// DocumentInfoVO document = JSON.parseObject(documentJson.toJSONString(), DocumentInfoVO.class); +// +// // 解析命中率 +// Double rate = pairArray.getDoubleValue(1); +// +// if (rate >= score) { +// QueryResultPairVO pair = new QueryResultPairVO(); +// pair.setDocument(document); +// pair.setHitRate(rate); +// results.add(pair); +// } +// +// } +// +// // // 访问数据 +// // for (QueryResultPairVO pair : results) { +// // System.out.println("Page Content: " + pair.getDocument().getPageContent()); +// // System.out.println("Hit Rate: " + pair.getHitRate()); +// // System.out.println("File ID: " + pair.getDocument().getMetadata().getFileId()); +// // System.out.println("----------------------"); +// // } +// +// return results; +// } public static void main (String[] args) { List ids = new ArrayList<>(); diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsModalReqVO.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsModalReqVO.java new file mode 100644 index 000000000..4c3a92413 --- /dev/null +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsModalReqVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.llm.service.http.vo; + +import com.alibaba.fastjson.JSONArray; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class ModelCompletionsModalReqVO { + + private String model; + private List messages; + private Integer max_tokens; + private Double temperature; + private Double top_p; + private Boolean stream; + + + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class ModelCompletionsMessageModal { + + private String role; + private JSONArray content; + + } +} diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsModalRespVO.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsModalRespVO.java new file mode 100644 index 000000000..7334e3176 --- /dev/null +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsModalRespVO.java @@ -0,0 +1,11 @@ +package cn.iocoder.yudao.module.llm.service.http.vo; + +import lombok.Data; + +@Data +public class ModelCompletionsModalRespVO { + + private String system; + private String question; + private String answer; +} diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsReqVO.java b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsReqVO.java index c2801e3fd..5396dace7 100644 --- a/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsReqVO.java +++ b/yudao-module-llm/yudao-module-llm-biz/src/main/java/cn/iocoder/yudao/module/llm/service/http/vo/ModelCompletionsReqVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.llm.service.http.vo; +import com.alibaba.fastjson.JSONArray; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/yudao-module-llm/yudao-module-llm-biz/src/main/resources/file/dataset_example/VL_test.zip b/yudao-module-llm/yudao-module-llm-biz/src/main/resources/file/dataset_example/VL_test.zip new file mode 100644 index 000000000..ac236e972 Binary files /dev/null and b/yudao-module-llm/yudao-module-llm-biz/src/main/resources/file/dataset_example/VL_test.zip differ diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 9c2810514..f18687fce 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -54,13 +54,12 @@ spring: url: jdbc:mysql://221.238.217.216:4156/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true username: root password: 123456 - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 redis: host: 127.0.0.1 # 地址 port: 6379 # 端口 database: 0 # 数据库索引 -# password: dev # 密码,建议生产环境开启 + password: 123456 # 密码,建议生产环境开启 --- #################### 定时任务相关配置 #################### @@ -247,6 +246,7 @@ justauth: llm: backend: #################### 8123: RAG服务、训练集和标注相关API。 ################### + dataset_more_modal_api: http://221.238.217.216:4143/api/VL_files ### RAG服务 request_address: http://221.238.217.216:4143 #RAG健康检查 GET @@ -307,6 +307,7 @@ llm: # 微调文件上传 aigc_file_upload: /api/files finetuning_create: /llm/finetuning + finetuning_create_modal: /llm/finetuning-mm # 日志获取 finetuning_log: /llm/get_log # 开始部署