# 知识库初始化 API 使用文档 ## 概述 提供了知识库批量初始化接口,用于将 `knowledge_base` 目录下的所有 Markdown 文档导入到数据库和向量索引(L0)。 **功能特点**: 1. ✅ **批量扫描**:递归扫描 knowledge_base 目录下所有 .md 文件 2. ✅ **自动去重**:基于文件路径检查,避免重复导入 3. ✅ **数据入库**:保存文档元数据到 MySQL 4. ✅ **L0 索引**:自动加入内存精确匹配索引 5. ⏳ **L1 索引**:暂未实现,需要后续通过独立索引任务完成 --- ## API 接口 ### 1. 初始化知识库 **端点**: ``` POST /api/knowledge/init?force=false ``` **参数**: - `force`(可选):是否强制重新导入,跳过去重检查 - `false`(默认):跳过已存在的文档 - `true`:强制重新导入所有文档 **请求示例**: ```bash # 首次导入(去重模式) curl -X POST http://localhost:9900/api/knowledge/init # 强制重新导入 curl -X POST http://localhost:9900/api/knowledge/init?force=true ``` **响应示例**: ```json { "success": true, "message": "知识库初始化完成", "scanned": 6, "skipped": 0, "inserted": 6, "failed": 0, "details": { "api/payment-errors.md": "导入成功(L0)", "domain/spring-ai-tool-best-practices.md": "导入成功(L0)", "infrastructure/flyway-best-practices.md": "导入成功(L0)", "infrastructure/mysql-connection-pool.md": "导入成功(L0)", "infrastructure/redis-config.md": "导入成功(L0)", "troubleshooting/fault-diagnosis-process.md": "导入成功(L0)" } } ``` **字段说明**: - `scanned`:扫描到的文件总数 - `skipped`:跳过的文件数量(已存在) - `inserted`:成功导入的文件数量 - `failed`:失败的文件数量 - `details`:每个文件的处理结果详情 --- ### 2. 查询知识库统计 **端点**: ``` GET /api/knowledge/stats ``` **请求示例**: ```bash curl http://localhost:9900/api/knowledge/stats ``` **响应示例**: ```json { "success": true, "totalDocuments": 6, "totalVectors": 0, "categories": { "api": 1, "domain": 1, "infrastructure": 3, "troubleshooting": 1 } } ``` **字段说明**: - `totalDocuments`:数据库中的文档总数 - `totalVectors`:Milvus 中的向量总数(当前为 0,未实现) - `categories`:按分类统计的文档数量 --- ## 使用场景 ### 场景 1:项目启动时初始化 ```bash # 1. 启动应用 mvn spring-boot:run # 2. 等待应用启动完成(约 10 秒) # 3. 调用初始化接口 curl -X POST http://localhost:9900/api/knowledge/init # 4. 查看结果 # 日志输出:知识库初始化完成: 扫描=6, 跳过=0, 新增=6, 失败=0 ``` --- ### 场景 2:添加新文档后重新初始化 ```bash # 1. 添加新文档到 knowledge_base 目录 echo "--- title: 新文档 keywords: [测试, test] summary: 这是一个测试文档 category: test --- # 新文档内容 " > knowledge_base/test/new-doc.md # 2. 调用初始化接口(去重模式) curl -X POST http://localhost:9900/api/knowledge/init # 3. 查看结果 # 只会导入新文档,跳过已存在的 6 个文档 # 响应: scanned=7, skipped=6, inserted=1, failed=0 ``` --- ### 场景 3:强制重新导入所有文档 ```bash # 适用场景: # - 数据库被清空,需要重新导入 # - 文档内容有更新,需要刷新 # - 索引损坏,需要重建 curl -X POST http://localhost:9900/api/knowledge/init?force=true # 响应: scanned=6, skipped=0, inserted=6, failed=0 ``` --- ## 去重机制 ### 去重依据 - **文件路径**:相对于 `knowledge_base` 目录的相对路径 - 示例:`api/payment-errors.md` ### 去重逻辑 ``` if (!force && existingFilePaths.contains(relativePath)) { 跳过该文档 } else { 导入该文档 } ``` ### 注意事项 1. **文件移动会被视为新文档**: ```bash # 移动前:api/payment-errors.md # 移动后:errors/payment-errors.md # 结果:会被当作两个不同的文档 ``` 2. **文件重命名会被视为新文档**: ```bash # 重命名前:payment-errors.md # 重命名后:payment-error-codes.md # 结果:会被当作两个不同的文档 ``` 3. **内容更新不触发重新导入**(非 force 模式): ```bash # 修改文件内容后调用 init(非 force) # 结果:跳过该文档,数据库中仍是旧内容 # 解决:使用 force=true 强制重新导入 ``` --- ## 数据存储 ### 数据库表结构(api_document) | 字段 | 类型 | 说明 | 示例 | |------|------|------|------| | `id` | BIGINT | 主键 | 1 | | `doc_id` | VARCHAR(64) | 文档唯一标识 | uuid | | `file_name` | VARCHAR(256) | 文件名 | payment-errors.md | | `file_path` | VARCHAR(512) | 相对路径 | api/payment-errors.md | | `api_name` | VARCHAR(128) | 文档标题 | 支付网关错误码定义 | | `status` | VARCHAR(16) | 状态 | INDEXED | | `metadata` | TEXT | Frontmatter JSON | {"title":"...","keywords":[...]} | | `file_size` | BIGINT | 文件大小(字节) | 2048 | | `indexed_at` | DATETIME | 索引时间 | 2026-06-25 10:00:00 | ### metadata JSON 结构 ```json { "title": "支付网关错误码定义", "summary": "记录了支付网关所有核心错误码的含义及排查方向", "category": "api", "keywords": ["ERR_TIMEOUT","超时","支付网关"] } ``` --- ## L0 内存索引 导入过程会自动将文档加入 `KnowledgeIndexService` 的内存索引: ```java KnowledgeEntry entry = KnowledgeEntry.builder() .filePath(relativePath) .title(title) .keywords(keywords) .summary(summary) .category(category) .build(); knowledgeIndexService.addToIndex(entry); ``` **验证 L0 索引**: ```bash # 应用启动后查看日志 grep "知识库索引加载完成" logs/application.log # 输出示例: # [INFO] 知识库索引加载完成,共 6 个文档 ``` --- ## 错误处理 ### 常见错误 #### 1. 目录不存在 ```json { "success": false, "message": "初始化失败: 知识库目录不存在: knowledge_base" } ``` **解决**: ```bash mkdir -p knowledge_base/api mkdir -p knowledge_base/infrastructure mkdir -p knowledge_base/domain mkdir -p knowledge_base/troubleshooting ``` --- #### 2. 文档格式无效 ```json { "success": true, "scanned": 6, "inserted": 5, "failed": 1, "details": { "test/invalid.md": "格式无效: frontmatter 解析失败" } } ``` **原因**: - 缺少 frontmatter - YAML 格式错误 - 缺少必填字段(title, keywords, summary) **解决**: ```markdown --- title: 文档标题 keywords: [关键词1, 关键词2] summary: 文档摘要 category: api --- # 正文内容 ``` --- #### 3. 文档缺少标题 ```json { "details": { "test/no-title.md": "缺少标题" } } ``` **解决**:在 frontmatter 中添加 `title` 字段。 --- ## 后续扩展(L1 向量索引) 当前版本暂未实现 L1 向量索引(Milvus),计划后续扩展: ### 扩展方案 1. **独立索引任务**: ```bash POST /api/knowledge/build-vectors ``` - 读取数据库中所有文档 - 调用 `DocumentManagementService` 处理分块 - 上传到 Milvus 2. **或者修改当前接口**: - 在 `initializeKnowledgeBase` 中调用文档分块和向量索引 - 需要处理大文件的分块逻辑 ### 验证 L1 的方法(未来) ```bash # 1. 调用 L1 索引构建 curl -X POST http://localhost:9900/api/knowledge/build-vectors # 2. 查询统计信息 curl http://localhost:9900/api/knowledge/stats # 3. 确认 totalVectors > 0 ``` --- ## 最佳实践 ### ✅ 推荐做法 1. **首次启动后立即初始化**: ```bash mvn spring-boot:run sleep 15 # 等待启动完成 curl -X POST http://localhost:9900/api/knowledge/init ``` 2. **新增文档后增量导入**: ```bash # 不使用 force,只导入新文档 curl -X POST http://localhost:9900/api/knowledge/init ``` 3. **定期检查统计信息**: ```bash curl http://localhost:9900/api/knowledge/stats ``` 4. **更新文档内容后强制刷新**: ```bash curl -X POST http://localhost:9900/api/knowledge/init?force=true ``` --- ### ❌ 避免做法 1. **不检查响应就认为成功**: - 始终检查 `failed` 字段 - 查看 `details` 了解具体失败原因 2. **频繁使用 force=true**: - 会重复插入数据(违反唯一约束) - 建议先清理数据库,再使用 force 3. **不检查文档格式就导入**: - 先手动验证 frontmatter 格式 - 确保必填字段完整 --- ## 相关文档 - **知识库使用指南**:`mvp/architecture/knowledge-retrieval-usage.md` - **知识库架构**:`mvp/architecture/knowledge-retrieval-architecture.md` - **Executor Prompt**:`src/main/resources/prompts/executor-prompt.md`