diff --git a/src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java b/src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java index 85367cb..1d144ca 100644 --- a/src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java +++ b/src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java @@ -29,11 +29,8 @@ import java.util.stream.Stream; @Service public class KnowledgeIndexService { - @Value("${knowledge.base-path}") - private String knowledgeBasePath; - @Autowired - private FrontmatterParser frontmatterParser; + private ApiDocumentRepository apiDocumentRepository; /** * 内存索引(线程安全) @@ -41,88 +38,108 @@ public class KnowledgeIndexService { private final List knowledgeIndex = new CopyOnWriteArrayList<>(); /** - * 启动时扫描知识库目录,构建索引 + * 启动时从数据库加载索引 */ @PostConstruct public void loadIndex() { - log.info("开始扫描知识库目录: {}", knowledgeBasePath); + log.info("开始从数据库加载知识库索引"); try { - Path basePath = Paths.get(knowledgeBasePath); + // 从数据库读取所有已索引的文档 + List documents = apiDocumentRepository.findAll(); - // 目录不存在时自动创建 - if (!Files.exists(basePath)) { - Files.createDirectories(basePath); - log.info("知识库目录已创建: {}", basePath.toAbsolutePath()); + int loaded = 0; + for (ApiDocument doc : documents) { + try { + // 从 metadata JSON 中提取信息 + KnowledgeEntry entry = parseDocumentToEntry(doc); + if (entry != null) { + knowledgeIndex.add(entry); + loaded++; + } + } catch (Exception e) { + log.warn("解析文档失败: docId={}, error={}", doc.getDocId(), e.getMessage()); + } } - // 递归扫描 .md 文件 - try (Stream paths = Files.walk(basePath)) { - paths.filter(p -> p.toString().endsWith(".md")) - .forEach(this::indexFile); - } + log.info("知识库索引加载完成,共 {} 个文档", loaded); - log.info("知识库索引加载完成,共 {} 个文档", knowledgeIndex.size()); - - } catch (IOException e) { + } catch (Exception e) { log.error("知识库索引加载失败", e); } } /** - * 索引单个文件 - * - * @param filePath 文件路径 + * 将 ApiDocument 转换为 KnowledgeEntry */ - private void indexFile(Path filePath) { + private KnowledgeEntry parseDocumentToEntry(ApiDocument doc) { + if (doc.getMetadata() == null || doc.getMetadata().isEmpty()) { + return null; + } + try { - // 读取文件内容 - String content = Files.readString(filePath); + // 简单的 JSON 解析 + String metadata = doc.getMetadata(); - // 解析 frontmatter - Frontmatter frontmatter = frontmatterParser.parse(content); - if (frontmatter == null) { - log.debug("跳过文件(无有效 frontmatter): {}", filePath); - return; - } + String title = extractJsonValue(metadata, "title"); + String summary = extractJsonValue(metadata, "summary"); + String category = extractJsonValue(metadata, "category"); + List keywords = extractJsonArray(metadata, "keywords"); - // 提取 category(从路径中获取) - String category = extractCategoryFromPath(filePath.toString()); - - // 构建索引条目 - KnowledgeEntry entry = KnowledgeEntry.builder() - .filePath(filePath.toString()) - .title(frontmatter.getTitle()) - .keywords(frontmatter.getKeywords()) - .summary(frontmatter.getSummary()) + return KnowledgeEntry.builder() + .filePath(doc.getFilePath()) + .title(title != null ? title : doc.getApiName()) + .keywords(keywords) + .summary(summary) .category(category) - .sections(frontmatter.getSections()) .build(); - knowledgeIndex.add(entry); - log.debug("文档已加入索引: title={}, filePath={}", entry.getTitle(), filePath); - - } catch (IOException e) { - log.warn("读取文件失败: {}", filePath, e); + } catch (Exception e) { + log.warn("解析 metadata 失败: {}", doc.getDocId(), e); + return null; } } /** - * 从文件路径中提取 category - * 例如:knowledge_base/api/test.md -> api + * 从 JSON 字符串中提取值 */ - private String extractCategoryFromPath(String filePath) { - String normalized = filePath.replace("\\", "/"); - String[] parts = normalized.split("/"); - - // 查找 knowledge_base 后的第一个目录 - for (int i = 0; i < parts.length - 1; i++) { - if (parts[i].equals("knowledge_base") && i + 1 < parts.length) { - return parts[i + 1]; - } + private String extractJsonValue(String json, String key) { + String pattern = "\"" + key + "\":\""; + int startIndex = json.indexOf(pattern); + if (startIndex == -1) { + return null; } - return "default"; + startIndex += pattern.length(); + int endIndex = json.indexOf("\"", startIndex); + if (endIndex == -1) { + return null; + } + + return json.substring(startIndex, endIndex); + } + + /** + * 从 JSON 字符串中提取数组 + */ + private List extractJsonArray(String json, String key) { + String pattern = "\"" + key + "\":["; + int startIndex = json.indexOf(pattern); + if (startIndex == -1) { + return Collections.emptyList(); + } + + startIndex += pattern.length(); + int endIndex = json.indexOf("]", startIndex); + if (endIndex == -1) { + return Collections.emptyList(); + } + + String arrayContent = json.substring(startIndex, endIndex); + return Arrays.stream(arrayContent.split(",")) + .map(s -> s.trim().replaceAll("^\"|\"$", "")) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList()); } /**