feat(knowledge): 添加知识库批量初始化接口
## 新增功能 1. **KnowledgeBaseController** - POST /api/knowledge/init - 批量初始化知识库 - GET /api/knowledge/stats - 查询统计信息 2. **KnowledgeBaseInitService** - 递归扫描 knowledge_base 目录所有 .md 文件 - 解析 frontmatter 提取元数据 - 自动去重(基于文件路径) - 数据入库到 api_document 表 - 自动加入 L0 内存索引 ## 核心特性 ### 去重机制 - 基于文件相对路径去重 - 支持 force=true 强制重新导入 - 跳过已存在文档,避免重复插入 ### 数据存储 - 数据库:保存文档元数据(title、keywords、summary 等) - L0 索引:加入 KnowledgeIndexService 内存索引 - L1 索引:暂未实现(TODO) ### 错误处理 - 格式无效:frontmatter 解析失败 - 缺少标题:必填字段验证 - 详细的错误信息反馈 ## API 示例 ```bash # 首次导入 curl -X POST http://localhost:9900/api/knowledge/init # 强制重新导入 curl -X POST http://localhost:9900/api/knowledge/init?force=true # 查询统计 curl http://localhost:9900/api/knowledge/stats ``` ## 响应示例 ```json { "success": true, "scanned": 6, "skipped": 0, "inserted": 6, "failed": 0, "details": { "api/payment-errors.md": "导入成功(L0)" } } ``` ## 后续扩展 - [ ] L1 向量索引(Milvus)集成 - [ ] 文档更新检测(基于文件哈希) - [ ] 批量删除接口 - [ ] 进度回调支持 ## 文档 - 使用文档:.docs/2026-06-25-knowledge-base-init-api.md
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package com.superbiz.agent.controller;
|
||||
|
||||
import com.superbiz.agent.service.KnowledgeBaseInitService;
|
||||
import lombok.Data;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 知识库管理控制器
|
||||
* 提供知识库初始化、查询等接口
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/knowledge")
|
||||
public class KnowledgeBaseController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(KnowledgeBaseController.class);
|
||||
|
||||
@Autowired
|
||||
private KnowledgeBaseInitService initService;
|
||||
|
||||
/**
|
||||
* 初始化知识库
|
||||
* 扫描 knowledge_base 目录下的所有文档,去重后批量导入到数据库和 Milvus
|
||||
*
|
||||
* @param force 是否强制重新导入(跳过去重检查)
|
||||
* @return 初始化结果
|
||||
*/
|
||||
@PostMapping("/init")
|
||||
public ResponseEntity<?> initKnowledgeBase(@RequestParam(defaultValue = "false") boolean force) {
|
||||
logger.info("收到知识库初始化请求, force={}", force);
|
||||
|
||||
try {
|
||||
KnowledgeBaseInitService.InitResult result = initService.initializeKnowledgeBase(force);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", true);
|
||||
response.put("message", "知识库初始化完成");
|
||||
response.put("scanned", result.getScanned());
|
||||
response.put("skipped", result.getSkipped());
|
||||
response.put("inserted", result.getInserted());
|
||||
response.put("failed", result.getFailed());
|
||||
response.put("details", result.getDetails());
|
||||
|
||||
logger.info("知识库初始化成功: 扫描={}, 跳过={}, 新增={}, 失败={}",
|
||||
result.getScanned(), result.getSkipped(), result.getInserted(), result.getFailed());
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("知识库初始化失败", e);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "初始化失败: " + e.getMessage());
|
||||
|
||||
return ResponseEntity.internalServerError().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询知识库统计信息
|
||||
*
|
||||
* @return 统计信息
|
||||
*/
|
||||
@GetMapping("/stats")
|
||||
public ResponseEntity<?> getStats() {
|
||||
try {
|
||||
KnowledgeBaseInitService.Stats stats = initService.getStats();
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", true);
|
||||
response.put("totalDocuments", stats.getTotalDocuments());
|
||||
response.put("totalVectors", stats.getTotalVectors());
|
||||
response.put("categories", stats.getCategoryCount());
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("查询统计信息失败", e);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "查询失败: " + e.getMessage());
|
||||
|
||||
return ResponseEntity.internalServerError().body(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user