【功能新增】AI:新增知识库文档的更新信息与状态
This commit is contained in:
parent
d1e207899a
commit
a998168b3b
|
@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowl
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentRespVO;
|
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.document.AiKnowledgeDocumentUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentCreateListReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentCreateListReqVO;
|
||||||
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateStatusReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeDocumentCreateReqVO;
|
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.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
|
||||||
import cn.iocoder.yudao.module.ai.service.knowledge.AiKnowledgeDocumentService;
|
import cn.iocoder.yudao.module.ai.service.knowledge.AiKnowledgeDocumentService;
|
||||||
|
@ -47,14 +48,14 @@ public class AiKnowledgeDocumentController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "新建文档")
|
@Operation(summary = "新建文档(单个)")
|
||||||
public CommonResult<Long> createKnowledgeDocument(@RequestBody @Valid AiKnowledgeDocumentCreateReqVO reqVO) {
|
public CommonResult<Long> createKnowledgeDocument(@RequestBody @Valid AiKnowledgeDocumentCreateReqVO reqVO) {
|
||||||
Long id = documentService.createKnowledgeDocument(reqVO);
|
Long id = documentService.createKnowledgeDocument(reqVO);
|
||||||
return success(id);
|
return success(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/create-list")
|
@PostMapping("/create-list")
|
||||||
@Operation(summary = "批量新建文档")
|
@Operation(summary = "新建文档(多个)")
|
||||||
public CommonResult<List<Long>> createKnowledgeDocumentList(
|
public CommonResult<List<Long>> createKnowledgeDocumentList(
|
||||||
@RequestBody @Valid AiKnowledgeDocumentCreateListReqVO reqVO) {
|
@RequestBody @Valid AiKnowledgeDocumentCreateListReqVO reqVO) {
|
||||||
List<Long> ids = documentService.createKnowledgeDocumentList(reqVO);
|
List<Long> ids = documentService.createKnowledgeDocumentList(reqVO);
|
||||||
|
@ -68,4 +69,12 @@ public class AiKnowledgeDocumentController {
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update-status")
|
||||||
|
@Operation(summary = "更新文档状态")
|
||||||
|
public CommonResult<Boolean> updateKnowledgeDocumentStatus(
|
||||||
|
@Valid @RequestBody AiKnowledgeDocumentUpdateStatusReqVO reqVO) {
|
||||||
|
documentService.updateKnowledgeDocumentStatus(reqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.Parameters;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
import org.hibernate.validator.constraints.URL;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@ public class AiKnowledgeSegmentController {
|
||||||
@Parameter(name = "segmentMaxTokens", description = "分段的最大 Token 数", required = true)
|
@Parameter(name = "segmentMaxTokens", description = "分段的最大 Token 数", required = true)
|
||||||
})
|
})
|
||||||
public CommonResult<List<AiKnowledgeSegmentRespVO>> splitContent(
|
public CommonResult<List<AiKnowledgeSegmentRespVO>> splitContent(
|
||||||
@RequestParam("url") String url,
|
@RequestParam("url") @URL String url,
|
||||||
@RequestParam(value = "segmentMaxTokens") Integer segmentMaxTokens) {
|
@RequestParam(value = "segmentMaxTokens") Integer segmentMaxTokens) {
|
||||||
List<AiKnowledgeSegmentDO> segments = segmentService.splitContent(url, segmentMaxTokens);
|
List<AiKnowledgeSegmentDO> segments = segmentService.splitContent(url, segmentMaxTokens);
|
||||||
return success(BeanUtils.toBean(segments, AiKnowledgeSegmentRespVO.class));
|
return success(BeanUtils.toBean(segments, AiKnowledgeSegmentRespVO.class));
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document;
|
package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|
||||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
// TODO @芋艿:稍后优化
|
|
||||||
@Schema(description = "管理后台 - AI 知识库文档更新 Request VO")
|
@Schema(description = "管理后台 - AI 知识库文档更新 Request VO")
|
||||||
@Data
|
@Data
|
||||||
public class AiKnowledgeDocumentUpdateReqVO {
|
public class AiKnowledgeDocumentUpdateReqVO {
|
||||||
|
@ -18,8 +15,7 @@ public class AiKnowledgeDocumentUpdateReqVO {
|
||||||
@Schema(description = "名称", example = "Java 开发手册")
|
@Schema(description = "名称", example = "Java 开发手册")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Schema(description = "是否启用", example = "1")
|
@Schema(description = "分片最大 Token 数", example = "1000")
|
||||||
@InEnum(CommonStatusEnum.class)
|
private Integer segmentMaxTokens;
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,4 +31,10 @@ public interface AiKnowledgeSegmentMapper extends BaseMapperX<AiKnowledgeSegment
|
||||||
.orderByDesc(AiKnowledgeSegmentDO::getId));
|
.orderByDesc(AiKnowledgeSegmentDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default List<AiKnowledgeSegmentDO> selectListByDocumentId(Long documentId) {
|
||||||
|
return selectList(new LambdaQueryWrapperX<AiKnowledgeSegmentDO>()
|
||||||
|
.eq(AiKnowledgeSegmentDO::getDocumentId, documentId)
|
||||||
|
.orderByDesc(AiKnowledgeSegmentDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.ai.service.knowledge;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
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.AiKnowledgeDocumentPageReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateStatusReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeDocumentCreateReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeDocumentCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentCreateListReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentCreateListReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
|
||||||
|
@ -10,14 +11,14 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI 知识库-文档 Service 接口
|
* AI 知识库文档 Service 接口
|
||||||
*
|
*
|
||||||
* @author xiaoxin
|
* @author xiaoxin
|
||||||
*/
|
*/
|
||||||
public interface AiKnowledgeDocumentService {
|
public interface AiKnowledgeDocumentService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建文档
|
* 创建文档(单个)
|
||||||
*
|
*
|
||||||
* @param createReqVO 文档创建 Request VO
|
* @param createReqVO 文档创建 Request VO
|
||||||
* @return 文档编号
|
* @return 文档编号
|
||||||
|
@ -25,7 +26,7 @@ public interface AiKnowledgeDocumentService {
|
||||||
Long createKnowledgeDocument(AiKnowledgeDocumentCreateReqVO createReqVO);
|
Long createKnowledgeDocument(AiKnowledgeDocumentCreateReqVO createReqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量创建文档
|
* 创建文档(多个)
|
||||||
*
|
*
|
||||||
* @param createListReqVO 批量创建 Request VO
|
* @param createListReqVO 批量创建 Request VO
|
||||||
* @return 文档编号列表
|
* @return 文档编号列表
|
||||||
|
@ -55,6 +56,13 @@ public interface AiKnowledgeDocumentService {
|
||||||
*/
|
*/
|
||||||
void updateKnowledgeDocument(AiKnowledgeDocumentUpdateReqVO reqVO);
|
void updateKnowledgeDocument(AiKnowledgeDocumentUpdateReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新文档状态
|
||||||
|
*
|
||||||
|
* @param reqVO 更新状态信息
|
||||||
|
*/
|
||||||
|
void updateKnowledgeDocumentStatus(AiKnowledgeDocumentUpdateStatusReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验文档是否存在
|
* 校验文档是否存在
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.ai.service.knowledge;
|
package cn.iocoder.yudao.module.ai.service.knowledge;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
@ -8,6 +9,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
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.AiKnowledgeDocumentPageReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentUpdateStatusReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentCreateListReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.document.AiKnowledgeDocumentCreateListReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.knowledge.AiKnowledgeDocumentCreateReqVO;
|
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.dal.dataobject.knowledge.AiKnowledgeDocumentDO;
|
||||||
|
@ -88,6 +90,7 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
|
||||||
.setKnowledgeId(createListReqVO.getKnowledgeId())
|
.setKnowledgeId(createListReqVO.getKnowledgeId())
|
||||||
.setContent(content).setContentLength(content.length())
|
.setContent(content).setContentLength(content.length())
|
||||||
.setTokens(tokenCountEstimator.estimate(content))
|
.setTokens(tokenCountEstimator.estimate(content))
|
||||||
|
.setSegmentMaxTokens(createListReqVO.getSegmentMaxTokens())
|
||||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||||
}
|
}
|
||||||
knowledgeDocumentMapper.insertBatch(documentDOs);
|
knowledgeDocumentMapper.insertBatch(documentDOs);
|
||||||
|
@ -111,11 +114,38 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
|
||||||
@Override
|
@Override
|
||||||
public void updateKnowledgeDocument(AiKnowledgeDocumentUpdateReqVO reqVO) {
|
public void updateKnowledgeDocument(AiKnowledgeDocumentUpdateReqVO reqVO) {
|
||||||
// 1. 校验文档是否存在
|
// 1. 校验文档是否存在
|
||||||
validateKnowledgeDocumentExists(reqVO.getId());
|
AiKnowledgeDocumentDO oldDocument = validateKnowledgeDocumentExists(reqVO.getId());
|
||||||
|
|
||||||
// 2. 更新文档
|
// 2. 更新文档
|
||||||
AiKnowledgeDocumentDO document = BeanUtils.toBean(reqVO, AiKnowledgeDocumentDO.class);
|
AiKnowledgeDocumentDO document = BeanUtils.toBean(reqVO, AiKnowledgeDocumentDO.class);
|
||||||
knowledgeDocumentMapper.updateById(document);
|
knowledgeDocumentMapper.updateById(document);
|
||||||
// TODO @芋艿:这里要处理状态的变更
|
|
||||||
|
// 3. 如果处于开启状态,并且最大 tokens 发生变化,则 segment 需要重新索引
|
||||||
|
if (CommonStatusEnum.isEnable(oldDocument.getStatus())
|
||||||
|
&& reqVO.getSegmentMaxTokens() != null
|
||||||
|
&& ObjUtil.notEqual(reqVO.getSegmentMaxTokens(), oldDocument.getSegmentMaxTokens())) {
|
||||||
|
// 删除旧的文档切片
|
||||||
|
knowledgeSegmentService.deleteKnowledgeSegmentByDocumentId(reqVO.getId());
|
||||||
|
// 重新创建文档切片
|
||||||
|
knowledgeSegmentService.createKnowledgeSegmentBySplitContentAsync(reqVO.getId(), oldDocument.getContent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateKnowledgeDocumentStatus(AiKnowledgeDocumentUpdateStatusReqVO reqVO) {
|
||||||
|
// 1. 校验存在
|
||||||
|
AiKnowledgeDocumentDO document = validateKnowledgeDocumentExists(reqVO.getId());
|
||||||
|
|
||||||
|
// 2. 更新状态
|
||||||
|
knowledgeDocumentMapper.updateById(new AiKnowledgeDocumentDO()
|
||||||
|
.setId(reqVO.getId()).setStatus(reqVO.getStatus()));
|
||||||
|
|
||||||
|
// 3. 处理文档切片
|
||||||
|
if (CommonStatusEnum.isEnable(reqVO.getStatus())) {
|
||||||
|
knowledgeSegmentService.createKnowledgeSegmentBySplitContentAsync(reqVO.getId(), document.getContent());
|
||||||
|
} else {
|
||||||
|
knowledgeSegmentService.deleteKnowledgeSegmentByDocumentId(reqVO.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -58,6 +58,13 @@ public interface AiKnowledgeSegmentService {
|
||||||
*/
|
*/
|
||||||
void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO);
|
void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文档编号删除段落
|
||||||
|
*
|
||||||
|
* @param documentId 文档编号
|
||||||
|
*/
|
||||||
|
void deleteKnowledgeSegmentByDocumentId(Long documentId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 召回段落
|
* 召回段落
|
||||||
*
|
*
|
||||||
|
|
|
@ -115,6 +115,22 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteKnowledgeSegmentByDocumentId(Long documentId) {
|
||||||
|
// 1. 查询需要删除的段落
|
||||||
|
List<AiKnowledgeSegmentDO> segments = segmentMapper.selectListByDocumentId(documentId);
|
||||||
|
if (CollUtil.isEmpty(segments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 批量删除段落记录
|
||||||
|
segmentMapper.deleteByIds(convertList(segments, AiKnowledgeSegmentDO::getId));
|
||||||
|
|
||||||
|
// 3. 删除向量存储中的段落
|
||||||
|
VectorStore vectorStore = getVectorStoreById(segments.get(0).getKnowledgeId());
|
||||||
|
vectorStore.delete(convertList(segments, AiKnowledgeSegmentDO::getVectorId));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO) {
|
public void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO) {
|
||||||
// 1. 校验
|
// 1. 校验
|
||||||
|
|
Loading…
Reference in New Issue