diff --git a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiChatRoleEnum.java b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiChatRoleEnum.java
index 811189efe..029961bf3 100644
--- a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiChatRoleEnum.java
+++ b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiChatRoleEnum.java
@@ -1,11 +1,8 @@
package cn.iocoder.yudao.module.ai.enums;
-import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
-import java.util.Arrays;
-
/**
* AI 内置聊天角色的枚举
*
@@ -13,16 +10,16 @@ import java.util.Arrays;
*/
@AllArgsConstructor
@Getter
-public enum AiChatRoleEnum implements IntArrayValuable {
+public enum AiChatRoleEnum {
- AI_WRITE_ROLE(1, "写作助手", """
+ AI_WRITE_ROLE("写作助手", """
你是一位出色的写作助手,能够帮助用户生成创意和灵感,并在用户提供场景和提示词时生成对应的回复。你的任务包括:
1. 撰写建议:根据用户提供的主题或问题,提供详细的写作建议、情节发展方向、角色设定以及背景描写,确保内容结构清晰、有逻辑。
2. 回复生成:根据用户提供的场景和提示词,生成合适的对话或文字回复,确保语气和风格符合场景需求。
除此之外不需要除了正文内容外的其他回复,如标题、开头、任何解释性语句或道歉。
"""),
- AI_MIND_MAP_ROLE(2, "导图助手", """
+ AI_MIND_MAP_ROLE("导图助手", """
你是一位非常优秀的思维导图助手,你会把用户的所有提问都总结成思维导图,然后以 Markdown 格式输出。markdown 只需要输出一级标题,二级标题,三级标题,四级标题,最多输出四级,除此之外不要输出任何其他 markdown 标记。下面是一个合格的例子:
# Geek-AI 助手
## 完整的开源系统
@@ -39,11 +36,6 @@ public enum AiChatRoleEnum implements IntArrayValuable {
除此之外不要任何解释性语句。
""");
- // TODO @xin:这个 role 是不是删除掉好点哈。= = 目前主要是没做角色枚举。这里多了 role 反倒容易误解哈
- /**
- * 角色
- */
- private final Integer role;
/**
* 角色名
*/
@@ -54,11 +46,4 @@ public enum AiChatRoleEnum implements IntArrayValuable {
*/
private final String systemMessage;
- public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AiChatRoleEnum::getRole).toArray();
-
- @Override
- public int[] array() {
- return ARRAYS;
- }
-
}
diff --git a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java
index 714d49adb..c3158a1aa 100644
--- a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java
+++ b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* AI 错误码枚举类
- *
+ *
* ai 系统,使用 1-040-000-000 段
*/
public interface ErrorCodeConstants {
@@ -55,5 +55,7 @@ public interface ErrorCodeConstants {
// ========== API 知识库 1-022-008-000 ==========
ErrorCode KNOWLEDGE_NOT_EXISTS = new ErrorCode(1_022_008_000, "知识库不存在!");
+ ErrorCode KNOWLEDGE_DOCUMENT_NOT_EXISTS = new ErrorCode(1_022_008_001, "文档不存在!");
+ ErrorCode KNOWLEDGE_SEGMENT_NOT_EXISTS = new ErrorCode(1_022_008_002, "段落不存在!");
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeController.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeController.java
index 9d9c99a9a..a7b49b413 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeController.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeController.java
@@ -1,13 +1,19 @@
package cn.iocoder.yudao.module.ai.controller.admin.knowledge;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeCreateMyReqVO;
-import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeUpdateMyReqVO;
-import cn.iocoder.yudao.module.ai.service.knowledge.AiKnowledgeBaseService;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeCreateMyReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeRespVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeUpdateMyReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDO;
+import cn.iocoder.yudao.module.ai.service.knowledge.AiKnowledgeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
+import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -19,19 +25,27 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
public class AiKnowledgeController {
@Resource
- private AiKnowledgeBaseService knowledgeBaseService;
+ private AiKnowledgeService knowledgeService;
+
+ @GetMapping("/my-page")
+ @Operation(summary = "获取【我的】知识库分页")
+ public CommonResult> getKnowledgePageMy(@Validated PageParam pageReqVO) {
+ PageResult pageResult = knowledgeService.getKnowledgePageMy(getLoginUserId(), pageReqVO);
+ return success(BeanUtils.toBean(pageResult, AiKnowledgeRespVO.class));
+ }
+
@PostMapping("/create-my")
@Operation(summary = "创建【我的】知识库")
public CommonResult createKnowledgeMy(@RequestBody @Valid AiKnowledgeCreateMyReqVO createReqVO) {
- return success(knowledgeBaseService.createKnowledgeMy(createReqVO, getLoginUserId()));
+ return success(knowledgeService.createKnowledgeMy(createReqVO, getLoginUserId()));
}
@PutMapping("/update-my")
@Operation(summary = "更新【我的】知识库")
public CommonResult updateKnowledgeMy(@RequestBody @Valid AiKnowledgeUpdateMyReqVO updateReqVO) {
- knowledgeBaseService.updateKnowledgeMy(updateReqVO, getLoginUserId());
+ knowledgeService.updateKnowledgeMy(updateReqVO, getLoginUserId());
return success(true);
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeDocumentController.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeDocumentController.java
new file mode 100644
index 000000000..58a53a19c
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeDocumentController.java
@@ -0,0 +1,54 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentPageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentRespVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeDocumentCreateReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
+import cn.iocoder.yudao.module.ai.service.knowledge.AiKnowledgeDocumentService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+
+@Tag(name = "管理后台 - AI 知识库-文档")
+@RestController
+@RequestMapping("/ai/knowledge/document")
+public class AiKnowledgeDocumentController {
+
+ @Resource
+ private AiKnowledgeDocumentService documentService;
+
+
+ @PostMapping("/create")
+ @Operation(summary = "新建文档")
+ public CommonResult createKnowledgeDocument(@Validated AiKnowledgeDocumentCreateReqVO reqVO) {
+ Long knowledgeDocumentId = documentService.createKnowledgeDocument(reqVO);
+ return success(knowledgeDocumentId);
+ }
+
+
+ @GetMapping("/page")
+ @Operation(summary = "获取文档分页")
+ public CommonResult> getKnowledgeDocumentPageMy(@Validated AiKnowledgeDocumentPageReqVO pageReqVO) {
+ PageResult pageResult = documentService.getKnowledgeDocumentPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, AiKnowledgeDocumentRespVO.class));
+ }
+
+
+ @PutMapping("/update")
+ @Operation(summary = "更新文档")
+ public CommonResult updateKnowledgeDocument(@Validated @RequestBody AiKnowledgeDocumentUpdateReqVO reqVO) {
+ documentService.updateKnowledgeDocument(reqVO);
+ return success(true);
+ }
+
+
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java
new file mode 100644
index 000000000..a19f38eb7
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java
@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentPageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentRespVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateStatusReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeSegmentDO;
+import cn.iocoder.yudao.module.ai.service.knowledge.AiKnowledgeSegmentService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+
+@Tag(name = "管理后台 - AI 知识库-段落")
+@RestController
+@RequestMapping("/ai/knowledge/segment")
+public class AiKnowledgeSegmentController {
+
+ @Resource
+ private AiKnowledgeSegmentService segmentService;
+
+ @GetMapping("/page")
+ @Operation(summary = "获取段落分页")
+ public CommonResult> getKnowledgeSegmentPageMy(@Validated AiKnowledgeSegmentPageReqVO pageReqVO) {
+ PageResult pageResult = segmentService.getKnowledgeSegmentPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, AiKnowledgeSegmentRespVO.class));
+ }
+
+
+ @PutMapping("/update")
+ @Operation(summary = "更新段落内容")
+ public CommonResult updateKnowledgeSegment(@Validated @RequestBody AiKnowledgeSegmentUpdateReqVO reqVO) {
+ segmentService.updateKnowledgeSegment(reqVO);
+ return success(true);
+ }
+
+ @PutMapping("/update-status")
+ @Operation(summary = "启禁用段落内容")
+ public CommonResult updateKnowledgeSegmentStatus(@Validated @RequestBody AiKnowledgeSegmentUpdateStatusReqVO reqVO) {
+ segmentService.updateKnowledgeSegmentStatus(reqVO);
+ return success(true);
+ }
+
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentPageReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentPageReqVO.java
new file mode 100644
index 000000000..c1e7947f5
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentPageReqVO.java
@@ -0,0 +1,13 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - AI 知识库-文档 分页 Request VO")
+@Data
+public class AiKnowledgeDocumentPageReqVO extends PageParam {
+
+ @Schema(description = "文档名称", example = "Java 开发手册")
+ private String name;
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentRespVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentRespVO.java
new file mode 100644
index 000000000..94a022363
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentRespVO.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - AI 知识库-文档 Response VO")
+@Data
+public class AiKnowledgeDocumentRespVO extends PageParam {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")
+ private Long id;
+
+ @Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")
+ private Long knowledgeId;
+
+ @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "Java 开发手册")
+ private String name;
+
+ @Schema(description = "内容", example = "Java 是一门面向对象的语言.....")
+ private String content;
+
+ @Schema(description = "文档 url", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://doc.iocoder.cn")
+ private String url;
+
+ @Schema(description = "token 数量", example = "1024")
+ private Integer tokens;
+
+ @Schema(description = "字符数", example = "1008")
+ private Integer wordCount;
+
+ @Schema(description = "切片状态", example = "1")
+ private Integer sliceStatus;
+
+ @Schema(description = "文档状态", example = "1")
+ private Integer status;
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentUpdateReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentUpdateReqVO.java
new file mode 100644
index 000000000..6fb42c774
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/document/AiKnowledgeDocumentUpdateReqVO.java
@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+
+@Schema(description = "管理后台 - AI 更新 知识库-文档 Request VO")
+@Data
+public class AiKnowledgeDocumentUpdateReqVO {
+
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15583")
+ @NotNull(message = "编号不能为空")
+ private Long id;
+
+ @Schema(description = "是否启用", example = "1")
+ private Integer status;
+
+ @Schema(description = "名称", example = "Java 开发手册")
+ private String name;
+
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeCreateMyReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeCreateMyReqVO.java
similarity index 98%
rename from yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeCreateMyReqVO.java
rename to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeCreateMyReqVO.java
index ac94a4c15..44a5e87ee 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeCreateMyReqVO.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeCreateMyReqVO.java
@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo;
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeDocumentCreateReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeDocumentCreateReqVO.java
similarity index 90%
rename from yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeDocumentCreateReqVO.java
rename to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeDocumentCreateReqVO.java
index 10ad036b2..660c573ba 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeDocumentCreateReqVO.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeDocumentCreateReqVO.java
@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo;
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
@@ -6,10 +6,8 @@ import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
-/**
- * @author xiaoxin
- */
-@Schema(description = "管理后台 - AI 知识库【创建文档】 Request VO")
+
+@Schema(description = "管理后台 - AI 知识库创建【文档】 Request VO")
@Data
public class AiKnowledgeDocumentCreateReqVO {
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeRespVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeRespVO.java
new file mode 100644
index 000000000..2eb08717e
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeRespVO.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+
+@Schema(description = "管理后台 - AI 知识库 Response VO")
+@Data
+public class AiKnowledgeRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")
+ private Long id;
+
+ @Schema(description = "知识库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "ruoyi-vue-pro 用户指南")
+ private String name;
+
+ @Schema(description = "知识库描述", example = "ruoyi-vue-pro 用户指南")
+ private String description;
+
+ @Schema(description = "模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "14")
+ private Long modelId;
+
+ @Schema(description = "模型标识", example = "qwen-72b-chat")
+ private String model;
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeUpdateMyReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeUpdateMyReqVO.java
similarity index 94%
rename from yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeUpdateMyReqVO.java
rename to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeUpdateMyReqVO.java
index e1f6a31af..987c9bf4a 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/AiKnowledgeUpdateMyReqVO.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/knowledge/AiKnowledgeUpdateMyReqVO.java
@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo;
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
@@ -7,7 +7,7 @@ import lombok.Data;
import java.util.List;
-@Schema(description = "管理后台 - AI 知识库创建【我的】 Request VO")
+@Schema(description = "管理后台 - AI 知识库更新【我的】 Request VO")
@Data
public class AiKnowledgeUpdateMyReqVO {
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentPageReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentPageReqVO.java
new file mode 100644
index 000000000..125cb80b1
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentPageReqVO.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - AI 知识库分页 Request VO")
+@Data
+public class AiKnowledgeSegmentPageReqVO extends PageParam {
+
+
+ @Schema(description = "分段状态", example = "1")
+ private Integer status;
+
+ @Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Integer documentId;
+
+ @Schema(description = "分段内容关键字", example = "Java 开发")
+ private String keyword;
+
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentRespVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentRespVO.java
new file mode 100644
index 000000000..d8411618b
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentRespVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - AI 知识库-文档 Response VO")
+@Data
+public class AiKnowledgeSegmentRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")
+ private Long id;
+
+ @Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")
+ private Long documentId;
+
+ @Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")
+ private Long knowledgeId;
+
+ @Schema(description = "向量库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1858496a-1dde-4edf-a43e-0aed08f37f8c")
+ private String vectorId;
+
+ @Schema(description = "切片内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "Java 开发手册")
+ private String content;
+
+ @Schema(description = "token 数量", example = "1024")
+ private Integer tokens;
+
+ @Schema(description = "字符数", example = "1008")
+ private Integer wordCount;
+
+ @Schema(description = "文档状态", example = "1")
+ private Integer status;
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateReqVO.java
new file mode 100644
index 000000000..23b1461e2
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateReqVO.java
@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+
+@Schema(description = "管理后台 - AI 更新 知识库-段落 request VO")
+@Data
+public class AiKnowledgeSegmentUpdateReqVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")
+ private Long id;
+
+ @Schema(description = "切片内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "Java 开发手册")
+ private String content;
+
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateStatusReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateStatusReqVO.java
new file mode 100644
index 000000000..409ce0146
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateStatusReqVO.java
@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+
+@Schema(description = "管理后台 - AI 更新 知识库-段落 request VO")
+@Data
+public class AiKnowledgeSegmentUpdateStatusReqVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")
+ private Long id;
+
+ @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Integer status;
+
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeBaseDO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeDO.java
similarity index 77%
rename from yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeBaseDO.java
rename to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeDO.java
index d33114f2d..756d8cdb3 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeBaseDO.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeDO.java
@@ -10,15 +10,14 @@ import lombok.Data;
import java.util.List;
-// TODO @xin:要不把 AiKnowledgeBaseDO 改成 AiKnowledgeDO。感觉 base 后缀,感觉有点奇怪(让人以为是基类)。然后,我们很多地方的外键编号,都是 knowledgeId
/**
* AI 知识库 DO
*
* @author xiaoxin
*/
-@TableName(value = "ai_knowledge_base", autoResultMap = true)
+@TableName(value = "ai_knowledge", autoResultMap = true)
@Data
-public class AiKnowledgeBaseDO extends BaseDO {
+public class AiKnowledgeDO extends BaseDO {
/**
* 编号
@@ -46,7 +45,7 @@ public class AiKnowledgeBaseDO extends BaseDO {
@TableField(typeHandler = JacksonTypeHandler.class)
private List visibilityPermissions;
/**
- * 嵌入模型编号,高质量模式时维护
+ * 嵌入模型编号
*/
private Long modelId;
/**
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeDocumentDO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeDocumentDO.java
index 486602509..c5e526cce 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeDocumentDO.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeDocumentDO.java
@@ -24,7 +24,7 @@ public class AiKnowledgeDocumentDO extends BaseDO {
/**
* 知识库编号
*
- * 关联 {@link AiKnowledgeBaseDO#getId()}
+ * 关联 {@link AiKnowledgeDO#getId()}
*/
private Long knowledgeId;
/**
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeSegmentDO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeSegmentDO.java
index 2032bfd5e..fc758ce31 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeSegmentDO.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/knowledge/AiKnowledgeSegmentDO.java
@@ -15,6 +15,8 @@ import lombok.Data;
@Data
public class AiKnowledgeSegmentDO extends BaseDO {
+ public static final String FIELD_KNOWLEDGE_ID = "knowledgeId";
+
/**
* 编号
*/
@@ -24,10 +26,14 @@ public class AiKnowledgeSegmentDO extends BaseDO {
* 向量库的编号
*/
private String vectorId;
- // TODO @新:knowledgeId 加个,会方便点
+ /**
+ * 知识库编号
+ * 关联 {@link AiKnowledgeDO#getId()}
+ */
+ private Long knowledgeId;
/**
* 文档编号
- *
+ *
* 关联 {@link AiKnowledgeDocumentDO#getId()}
*/
private Long documentId;
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeBaseMapper.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeBaseMapper.java
deleted file mode 100644
index cad90fcfe..000000000
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeBaseMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package cn.iocoder.yudao.module.ai.dal.mysql.knowledge;
-
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeBaseDO;
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * AI 知识库基础信息 Mapper
- *
- * @author xiaoxin
- */
-@Mapper
-public interface AiKnowledgeBaseMapper extends BaseMapperX {
-}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeDocumentMapper.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeDocumentMapper.java
index af55f545a..7692d1ced 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeDocumentMapper.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeDocumentMapper.java
@@ -1,6 +1,9 @@
package cn.iocoder.yudao.module.ai.dal.mysql.knowledge;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentPageReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
import org.apache.ibatis.annotations.Mapper;
@@ -11,4 +14,11 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface AiKnowledgeDocumentMapper extends BaseMapperX {
+
+ default PageResult selectPage(AiKnowledgeDocumentPageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .likeIfPresent(AiKnowledgeDocumentDO::getName, reqVO.getName())
+ .orderByDesc(AiKnowledgeDocumentDO::getId));
+ }
+
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeMapper.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeMapper.java
new file mode 100644
index 000000000..2bf23411a
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeMapper.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.ai.dal.mysql.knowledge;
+
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * AI 知识库基础信息 Mapper
+ *
+ * @author xiaoxin
+ */
+@Mapper
+public interface AiKnowledgeMapper extends BaseMapperX {
+
+ default PageResult selectPageByMy(Long userId, PageParam pageReqVO) {
+ return selectPage(pageReqVO, new LambdaQueryWrapperX()
+ .eq(AiKnowledgeDO::getUserId, userId)
+ .eq(AiKnowledgeDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
+ .orderByDesc(AiKnowledgeDO::getId));
+ }
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeSegmentMapper.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeSegmentMapper.java
index 5043ee0ca..912d18cbc 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeSegmentMapper.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeSegmentMapper.java
@@ -1,6 +1,9 @@
package cn.iocoder.yudao.module.ai.dal.mysql.knowledge;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentPageReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeSegmentDO;
import org.apache.ibatis.annotations.Mapper;
@@ -11,4 +14,12 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface AiKnowledgeSegmentMapper extends BaseMapperX {
+
+ default PageResult selectPage(AiKnowledgeSegmentPageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .eq(AiKnowledgeSegmentDO::getDocumentId, reqVO.getDocumentId())
+ .eqIfPresent(AiKnowledgeSegmentDO::getStatus, reqVO.getStatus())
+ .likeIfPresent(AiKnowledgeSegmentDO::getContent, reqVO.getKeyword())
+ .orderByDesc(AiKnowledgeSegmentDO::getId));
+ }
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiEmbeddingService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiEmbeddingService.java
deleted file mode 100644
index ee4b3d03c..000000000
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiEmbeddingService.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.module.ai.service.knowledge;
-
-import org.springframework.ai.document.Document;
-import org.springframework.ai.vectorstore.SearchRequest;
-
-import java.util.List;
-
-/**
- * AI 嵌入 Service 接口
- *
- * @author xiaoxin
- */
-public interface AiEmbeddingService {
-
- /**
- * 向量化文档并存储
- */
- void add(List documents);
-
- /**
- * 相似查询
- *
- * @param request 查询实体
- */
- List similaritySearch(SearchRequest request);
-
-}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiEmbeddingServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiEmbeddingServiceImpl.java
deleted file mode 100644
index 689ccea03..000000000
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiEmbeddingServiceImpl.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package cn.iocoder.yudao.module.ai.service.knowledge;
-
-import jakarta.annotation.Resource;
-import org.springframework.ai.document.Document;
-import org.springframework.ai.vectorstore.RedisVectorStore;
-import org.springframework.ai.vectorstore.SearchRequest;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-// TODO @xin:是不是不用 AiEmbeddingServiceImpl,直接 vectorStore 注入到需要的地方就好啦。通过 KnowledgeDocumentService 返回就好。
-/**
- * AI 嵌入 Service 实现类
- *
- * @author xiaoxin
- */
-@Service
-public class AiEmbeddingServiceImpl implements AiEmbeddingService {
-
- @Resource
- private RedisVectorStore vectorStore;
-
- @Override
-// @Async
- // TODO xiaoxin 报错先注释
- public void add(List documents) {
- vectorStore.add(documents);
- }
-
- @Override
- public List similaritySearch(SearchRequest request) {
- return vectorStore.similaritySearch(request);
- }
-
-}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeBaseService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeBaseService.java
deleted file mode 100644
index be96b0918..000000000
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeBaseService.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.ai.service.knowledge;
-import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeCreateMyReqVO;
-import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeUpdateMyReqVO;
-
-/**
- * AI 知识库-基础信息 Service 接口
- *
- * @author xiaoxin
- */
-public interface AiKnowledgeBaseService {
-
- /**
- * 创建【我的】知识库
- *
- * @param createReqVO 创建信息
- * @param userId 用户编号
- * @return 编号
- */
- Long createKnowledgeMy(AiKnowledgeCreateMyReqVO createReqVO, Long userId);
-
-
- /**
- * 创建【我的】知识库
- *
- * @param updateReqVO 更新信息
- * @param userId 用户编号
- */
- void updateKnowledgeMy(AiKnowledgeUpdateMyReqVO updateReqVO, Long userId);
-
-}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java
index 82c4f7b91..3de0ac01d 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java
@@ -1,6 +1,10 @@
package cn.iocoder.yudao.module.ai.service.knowledge;
-import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeDocumentCreateReqVO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentPageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeDocumentCreateReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
/**
* AI 知识库-文档 Service 接口
@@ -17,4 +21,19 @@ public interface AiKnowledgeDocumentService {
*/
Long createKnowledgeDocument(AiKnowledgeDocumentCreateReqVO createReqVO);
+
+ /**
+ * 获取文档分页
+ *
+ * @param pageReqVO 分页参数
+ * @return 文档分页
+ */
+ PageResult getKnowledgeDocumentPage(AiKnowledgeDocumentPageReqVO pageReqVO);
+
+ /**
+ * 更新文档
+ *
+ * @param reqVO 更新信息
+ */
+ void updateKnowledgeDocument(AiKnowledgeDocumentUpdateReqVO reqVO);
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java
index 537033015..3758c3bfd 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java
@@ -1,27 +1,39 @@
package cn.iocoder.yudao.module.ai.service.knowledge;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeDocumentCreateReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentPageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeDocumentCreateReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeSegmentDO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeDocumentMapper;
import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeSegmentMapper;
import cn.iocoder.yudao.module.ai.enums.knowledge.AiKnowledgeDocumentStatusEnum;
+import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService;
+import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.tika.TikaDocumentReader;
-import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator;
+import org.springframework.ai.tokenizer.TokenCountEstimator;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.ai.vectorstore.VectorStore;
+import org.springframework.core.io.ByteArrayResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
-import java.util.Objects;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.KNOWLEDGE_DOCUMENT_NOT_EXISTS;
/**
* AI 知识库-文档 Service 实现类
@@ -39,53 +51,99 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
@Resource
private TokenTextSplitter tokenTextSplitter;
+ @Resource
+ private TokenCountEstimator tokenCountEstimator;
@Resource
- private AiEmbeddingService embeddingService;
+ private AiApiKeyService apiKeyService;
+ @Resource
+ private AiKnowledgeService knowledgeService;
+ @Resource
+ private AiChatModelService chatModelService;
- // TODO @xin:@Resource 注入
- private static final JTokkitTokenCountEstimator TOKEN_COUNT_ESTIMATOR = new JTokkitTokenCountEstimator();
-
- // TODO xiaoxin 临时测试用,后续删
- @Value("classpath:/webapp/test/Fel.pdf")
- private org.springframework.core.io.Resource data;
// TODO 芋艿:需要 review 下,代码格式;
- // TODO @xin:最好有 1、/2、/3 这种,让代码更有层次感
@Override
@Transactional(rollbackFor = Exception.class)
public Long createKnowledgeDocument(AiKnowledgeDocumentCreateReqVO createReqVO) {
- // TODO xiaoxin 后续从 url 加载
- TikaDocumentReader loader = new TikaDocumentReader(data);
- // 加载文档
+ // 1.1 下载文档
+ String url = createReqVO.getUrl();
+ // 1.2 加载文档
+ TikaDocumentReader loader = new TikaDocumentReader(downloadFile(url));
List documents = loader.get();
Document document = CollUtil.getFirst(documents);
- // TODO @xin:是不是不存在,就抛出异常呀;厚泽 return 呀;
- // TODO 芋艿 文档层面有没有可能会比较大,这两个字段是否可以从分段表计算得出?回复:先直接算;
- Integer tokens = Objects.nonNull(document) ? TOKEN_COUNT_ESTIMATOR.estimate(document.getContent()) : 0;
- Integer wordCount = Objects.nonNull(document) ? document.getContent().length() : 0;
+ String content = document.getContent();
+ Integer tokens = tokenCountEstimator.estimate(content);
+ Integer wordCount = content.length();
+ // 1.3 文档记录入库
AiKnowledgeDocumentDO documentDO = BeanUtils.toBean(createReqVO, AiKnowledgeDocumentDO.class)
.setTokens(tokens).setWordCount(wordCount)
.setStatus(CommonStatusEnum.ENABLE.getStatus()).setSliceStatus(AiKnowledgeDocumentStatusEnum.SUCCESS.getStatus());
- // 文档记录入库
documentMapper.insert(documentDO);
Long documentId = documentDO.getId();
if (CollUtil.isEmpty(documents)) {
return documentId;
}
- // 文档分段
+ // 2.1 文档分段
List segments = tokenTextSplitter.apply(documents);
- // 分段内容入库
+ // 2.2 分段内容入库
List segmentDOList = CollectionUtils.convertList(segments,
- segment -> new AiKnowledgeSegmentDO().setContent(segment.getContent()).setDocumentId(documentId)
- .setTokens(TOKEN_COUNT_ESTIMATOR.estimate(segment.getContent())).setWordCount(segment.getContent().length())
+ segment -> new AiKnowledgeSegmentDO().setContent(segment.getContent()).setDocumentId(documentId).setKnowledgeId(createReqVO.getKnowledgeId()).setVectorId(segment.getId())
+ .setTokens(tokenCountEstimator.estimate(segment.getContent())).setWordCount(segment.getContent().length())
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
segmentMapper.insertBatch(segmentDOList);
- // 向量化并存储
- embeddingService.add(segments);
+
+ // 3.1 document 补充源数据
+ segments.forEach(segment -> {
+ Map metadata = segment.getMetadata();
+ metadata.put(AiKnowledgeSegmentDO.FIELD_KNOWLEDGE_ID, createReqVO.getKnowledgeId());
+ });
+
+ AiKnowledgeDO knowledge = knowledgeService.validateKnowledgeExists(createReqVO.getKnowledgeId());
+ AiChatModelDO model = chatModelService.validateChatModel(knowledge.getModelId());
+ // 3.2 获取向量存储实例
+ VectorStore vectorStore = apiKeyService.getOrCreateVectorStore(model.getKeyId());
+ // 3.3 向量化并存储
+ vectorStore.add(segments);
return documentId;
}
+ @Override
+ public PageResult getKnowledgeDocumentPage(AiKnowledgeDocumentPageReqVO pageReqVO) {
+ return documentMapper.selectPage(pageReqVO);
+ }
+
+ @Override
+ public void updateKnowledgeDocument(AiKnowledgeDocumentUpdateReqVO reqVO) {
+ validateKnowledgeDocumentExists(reqVO.getId());
+ AiKnowledgeDocumentDO document = BeanUtils.toBean(reqVO, AiKnowledgeDocumentDO.class);
+ documentMapper.updateById(document);
+ }
+
+ /**
+ * 校验文档是否存在
+ *
+ * @param id 文档编号
+ * @return 文档信息
+ */
+ private AiKnowledgeDocumentDO validateKnowledgeDocumentExists(Long id) {
+ AiKnowledgeDocumentDO knowledgeDocument = documentMapper.selectById(id);
+ if (knowledgeDocument == null) {
+ throw exception(KNOWLEDGE_DOCUMENT_NOT_EXISTS);
+ }
+ return knowledgeDocument;
+ }
+
+ private org.springframework.core.io.Resource downloadFile(String url) {
+ try {
+ byte[] bytes = HttpUtil.downloadBytes(url);
+ return new ByteArrayResource(bytes);
+ } catch (Exception e) {
+ log.error("[downloadFile][url({}) 下载失败]", url, e);
+ throw new RuntimeException(e);
+ }
+ }
+
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java
index 7caea9ff4..22f634907 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java
@@ -1,5 +1,11 @@
package cn.iocoder.yudao.module.ai.service.knowledge;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentPageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateStatusReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeSegmentDO;
+
/**
* AI 知识库分片 Service 接口
*
@@ -7,4 +13,25 @@ package cn.iocoder.yudao.module.ai.service.knowledge;
*/
public interface AiKnowledgeSegmentService {
+ /**
+ * 获取段落分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 文档分页
+ */
+ PageResult getKnowledgeSegmentPage(AiKnowledgeSegmentPageReqVO pageReqVO);
+
+ /**
+ * 更新段落内容
+ *
+ * @param reqVO 更新内容
+ */
+ void updateKnowledgeSegment(AiKnowledgeSegmentUpdateReqVO reqVO);
+
+ /**
+ * 更新状态
+ *
+ * @param reqVO 更新内容
+ */
+ void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO);
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java
index 226c5f8fb..7f751b176 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java
@@ -1,5 +1,13 @@
package cn.iocoder.yudao.module.ai.service.knowledge;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentPageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateStatusReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeSegmentDO;
+import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeSegmentMapper;
+import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -12,4 +20,23 @@ import org.springframework.stereotype.Service;
@Slf4j
public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService {
+ @Resource
+ private AiKnowledgeSegmentMapper segmentMapper;
+
+ @Override
+ public PageResult getKnowledgeSegmentPage(AiKnowledgeSegmentPageReqVO pageReqVO) {
+ return segmentMapper.selectPage(pageReqVO);
+ }
+
+ @Override
+ public void updateKnowledgeSegment(AiKnowledgeSegmentUpdateReqVO reqVO) {
+ segmentMapper.updateById(BeanUtils.toBean(reqVO, AiKnowledgeSegmentDO.class));
+ // TODO @xin 重新向量化
+ }
+
+ @Override
+ public void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO) {
+ segmentMapper.updateById(BeanUtils.toBean(reqVO, AiKnowledgeSegmentDO.class));
+ // TODO @xin 1.禁用删除向量 2.启用重新向量化
+ }
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeService.java
new file mode 100644
index 000000000..9f43c5328
--- /dev/null
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeService.java
@@ -0,0 +1,50 @@
+package cn.iocoder.yudao.module.ai.service.knowledge;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeCreateMyReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeUpdateMyReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDO;
+
+/**
+ * AI 知识库-基础信息 Service 接口
+ *
+ * @author xiaoxin
+ */
+public interface AiKnowledgeService {
+
+ /**
+ * 创建【我的】知识库
+ *
+ * @param createReqVO 创建信息
+ * @param userId 用户编号
+ * @return 编号
+ */
+ Long createKnowledgeMy(AiKnowledgeCreateMyReqVO createReqVO, Long userId);
+
+
+ /**
+ * 创建【我的】知识库
+ *
+ * @param updateReqVO 更新信息
+ * @param userId 用户编号
+ */
+ void updateKnowledgeMy(AiKnowledgeUpdateMyReqVO updateReqVO, Long userId);
+
+
+ /**
+ * 校验知识库是否存在
+ *
+ * @param id 记录编号
+ */
+ AiKnowledgeDO validateKnowledgeExists(Long id);
+
+ /**
+ * 获得【我的】知识库分页
+ *
+ * @param userId 用户编号
+ * @param pageReqVO 分页查询
+ * @return 知识库分页
+ */
+ PageResult getKnowledgePageMy(Long userId, PageParam pageReqVO);
+}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeBaseServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeServiceImpl.java
similarity index 61%
rename from yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeBaseServiceImpl.java
rename to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeServiceImpl.java
index c208c92ba..1948bb00e 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeBaseServiceImpl.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeServiceImpl.java
@@ -1,14 +1,15 @@
package cn.iocoder.yudao.module.ai.service.knowledge;
-import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeCreateMyReqVO;
-import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeUpdateMyReqVO;
-import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeBaseDO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeCreateMyReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeUpdateMyReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
-import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeBaseMapper;
+import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeMapper;
import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@@ -24,56 +25,54 @@ import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.KNOWLEDGE_NOT_
*/
@Service
@Slf4j
-public class AiKnowledgeBaseServiceImpl implements AiKnowledgeBaseService {
+public class AiKnowledgeServiceImpl implements AiKnowledgeService {
@Resource
private AiChatModelService chatModalService;
@Resource
- private AiKnowledgeBaseMapper knowledgeBaseMapper;
+ private AiKnowledgeMapper knowledgeMapper;
@Override
public Long createKnowledgeMy(AiKnowledgeCreateMyReqVO createReqVO, Long userId) {
- // TODO @xin:貌似直接调用 chatModalService.validateChatModel(id) 完事,不用搞个方法
// 1. 校验模型配置
- AiChatModelDO model = validateChatModel(createReqVO.getModelId());
+ AiChatModelDO model = chatModalService.validateChatModel(createReqVO.getModelId());
// 2. 插入知识库
- // TODO @xin:不用 DO 结尾
- AiKnowledgeBaseDO knowledgeBaseDO = BeanUtils.toBean(createReqVO, AiKnowledgeBaseDO.class)
+ AiKnowledgeDO knowledgeBase = BeanUtils.toBean(createReqVO, AiKnowledgeDO.class)
.setModel(model.getModel()).setUserId(userId).setStatus(CommonStatusEnum.ENABLE.getStatus());
- knowledgeBaseMapper.insert(knowledgeBaseDO);
- return knowledgeBaseDO.getId();
+ knowledgeMapper.insert(knowledgeBase);
+ return knowledgeBase.getId();
}
@Override
public void updateKnowledgeMy(AiKnowledgeUpdateMyReqVO updateReqVO, Long userId) {
// 1.1 校验知识库存在
- AiKnowledgeBaseDO knowledgeBaseDO = validateKnowledgeExists(updateReqVO.getId());
+ AiKnowledgeDO knowledgeBaseDO = validateKnowledgeExists(updateReqVO.getId());
if (ObjUtil.notEqual(knowledgeBaseDO.getUserId(), userId)) {
throw exception(KNOWLEDGE_NOT_EXISTS);
}
// 1.2 校验模型配置
- AiChatModelDO model = validateChatModel(updateReqVO.getModelId());
+ AiChatModelDO model = chatModalService.validateChatModel(updateReqVO.getModelId());
// 2. 更新知识库
- AiKnowledgeBaseDO updateDO = BeanUtils.toBean(updateReqVO, AiKnowledgeBaseDO.class);
+ AiKnowledgeDO updateDO = BeanUtils.toBean(updateReqVO, AiKnowledgeDO.class);
updateDO.setModel(model.getModel());
- knowledgeBaseMapper.updateById(updateDO);
+ knowledgeMapper.updateById(updateDO);
}
- private AiChatModelDO validateChatModel(Long id) {
- AiChatModelDO model = chatModalService.validateChatModel(id);
- Assert.notNull(model, "未找到对应嵌入模型");
- return model;
- }
-
- public AiKnowledgeBaseDO validateKnowledgeExists(Long id) {
- AiKnowledgeBaseDO knowledgeBase = knowledgeBaseMapper.selectById(id);
+ @Override
+ public AiKnowledgeDO validateKnowledgeExists(Long id) {
+ AiKnowledgeDO knowledgeBase = knowledgeMapper.selectById(id);
if (knowledgeBase == null) {
throw exception(KNOWLEDGE_NOT_EXISTS);
}
return knowledgeBase;
}
+ @Override
+ public PageResult getKnowledgePageMy(Long userId, PageParam pageReqVO) {
+ return knowledgeMapper.selectPageByMy(userId, pageReqVO);
+ }
+
}
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyService.java
index fe8fdd194..603325da6 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyService.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyService.java
@@ -9,7 +9,9 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeySaveR
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
import jakarta.validation.Valid;
import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.image.ImageModel;
+import org.springframework.ai.vectorstore.VectorStore;
import java.util.List;
@@ -83,6 +85,14 @@ public interface AiApiKeyService {
*/
ChatModel getChatModel(Long id);
+ /**
+ * 获得 EmbeddingModel 对象
+ *
+ * @param id 编号
+ * @return EmbeddingModel 对象
+ */
+ EmbeddingModel getEmbeddingModel(Long id);
+
/**
* 获得 ImageModel 对象
*
@@ -111,4 +121,12 @@ public interface AiApiKeyService {
*/
SunoApi getSunoApi();
+ /**
+ * 获得 vector 对象
+ *
+ * @param id 编号
+ * @return VectorStore 对象
+ */
+ VectorStore getOrCreateVectorStore(Long id);
+
}
\ No newline at end of file
diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyServiceImpl.java
index 590b10a4c..25eec75b7 100644
--- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyServiceImpl.java
+++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.ai.service.model;
import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
import cn.iocoder.yudao.framework.ai.core.factory.AiModelFactory;
+import cn.iocoder.yudao.framework.ai.core.factory.AiVectorStoreFactory;
import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
@@ -13,7 +14,9 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
import cn.iocoder.yudao.module.ai.dal.mysql.model.AiApiKeyMapper;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.image.ImageModel;
+import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -36,6 +39,8 @@ public class AiApiKeyServiceImpl implements AiApiKeyService {
@Resource
private AiModelFactory modelFactory;
+ @Resource
+ private AiVectorStoreFactory vectorFactory;
@Override
public Long createApiKey(AiApiKeySaveReqVO createReqVO) {
@@ -104,6 +109,13 @@ public class AiApiKeyServiceImpl implements AiApiKeyService {
return modelFactory.getOrCreateChatModel(platform, apiKey.getApiKey(), apiKey.getUrl());
}
+ @Override
+ public EmbeddingModel getEmbeddingModel(Long id) {
+ AiApiKeyDO apiKey = validateApiKey(id);
+ AiPlatformEnum platform = AiPlatformEnum.validatePlatform(apiKey.getPlatform());
+ return modelFactory.getOrCreateEmbeddingModel(platform, apiKey.getApiKey(), apiKey.getUrl());
+ }
+
@Override
public ImageModel getImageModel(AiPlatformEnum platform) {
AiApiKeyDO apiKey = apiKeyMapper.selectFirstByPlatformAndStatus(platform.getPlatform(), CommonStatusEnum.ENABLE.getStatus());
@@ -132,4 +144,11 @@ public class AiApiKeyServiceImpl implements AiApiKeyService {
}
return modelFactory.getOrCreateSunoApi(apiKey.getApiKey(), apiKey.getUrl());
}
+
+ @Override
+ public VectorStore getOrCreateVectorStore(Long id) {
+ AiApiKeyDO apiKey = validateApiKey(id);
+ AiPlatformEnum platform = AiPlatformEnum.validatePlatform(apiKey.getPlatform());
+ return vectorFactory.getOrCreateVectorStore(getEmbeddingModel(id), platform, apiKey.getApiKey(), apiKey.getUrl());
+ }
}
\ No newline at end of file
diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
index 543444fdd..79a1f345b 100644
--- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
+++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
@@ -2,6 +2,8 @@ package cn.iocoder.yudao.framework.ai.config;
import cn.iocoder.yudao.framework.ai.core.factory.AiModelFactory;
import cn.iocoder.yudao.framework.ai.core.factory.AiModelFactoryImpl;
+import cn.iocoder.yudao.framework.ai.core.factory.AiVectorStoreFactory;
+import cn.iocoder.yudao.framework.ai.core.factory.AiVectorStoreFactoryImpl;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatOptions;
import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
@@ -10,20 +12,15 @@ import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatOptions;
import com.alibaba.cloud.ai.tongyi.TongYiAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreProperties;
-import org.springframework.ai.document.MetadataMode;
-import org.springframework.ai.embedding.EmbeddingModel;
+import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator;
+import org.springframework.ai.tokenizer.TokenCountEstimator;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
-import org.springframework.ai.transformers.TransformersEmbeddingModel;
-import org.springframework.ai.vectorstore.RedisVectorStore;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
-import redis.clients.jedis.JedisPooled;
/**
* 芋道 AI 自动配置
@@ -41,6 +38,12 @@ public class YudaoAiAutoConfiguration {
return new AiModelFactoryImpl();
}
+ @Bean
+ public AiVectorStoreFactory aiVectorFactory() {
+ return new AiVectorStoreFactoryImpl();
+ }
+
+
// ========== 各种 AI Client 创建 ==========
@Bean
@@ -83,30 +86,31 @@ public class YudaoAiAutoConfiguration {
}
// ========== rag 相关 ==========
- @Bean
- @Lazy // TODO 芋艿:临时注释,避免无法启动
- public EmbeddingModel transformersEmbeddingClient() {
- return new TransformersEmbeddingModel(MetadataMode.EMBED);
- }
+ // TODO @xin 免费版本
+// @Bean
+// @Lazy // TODO 芋艿:临时注释,避免无法启动」
+// public EmbeddingModel transformersEmbeddingClient() {
+// return new TransformersEmbeddingModel(MetadataMode.EMBED);
+// }
/**
- * 我们启动有加载很多 Embedding 模型,不晓得取哪个好,先 new 个 TransformersEmbeddingModel 跑
+ * TODO @xin 默认版本先不弄,目前都先取对应的 EmbeddingModel
*/
- @Bean
- @Lazy // TODO 芋艿:临时注释,避免无法启动
- public RedisVectorStore vectorStore(TransformersEmbeddingModel transformersEmbeddingModel, RedisVectorStoreProperties properties,
- RedisProperties redisProperties) {
- var config = RedisVectorStore.RedisVectorStoreConfig.builder()
- .withIndexName(properties.getIndex())
- .withPrefix(properties.getPrefix())
- .build();
-
- RedisVectorStore redisVectorStore = new RedisVectorStore(config, transformersEmbeddingModel,
- new JedisPooled(redisProperties.getHost(), redisProperties.getPort()),
- properties.isInitializeSchema());
- redisVectorStore.afterPropertiesSet();
- return redisVectorStore;
- }
+// @Bean
+// @Lazy // TODO 芋艿:临时注释,避免无法启动
+// public RedisVectorStore vectorStore(TongYiTextEmbeddingModel tongYiTextEmbeddingModel, RedisVectorStoreProperties properties,
+// RedisProperties redisProperties) {
+// var config = RedisVectorStore.RedisVectorStoreConfig.builder()
+// .withIndexName(properties.getIndex())
+// .withPrefix(properties.getPrefix())
+// .build();
+//
+// RedisVectorStore redisVectorStore = new RedisVectorStore(config, tongYiTextEmbeddingModel,
+// new JedisPooled(redisProperties.getHost(), redisProperties.getPort()),
+// properties.isInitializeSchema());
+// redisVectorStore.afterPropertiesSet();
+// return redisVectorStore;
+// }
@Bean
@Lazy // TODO 芋艿:临时注释,避免无法启动
@@ -114,4 +118,10 @@ public class YudaoAiAutoConfiguration {
return new TokenTextSplitter(500, 100, 5, 10000, true);
}
+ @Bean
+ @Lazy // TODO 芋艿:临时注释,避免无法启动
+ public TokenCountEstimator tokenCountEstimator() {
+ return new JTokkitTokenCountEstimator();
+ }
+
}
\ No newline at end of file
diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactory.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactory.java
index b6d7b3dd0..6f628ea4d 100644
--- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactory.java
+++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactory.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.image.ImageModel;
/**
@@ -25,6 +26,18 @@ public interface AiModelFactory {
*/
ChatModel getOrCreateChatModel(AiPlatformEnum platform, String apiKey, String url);
+ /**
+ * 基于指定配置,获得 EmbeddingModel 对象
+ *
+ * 如果不存在,则进行创建
+ *
+ * @param platform 平台
+ * @param apiKey API KEY
+ * @param url API URL
+ * @return ChatModel 对象
+ */
+ EmbeddingModel getOrCreateEmbeddingModel(AiPlatformEnum platform, String apiKey, String url);
+
/**
* 基于默认配置,获得 ChatModel 对象
*
diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
index c9b04dc1e..5c3524e66 100644
--- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
+++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
@@ -21,6 +21,7 @@ import com.alibaba.cloud.ai.tongyi.image.TongYiImagesModel;
import com.alibaba.cloud.ai.tongyi.image.TongYiImagesProperties;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
+import com.alibaba.dashscope.embeddings.TextEmbedding;
import com.azure.ai.openai.OpenAIClient;
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiAutoConfiguration;
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiChatProperties;
@@ -37,6 +38,7 @@ import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiConnectionProperties;
import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiImageProperties;
import org.springframework.ai.azure.openai.AzureOpenAiChatModel;
import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.image.ImageModel;
import org.springframework.ai.model.function.FunctionCallbackContext;
import org.springframework.ai.ollama.OllamaChatModel;
@@ -97,6 +99,21 @@ public class AiModelFactoryImpl implements AiModelFactory {
});
}
+ @Override
+ public EmbeddingModel getOrCreateEmbeddingModel(AiPlatformEnum platform, String apiKey, String url) {
+ String cacheKey = buildClientCacheKey(EmbeddingModel.class, platform, apiKey, url);
+ return Singleton.get(cacheKey, (Func0) () -> {
+ // TODO @xin 先测试一个
+ switch (platform) {
+ case TONG_YI:
+ return buildTongYiEmbeddingModel(apiKey);
+ default:
+ throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform));
+ }
+ });
+ }
+
+
@Override
public ChatModel getDefaultChatModel(AiPlatformEnum platform) {
//noinspection EnhancedSwitchMigration
@@ -239,7 +256,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
/**
* 可参考 {@link ZhiPuAiAutoConfiguration#zhiPuAiChatModel(
- * ZhiPuAiConnectionProperties, ZhiPuAiChatProperties, RestClient.Builder, List, FunctionCallbackContext, RetryTemplate, ResponseErrorHandler)}
+ *ZhiPuAiConnectionProperties, ZhiPuAiChatProperties, RestClient.Builder, List, FunctionCallbackContext, RetryTemplate, ResponseErrorHandler)}
*/
private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) {
url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL);
@@ -249,7 +266,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
/**
* 可参考 {@link ZhiPuAiAutoConfiguration#zhiPuAiImageModel(
- * ZhiPuAiConnectionProperties, ZhiPuAiImageProperties, RestClient.Builder, RetryTemplate, ResponseErrorHandler)}
+ *ZhiPuAiConnectionProperties, ZhiPuAiImageProperties, RestClient.Builder, RetryTemplate, ResponseErrorHandler)}
*/
private ZhiPuAiImageModel buildZhiPuAiImageModel(String apiKey, String url) {
url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL);
@@ -315,4 +332,15 @@ public class AiModelFactoryImpl implements AiModelFactory {
return new StabilityAiImageModel(stabilityAiApi);
}
+ // ========== 各种创建 EmbeddingModel 的方法 ==========
+
+ /**
+ * 可参考 {@link TongYiAutoConfiguration#tongYiTextEmbeddingClient(TextEmbedding, TongYiConnectionProperties)}
+ */
+ private EmbeddingModel buildTongYiEmbeddingModel(String apiKey) {
+ TongYiConnectionProperties connectionProperties = new TongYiConnectionProperties();
+ connectionProperties.setApiKey(apiKey);
+ return new TongYiAutoConfiguration().tongYiTextEmbeddingClient(SpringUtil.getBean(TextEmbedding.class), connectionProperties);
+ }
+
}
diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiVectorStoreFactory.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiVectorStoreFactory.java
new file mode 100644
index 000000000..3e138cbd3
--- /dev/null
+++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiVectorStoreFactory.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.framework.ai.core.factory;
+
+import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
+import org.springframework.ai.embedding.EmbeddingModel;
+import org.springframework.ai.vectorstore.VectorStore;
+
+/**
+ * AI Vector 模型工厂的接口类
+ * @author xiaoxin
+ */
+public interface AiVectorStoreFactory {
+
+
+ /**
+ * 基于指定配置,获得 VectorStore 对象
+ *
+ * 如果不存在,则进行创建
+ *
+ * @param embeddingModel 嵌入模型
+ * @param platform 平台
+ * @param apiKey API KEY
+ * @param url API URL
+ * @return VectorStore 对象
+ */
+ VectorStore getOrCreateVectorStore(EmbeddingModel embeddingModel, AiPlatformEnum platform, String apiKey, String url);
+
+}
diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiVectorStoreFactoryImpl.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiVectorStoreFactoryImpl.java
new file mode 100644
index 000000000..b3291c6b7
--- /dev/null
+++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiVectorStoreFactoryImpl.java
@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.framework.ai.core.factory;
+
+import cn.hutool.core.lang.Singleton;
+import cn.hutool.core.lang.func.Func0;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
+import cn.iocoder.yudao.framework.common.util.spring.SpringUtils;
+import org.springframework.ai.embedding.EmbeddingModel;
+import org.springframework.ai.vectorstore.RedisVectorStore;
+import org.springframework.ai.vectorstore.VectorStore;
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+import redis.clients.jedis.JedisPooled;
+
+/**
+ * AI Vector 模型工厂的实现类
+ * 使用 redisVectorStore 实现 VectorStore
+ *
+ * @author xiaoxin
+ */
+public class AiVectorStoreFactoryImpl implements AiVectorStoreFactory {
+
+ @Override
+ public VectorStore getOrCreateVectorStore(EmbeddingModel embeddingModel, AiPlatformEnum platform, String apiKey, String url) {
+ String cacheKey = buildClientCacheKey(VectorStore.class, platform, apiKey, url);
+ return Singleton.get(cacheKey, (Func0) () -> {
+ // TODO 芋艿 @xin 这两个配置取哪好呢
+ // TODO 不同模型的向量维度可能会不一样,目前看貌似是以 index 来做区分的,维度不一样存不到一个 index 上
+ String index = "default-index";
+ String prefix = "default:";
+ var config = RedisVectorStore.RedisVectorStoreConfig.builder()
+ .withIndexName(index)
+ .withPrefix(prefix)
+ .build();
+ RedisProperties redisProperties = SpringUtils.getBean(RedisProperties.class);
+ RedisVectorStore redisVectorStore = new RedisVectorStore(config, embeddingModel,
+ new JedisPooled(redisProperties.getHost(), redisProperties.getPort()),
+ true);
+ redisVectorStore.afterPropertiesSet();
+ return redisVectorStore;
+ });
+ }
+
+
+ private static String buildClientCacheKey(Class> clazz, Object... params) {
+ if (ArrayUtil.isEmpty(params)) {
+ return clazz.getName();
+ }
+ return StrUtil.format("{}#{}", clazz.getName(), ArrayUtil.join(params, "_"));
+ }
+}
diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfiguration.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfiguration.java
index 615b05f78..a72d50c4a 100644
--- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfiguration.java
+++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfiguration.java
@@ -19,6 +19,7 @@ import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.vectorstore.RedisVectorStore;
import org.springframework.ai.vectorstore.RedisVectorStore.RedisVectorStoreConfig;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
@@ -38,7 +39,7 @@ import redis.clients.jedis.JedisPooled;
*/
@AutoConfiguration(after = RedisAutoConfiguration.class)
@ConditionalOnClass({JedisPooled.class, JedisConnectionFactory.class, RedisVectorStore.class, EmbeddingModel.class})
-//@ConditionalOnBean(JedisConnectionFactory.class)
+@ConditionalOnBean(JedisConnectionFactory.class)
@EnableConfigurationProperties(RedisVectorStoreProperties.class)
public class RedisVectorStoreAutoConfiguration {
diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/resources/webapp/test/Fel.pdf b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/resources/webapp/test/Fel.pdf
deleted file mode 100755
index 405b67fed..000000000
Binary files a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/resources/webapp/test/Fel.pdf and /dev/null differ