chore: initialize qiming workspace repository

This commit is contained in:
Codex
2026-05-29 14:22:48 +08:00
commit bfd67a0f2c
10750 changed files with 1885711 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xspaceagi</groupId>
<artifactId>app-platform-knowledge</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>app-platform-knowledge-sdk</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.xspaceagi</groupId>
<artifactId>system-sdk</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,41 @@
package com.xspaceagi.knowledge.sdk.enums;
import java.util.Arrays;
import lombok.Getter;
/**
* 知识库文档状态,1:分析中;2:分析成功;10:分析失败;
*/
@Getter
public enum KnowledgeDocStatueEnum {
ANALYZING(1, "分析中", "分析中"),
ANALYZED(2, "分析成功", "分析成功"),
ANALYZING_RAW(3, "分析中", "分段生成中"),
ANALYZED_QA(4, "分析中", "问答生成中"),
ANALYZED_EMBEDDING(5, "分析中", "向量化中"),
ANALYZE_FAILED(10, "分析失败", "分析失败");
private final Integer code;
/**
* 描述
*/
private final String desc;
/**
* 具体步骤描述
*/
private final String stepDesc;
KnowledgeDocStatueEnum(Integer code, String desc, String stepDesc) {
this.code = code;
this.desc = desc;
this.stepDesc = stepDesc;
}
public static KnowledgeDocStatueEnum getByCode(Integer code) {
return Arrays.stream(KnowledgeDocStatueEnum.values())
.filter(e -> e.getCode().equals(code))
.findFirst()
.orElse(null);
}
}

View File

@@ -0,0 +1,11 @@
package com.xspaceagi.knowledge.sdk.enums;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
@Schema(description = "知识状态")
@Getter
public enum KnowledgePubStatusEnum {
Waiting,
Published
}

View File

@@ -0,0 +1,13 @@
package com.xspaceagi.knowledge.sdk.enums;
import lombok.Getter;
/**
* 分段类型words: 按照词数分段, delimiter: 按照分隔符分段field: 按照字段分段,json文件,按照定义好的问答字段,进行解析问答结果
*/
@Getter
public enum SegmentEnum {
WORDS,
DELIMITER,
SMART
}

View File

@@ -0,0 +1,47 @@
package com.xspaceagi.knowledge.sdk.request;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 知识库配置请求参数
*/
@Builder
@Getter
@Setter
public class KnowledgeConfigRequestVo {
@Schema(description = "页码")
private Integer page;
@Schema(description = "每页数量")
private Integer pageSize;
// @Schema(description = "分类名称")
// private String category;
@Schema(description = "关键字搜索")
private String kw;
@Schema(description = "空间ID可选需要通过空间过滤时有用")
private Long spaceId;
@Schema(description = "空间ID列表可选,查询用户有权限的空间,限制访问空间,比如工作流查询全部知识库,要限制用户有权限的空间下的知识库")
private List<Long> authSpaceIds;
@Schema(description = "创建人ID列表")
private List<Long> creatorIds;
@Schema(description = "数据类型,默认文本,1:文本;2:表格")
private Integer dataType;
//新增
@Schema(description = "知识库的管控授权")
private List<Long> knowledgeIds;
}

View File

@@ -0,0 +1,47 @@
package com.xspaceagi.knowledge.sdk.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
/**
* 知识库配置创建请求
*/
@Builder
@Getter
@Setter
public class KnowledgeCreateRequestVo {
/**
* 用户ID
*/
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
private Long userId;
/**
* 所属空间ID
*/
@Schema(description = "所属空间ID", requiredMode = Schema.RequiredMode.REQUIRED)
private Long spaceId;
@Schema(description = "知识库名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "Knowledge base name is required")
private String name;
@Schema(description = "知识库描述")
private String description;
/**
* 数据类型,默认文本,1:文本;2:表格
*/
@Schema(description = "数据类型,默认文本,1:文本;2:表格", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Integer dataType;
@Schema(description = "图标的url地址,[可选]", requiredMode = Schema.RequiredMode.REQUIRED)
private String icon;
}

View File

@@ -0,0 +1,21 @@
package com.xspaceagi.knowledge.sdk.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
@Schema(description = "知识库下的文档查询")
public class KnowledgeDocumentRequestVo implements Serializable {
@Schema(description = "知识库ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "Knowledge base ID is required")
private Long kbId;
}

View File

@@ -0,0 +1,79 @@
package com.xspaceagi.knowledge.sdk.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* 知识库全文检索请求 VO
*
* <p><b>最简使用只需2个参数</b></p>
* <pre>
* KnowledgeFullTextSearchRequestVo request = new KnowledgeFullTextSearchRequestVo();
* request.setKbId(123L); // 必填知识库ID
* request.setQueryText("Spring Boot"); // 必填:查询文本
* // 其他参数都有默认值,无需设置
* </pre>
*
* @author system
* @date 2025-03-31
*/
@Getter
@Setter
@Schema(description = "知识库全文检索请求")
public class KnowledgeFullTextSearchRequestVo implements Serializable {
private static final long serialVersionUID = 1L;
// ==================== 必填参数 ==================== //
@Schema(
description = "租户IDRPC调用必填",
requiredMode = Schema.RequiredMode.REQUIRED,
example = "1"
)
@NotNull(message = "Tenant ID is required")
private Long tenantId;
@Schema(
description = "知识库ID列表可选不传则检索所有知识库",
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
example = "[123, 456]"
)
private List<Long> kbIds;
@Schema(
description = "全文检索查询文本(自然语言,系统自动分词)",
requiredMode = Schema.RequiredMode.REQUIRED,
example = "Spring Boot 开发框架"
)
@NotBlank(message = "Query text is required")
private String queryText;
// ==================== 可选参数(有默认值)==================== //
@Schema(
description = "返回结果数量Top-K默认10",
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
example = "10"
)
@Min(value = 1, message = "Result size must be at least 1")
@Max(value = 100, message = "Result size must be at most 100")
private Integer topK = 10;
@Schema(
description = "指定文档ID列表可选不指定则检索所有文档",
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
example = "[1, 2, 3]"
)
private List<Long> docIds;
}

View File

@@ -0,0 +1,33 @@
package com.xspaceagi.knowledge.sdk.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
@Schema(description = "知识库内问答查询")
public class KnowledgeQaRequestVo implements Serializable {
@Schema(description = "知识库ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "Knowledge base ID is required")
private Long kbId;
@Schema(description = "问题", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "Question is required")
private String question;
@Schema(description = "top-K值", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "top-K is required")
private int topK;
@Schema(description = "是否忽略文档状态", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "ignoreDocStatus flag is required")
private boolean ignoreDocStatus;
private boolean ignoreTenantId;
}

View File

@@ -0,0 +1,19 @@
package com.xspaceagi.knowledge.sdk.response;
import com.xspaceagi.system.spec.page.SuperPage;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* 知识库表
*
* @TableName knowledge_config
*/
@Getter
@Setter
public class KnowledgeConfigResponseVo {
@Schema(description = "知识库分页查询结果")
private SuperPage<KnowledgeConfigVo> configPage;
}

View File

@@ -0,0 +1,75 @@
package com.xspaceagi.knowledge.sdk.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
/**
* 知识库表
*/
@Getter
@Setter
public class KnowledgeConfigVo {
@Schema(description = "主键id")
private Long id;
@Schema(description = "知识库名称")
private String name;
@Schema(description = "知识库描述")
private String description;
@Schema(description = "发布状态")
private String pubStatus;
/**
* 数据类型,默认文本,1:文本;2:表格
*/
@Schema(description = "数据类型,默认文本,1:文本;2:表格")
private Integer dataType;
@Schema(description = "知识库的嵌入模型ID")
private Long embeddingModelId;
@Schema(description = "知识库的生成Q&A模型ID")
private Long chatModelId;
@Schema(description = "所属空间ID")
private Long spaceId;
@Schema(description = "图标的url地址")
private String icon;
@Schema(description = "创建时间")
private LocalDateTime created;
@Schema(description = "创建人id")
private Long creatorId;
@Schema(description = "创建人")
private String creatorName;
@Schema(description = "创建人昵称")
private String creatorNickName;
@Schema(description = "头像")
private String creatorAvatar;
@Schema(description = "更新时间")
private LocalDateTime modified;
@Schema(description = "最后修改人id")
private Long modifiedId;
@Schema(description = "最后修改人")
private String modifiedName;
@Schema(description = "工作流ID")
private Long workflowId;
@Schema(description = "是否受后台权限控制0 不受1 受")
private Integer accessControl;
}

View File

@@ -0,0 +1,17 @@
package com.xspaceagi.knowledge.sdk.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
@Getter
@Setter
public class KnowledgeDocumentResponseVo implements Serializable {
@Schema(description = "文档列表结果")
private List<KnowledgeDocumentVo> documentVoList;
}

View File

@@ -0,0 +1,87 @@
package com.xspaceagi.knowledge.sdk.response;
import com.xspaceagi.knowledge.sdk.enums.KnowledgeDocStatueEnum;
import com.xspaceagi.knowledge.sdk.enums.KnowledgePubStatusEnum;
import com.xspaceagi.knowledge.sdk.vo.SegmentConfigModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
public class KnowledgeDocumentVo implements Serializable {
@Schema(description = "主键id")
private Long id;
@Schema(description = "文档所属知识库")
private Long kbId;
@Schema(description = "文档名称")
private String name;
@Schema(description = "文件URL")
private String docUrl;
@Schema(description = "发布状态")
private KnowledgePubStatusEnum pubStatus;
@Schema(description = "知识库文档状态,1:分析中;2:分析成功;10:分析失败;")
private KnowledgeDocStatueEnum docStatus;
@Schema(description = "知识库文档状态原因,失败的原因")
private String docStatusReason;
@Schema(description = "是否已经生成Q&A")
private Boolean hasQa;
@Schema(description = "是否已经完成嵌入")
private Boolean hasEmbedding;
@Schema(description = "文档分段方式")
private SegmentConfigModel segmentConfig;
@Schema(description = "所属空间ID")
private Long spaceId;
/**
* 自定义文本内容,自定义添加会有
*/
@Schema(description = "文件内容")
private String fileContent;
/**
* 文件大小,单位字节byte
*/
@Schema(description = "文件大小,单位字节byte")
private Long fileSize;
/**
* 文件类型,1:URL访问文件;2:自定义文本内容
*/
@Schema(description = "文件类型,1:URL访问文件;2:自定义文本内容")
private Integer dataType;
@Schema(description = "创建时间")
private LocalDateTime created;
@Schema(description = "创建人id")
private Long creatorId;
@Schema(description = "创建人")
private String creatorName;
@Schema(description = "更新时间")
private LocalDateTime modified;
@Schema(description = "最后修改人id")
private Long modifiedId;
@Schema(description = "最后修改人")
private String modifiedName;
/**
* 租户ID
*/
private Long tenantId;
}

View File

@@ -0,0 +1,30 @@
package com.xspaceagi.knowledge.sdk.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* 知识库全文检索响应 VO
*
* @author system
* @date 2025-03-31
*/
@Getter
@Setter
@Schema(description = "知识库全文检索响应")
public class KnowledgeFullTextSearchResponseVo implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "检索结果列表(按相关性分数降序排列)")
private List<KnowledgeFullTextSearchResultVo> results;
@Schema(description = "总耗时(毫秒)")
private Long costTimeMs;
}

View File

@@ -0,0 +1,44 @@
package com.xspaceagi.knowledge.sdk.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* 知识库全文检索单个结果 VO
*
* @author system
* @date 2025-03-31
*/
@Getter
@Setter
@Schema(description = "知识库全文检索结果")
public class KnowledgeFullTextSearchResultVo implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "原始分段ID")
private Long rawSegmentId;
@Schema(description = "文档ID")
private Long docId;
@Schema(description = "知识库ID")
private Long kbId;
@Schema(description = "原始分段文本(匹配的内容)")
private String rawText;
@Schema(description = "分段排序索引")
private Integer sortIndex;
@Schema(description = "相关性分数BM25算法计算值越大越相关")
private Float score;
@Schema(description = "文档名称(扩展字段)")
private String documentName;
}

View File

@@ -0,0 +1,17 @@
package com.xspaceagi.knowledge.sdk.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
@Getter
@Setter
public class KnowledgeQaResponseVo implements Serializable {
@Schema(description = "问答结果")
private List<KnowledgeQaVo> qaVoList;
}

View File

@@ -0,0 +1,34 @@
package com.xspaceagi.knowledge.sdk.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
@Schema(description = "问答结果")
public class KnowledgeQaVo implements Serializable {
@Schema(description = "问答ID")
private Long qaId;
@Schema(description = "所在知识库ID")
private Long kbId;
@Schema(description = "所属文档ID")
private Long docId;
@Schema(description = "分段问题")
private String question;
@Schema(description = "分段答案")
private String answer;
@Schema(description = "归属分段对应的原始分段文本,可能没有", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String rawTxt;
@Schema(description = "得分")
private double score;
}

View File

@@ -0,0 +1,84 @@
package com.xspaceagi.knowledge.sdk.sevice;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xspaceagi.knowledge.sdk.request.KnowledgeConfigRequestVo;
import com.xspaceagi.knowledge.sdk.request.KnowledgeCreateRequestVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeConfigResponseVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeConfigVo;
import com.xspaceagi.system.spec.common.UserContext;
import java.util.List;
/**
* 知识库查询服务
*/
public interface IKnowledgeConfigRpcService {
/**
* 查询知识库列表,如果没有当前页和页大小,默认当前页为1,页大小为100
*
* @param knowledgeConfigRequestVo 请求参数
* @return 知识库基础配置列表
*/
public KnowledgeConfigResponseVo queryListKnowledgeConfig(KnowledgeConfigRequestVo knowledgeConfigRequestVo);
/**
* 创建知识库
*
* @param createRequestVo 创建知识库请求参数
* @return 知识库主键id
*/
Long createKnowledgeConfig(KnowledgeCreateRequestVo createRequestVo);
/**
* 根据知识库主键id查询知识库配置
*
* @param id 知识库主键id
* @return 知识库配置
*/
KnowledgeConfigVo queryKnowledgeConfigById(Long id);
/**
* 统计知识库总数
*
* @return 知识库总数
*/
Long countTotalKnowledge(Long userId);
/**
* 管理端查询知识库列表
*
* @param pageNo 页码
* @param pageSize 每页大小
* @param name 名称模糊搜索
* @param creatorIds 创建人ID列表
* @param spaceId 空间ID
* @return 知识库配置列表
*/
IPage<KnowledgeConfigVo> queryListForManage(Integer pageNo, Integer pageSize, String name,
java.util.List<Long> creatorIds, Long spaceId, Integer accessControl);
/**
* 管理端删除知识库
*
* @param id 知识库ID
*/
void deleteForManage(Long id);
/**
* 根据ID列表查询知识库列表
*
* @param ids 知识库ID列表
* @return 知识库配置列表
*/
List<KnowledgeConfigVo> listByIds(java.util.List<Long> ids);
/**
* 管理端更新知识库管控状态
*
* @param id 知识库ID
* @param status 管控状态
*/
void updateAccessControlStatus(Long id, Integer status, UserContext userContext);
}

View File

@@ -0,0 +1,20 @@
package com.xspaceagi.knowledge.sdk.sevice;
import com.xspaceagi.knowledge.sdk.request.KnowledgeDocumentRequestVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeDocumentResponseVo;
/**
* Q&A搜索接口
*/
public interface IKnowledgeDocumentSearchRpcService {
/**
* 文档搜索
*
* @param requestVo 搜索参数
* @return 列表
*/
public KnowledgeDocumentResponseVo documentSearch(KnowledgeDocumentRequestVo requestVo);
}

View File

@@ -0,0 +1,36 @@
package com.xspaceagi.knowledge.sdk.sevice;
import com.xspaceagi.knowledge.sdk.request.KnowledgeFullTextSearchRequestVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeFullTextSearchResponseVo;
/**
* 知识库全文检索 RPC 服务接口
*
* <p>基于 Milvus BM25 算法的全文检索服务</p>
*
* @author system
* @date 2025-03-31
*/
public interface IKnowledgeFullTextSearchRpcService {
/**
* 全文检索(推荐使用)
*
* <p>基于 BM25 算法的全文检索,支持精确关键词匹配</p>
*
* <p><b>最简使用示例:</b></p>
* <pre>
* KnowledgeFullTextSearchRequestVo request = new KnowledgeFullTextSearchRequestVo();
* request.setKbId(123L);
* request.setQueryText("Spring Boot 开发框架");
* // 其他参数使用默认值即可
* KnowledgeFullTextSearchResponseVo response = rpcService.search(request);
* </pre>
*
* @param requestVo 检索请求参数(只需设置 kbId 和 queryText
* @return 检索结果列表
*/
KnowledgeFullTextSearchResponseVo search(KnowledgeFullTextSearchRequestVo requestVo);
}

View File

@@ -0,0 +1,20 @@
package com.xspaceagi.knowledge.sdk.sevice;
import com.xspaceagi.knowledge.sdk.request.KnowledgeQaRequestVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeQaResponseVo;
/**
* Q&A搜索接口
*/
public interface IKnowledgeQaSearchRpcService {
/**
* Q&A搜索
*
* @param requestVo 请求参数
* @return 列表
*/
public KnowledgeQaResponseVo search(KnowledgeQaRequestVo requestVo);
}

View File

@@ -0,0 +1,53 @@
package com.xspaceagi.knowledge.sdk.vo;
import com.xspaceagi.knowledge.sdk.enums.SegmentEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import lombok.Data;
import java.io.Serializable;
@Schema(description = "分段配置")
@Data
public class SegmentConfigModel implements Serializable {
@Schema(description = "分段类型words: 按照词数分段, delimiter: 按照分隔符分段field: 按照字段分段")
private SegmentEnum segment;
@Schema(description = "分段最大字符数选择words或delimiter时有效")
private Integer words;
@Schema(description = "分段重叠字符数建议设置words的10%-25%")
@Max(value = 100, message = "Overlap characters cannot exceed 100")
@Min(value = 0, message = "Overlap characters cannot be less than 0")
private Integer overlaps;
@Schema(description = "分隔符仅在选择delimiter时有效")
private String delimiter;
@Schema(description = "是否去除连续空白、制表符和空行等默认为True")
private Boolean isTrim;
// @Deprecated
// @Schema(description = "问题字段仅在选择field时有效")
// private String questionField;
//
// @Deprecated
// @Schema(description = "答案字段仅在选择field时有效")
// private String answerField;
public static SegmentConfigModel obtainDefaultModel() {
//自动使用默认值
SegmentConfigModel segmentConfig = new SegmentConfigModel();
segmentConfig.setSegment(SegmentEnum.WORDS);
segmentConfig.setWords(1000);
segmentConfig.setOverlaps(10);
segmentConfig.setIsTrim(true);
return segmentConfig;
}
}