Files
SuperBizAgent-java/.docs/2026-06-25-knowledge-base-init-api.md
T
zhuyongxin dec587959c 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
2026-06-25 10:49:30 +08:00

8.7 KiB
Raw Blame History

知识库初始化 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:强制重新导入所有文档

请求示例:

# 首次导入(去重模式)
curl -X POST http://localhost:9900/api/knowledge/init

# 强制重新导入
curl -X POST http://localhost:9900/api/knowledge/init?force=true

响应示例:

{
  "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

请求示例:

curl http://localhost:9900/api/knowledge/stats

响应示例:

{
  "success": true,
  "totalDocuments": 6,
  "totalVectors": 0,
  "categories": {
    "api": 1,
    "domain": 1,
    "infrastructure": 3,
    "troubleshooting": 1
  }
}

字段说明:

  • totalDocuments:数据库中的文档总数
  • totalVectors:Milvus 中的向量总数(当前为 0,未实现)
  • categories:按分类统计的文档数量

使用场景

场景 1:项目启动时初始化

# 1. 启动应用
mvn spring-boot:run

# 2. 等待应用启动完成(约 10 秒)

# 3. 调用初始化接口
curl -X POST http://localhost:9900/api/knowledge/init

# 4. 查看结果
# 日志输出:知识库初始化完成: 扫描=6, 跳过=0, 新增=6, 失败=0

场景 2:添加新文档后重新初始化

# 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:强制重新导入所有文档

# 适用场景:
# - 数据库被清空,需要重新导入
# - 文档内容有更新,需要刷新
# - 索引损坏,需要重建

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. 文件移动会被视为新文档:

    # 移动前:api/payment-errors.md
    # 移动后:errors/payment-errors.md
    # 结果:会被当作两个不同的文档
    
  2. 文件重命名会被视为新文档:

    # 重命名前:payment-errors.md
    # 重命名后:payment-error-codes.md
    # 结果:会被当作两个不同的文档
    
  3. 内容更新不触发重新导入(非 force 模式):

    # 修改文件内容后调用 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 结构

{
  "title": "支付网关错误码定义",
  "summary": "记录了支付网关所有核心错误码的含义及排查方向",
  "category": "api",
  "keywords": ["ERR_TIMEOUT","超时","支付网关"]
}

L0 内存索引

导入过程会自动将文档加入 KnowledgeIndexService 的内存索引:

KnowledgeEntry entry = KnowledgeEntry.builder()
    .filePath(relativePath)
    .title(title)
    .keywords(keywords)
    .summary(summary)
    .category(category)
    .build();
knowledgeIndexService.addToIndex(entry);

验证 L0 索引:

# 应用启动后查看日志
grep "知识库索引加载完成" logs/application.log

# 输出示例:
# [INFO] 知识库索引加载完成,共 6 个文档

错误处理

常见错误

1. 目录不存在

{
  "success": false,
  "message": "初始化失败: 知识库目录不存在: knowledge_base"
}

解决:

mkdir -p knowledge_base/api
mkdir -p knowledge_base/infrastructure
mkdir -p knowledge_base/domain
mkdir -p knowledge_base/troubleshooting

2. 文档格式无效

{
  "success": true,
  "scanned": 6,
  "inserted": 5,
  "failed": 1,
  "details": {
    "test/invalid.md": "格式无效: frontmatter 解析失败"
  }
}

原因:

  • 缺少 frontmatter
  • YAML 格式错误
  • 缺少必填字段(title, keywords, summary)

解决:

---
title: 文档标题
keywords: [关键词1, 关键词2]
summary: 文档摘要
category: api
---

# 正文内容

3. 文档缺少标题

{
  "details": {
    "test/no-title.md": "缺少标题"
  }
}

解决:在 frontmatter 中添加 title 字段。


后续扩展(L1 向量索引)

当前版本暂未实现 L1 向量索引(Milvus),计划后续扩展:

扩展方案

  1. 独立索引任务:

    POST /api/knowledge/build-vectors
    
    • 读取数据库中所有文档
    • 调用 DocumentManagementService 处理分块
    • 上传到 Milvus
  2. 或者修改当前接口:

    • 在 initializeKnowledgeBase 中调用文档分块和向量索引
    • 需要处理大文件的分块逻辑

验证 L1 的方法(未来)

# 1. 调用 L1 索引构建
curl -X POST http://localhost:9900/api/knowledge/build-vectors

# 2. 查询统计信息
curl http://localhost:9900/api/knowledge/stats

# 3. 确认 totalVectors > 0

最佳实践

✅ 推荐做法

  1. 首次启动后立即初始化:

    mvn spring-boot:run
    sleep 15  # 等待启动完成
    curl -X POST http://localhost:9900/api/knowledge/init
    
  2. 新增文档后增量导入:

    # 不使用 force,只导入新文档
    curl -X POST http://localhost:9900/api/knowledge/init
    
  3. 定期检查统计信息:

    curl http://localhost:9900/api/knowledge/stats
    
  4. 更新文档内容后强制刷新:

    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