本文档为「知识库功能」的完整架构与实施指南。所有代码改动以此为准。
增加知识库功能,包括文档数据管理、结构化数据管理、知识图谱管理。
- 文档数据:上传后分类管理 → 直接向量化入库
- 结构化数据:参考 beekeeper-studio 的数据源管理(含 SQL Console)
- 知识图谱:图谱数据源管理 + 图谱查看
| 子系统 | 选型 | 部署模式 |
|---|---|---|
| 文档向量化 | Milvus + Spring AI starter | 外部独立服务(默认 localhost:19530) |
| 知识图谱 | Neo4j Community | 外部独立服务(默认 bolt://localhost:7687) |
| 结构化数据 | 完整 SQL Console(Monaco Editor) | JDBC 多驱动 + HikariCP 动态连接池 |
| 与工作流集成 | 本期独立,RAG / 图谱查询节点留待下期 | - |
→ 降级策略见第六章。所有外部依赖必须支持「未就绪时优雅降级」,应用能正常启动、UI 可见、提交时给出明确提示。
./data/agent-runs)AbstractJsonRepository)AiModelServiceImpl.clientCache)backend/pom.xml| 依赖 | 版本 | 用途 |
|---|---|---|
org.springframework.ai:spring-ai-starter-vector-store-milvus |
1.0.0(已有 BOM) | Milvus 集成 + EmbeddingModel 自动配置 |
org.neo4j.driver:neo4j-java-driver |
5.27.x | Neo4j Cypher 客户端 |
org.apache.tika:tika-parsers-standard-package |
2.9.2 | PDF/Word/Excel/PPT/HTML 解析 |
org.springframework.boot:spring-boot-starter-jdbc |
已随 boot | 动态数据源(HikariCP) |
mysql:mysql-connector-j |
8.4.x | MySQL 驱动 |
org.postgresql:postgresql |
42.7.x | PG 驱动 |
com.oracle.database.jdbc:ojdbc11 |
23.5.x | Oracle 驱动 |
com.microsoft.sqlserver:mssql-jdbc |
12.8.x | SQL Server 驱动 |
org.xerial:sqlite-jdbc |
3.46.x | SQLite 驱动 |
com.github.ulisesbocchio:jasypt-spring-boot-starter |
3.0.5 | 密码加密(数据源凭据) |
frontend/package.json| 依赖 | 用途 |
|---|---|
cytoscape |
图谱可视化核心 |
cytoscape-cose-bilkent |
自动布局算法 |
sql-formatter |
SQL 美化(4.x ncompact 版本) |
新增 modelType 字段(chat / embedding),现有 chat 模型默认 chat。EmbeddingService 复用 AiModelServiceImpl 的 clientCache 模式构建独立的 EmbeddingModel 缓存。
application.yml 新增配置app:
kb:
enabled: true # 总开关:false 时全部 kb 接口返回 503
upload-dir: ./uploads/kb
max-file-size: 52428800 # 50MB
chunk-size: 1000 # 字符数
chunk-overlap: 200
allowed-mime-types:
- application/pdf
- application/vnd.openxmlformats-officedocument.wordprocessingml.document
- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- application/vnd.openxmlformats-officedocument.presentationml.presentation
- text/plain
- text/markdown
- text/html
milvus:
enabled: true # false 时跳过 bean 创建
host: localhost
port: 19530
collection: kb_documents
vector-dimension: 1024 # 智谱 embedding-2 输出维度
neo4j:
enabled: true
# 默认连接(用户也可在 UI 配置多个)
default-uri: bolt://localhost:7687
default-user: neo4j
default-password: ${NEO4J_PASSWORD:}
spring:
ai:
openai:
embedding:
options:
model: embedding-2 # 智谱 embedding
jasypt:
encryptor:
password: ${JASYPT_KEY:dev-only-key-replace-me-in-prod}
model/entity/KbCategory.java — 树形分类(id, name, parentId, sortOrder)model/entity/KbDocument.java — 文档元数据(id, name, categoryId, sourcePath, fileSize, mimeType, status, chunkCount, vectorCount, errorMessage, createdAt, updatedAt)model/entity/KbChunk.java — 文档分块(id, documentId, chunkIndex, content, vectorId, charCount)repository/KbCategoryRepository.java、KbDocumentRepository.java、KbChunkRepository.javaservice/KbCategoryService.java + impl/KbCategoryServiceImpl.java — 分类 CRUDservice/DocumentService.java + impl/DocumentServiceImpl.java — 上传/解析/分块/向量化service/EmbeddingService.java + impl/EmbeddingServiceImpl.java — 调用 embedding-2(懒加载,复用 AiModelServiceImpl 模式)service/VectorStoreService.java + impl/VectorStoreServiceImpl.java — Milvus 操作(懒加载 + 降级)controller/KbCategoryController.java — 分类 CRUDcontroller/KbDocumentController.java — 上传/列表/分类切换/删除/重新向量化config/MilvusConfig.java — @ConditionalOnProperty("app.milvus.enabled")views/kb/DocumentManagement.vue — 主页:左分类树 + 右文档列表 + 状态徽章components/kb/DocumentUploader.vue — 多文件上传 + 进度 + 分类选择components/kb/CategoryTree.vue(可复用现有 components/skill/CategoryTree.vue,或单独建)api/kb.js — API 客户端上传文件 → 校验 MIME → 落盘 uploads/kb/ → INSERT KbDocument(status=PENDING)
↓
异步处理:
1. Tika 解析为纯文本
2. 递归字符分块 (1000 + overlap 200)
3. INSERT KbChunk 批量
4. 批量 embedding (status=EMBEDDING)
5. Milvus upsert (status=VECTORIZING)
6. status=READY / FAILED
PENDING → PARSING → CHUNKING → EMBEDDING → VECTORIZING → READY
任一步失败 → FAILED(记录 errorMessage)
model/entity/DataSource.java — id, name, type(MYSQL/PG/ORACLE/SQLSERVER/SQLITE), jdbcUrl, username, passwordEnc, createdAtrepository/DataSourceRepository.javaservice/DataSourceService.java + Impl — CRUD + 测试连接service/DynamicJdbcService.java — 按 datasourceId 维护 HikariCP 连接池缓存(LRU + 最大 10 池)service/SchemaExplorerService.java + Impl — listSchemas / listTables / describeTable / countRows / pageQueryservice/SqlGuardService.java — SQL 白名单校验controller/DataSourceController.java — CRUD + 测试连接controller/DataSourceQueryController.java — executeSql / listTables / describeTable / pageQueryviews/kb/DataSourceManagement.vue — 主页:左数据源列表 + 右侧 Tabcomponents/kb/DataSourceForm.vue — 新增/编辑表单 + 测试连接components/kb/TableExplorer.vue — 表/字段树components/kb/SqlConsole.vue — Monaco 编辑器 + 执行按钮 + 历史记录components/kb/QueryResult.vue — 虚拟滚动结果表components/kb/QueryHistory.vue — 查询历史持久化api/datasource.js// SqlGuardService 白名单
ALLOWED_PREFIXES = ["SELECT", "WITH", "EXPLAIN"]
FORBIDDEN_KEYWORDS = ["INSERT", "UPDATE", "DELETE", "DROP", "ALTER",
"CREATE", "TRUNCATE", "GRANT", "REVOKE", "MERGE"]
// 限制
- 单次查询硬超时 30s
- 返回行数硬限 10000
- 禁止系统库(如 information_schema、mysql、sys)
model/entity/GraphSource.java — id, name, uri, username, passwordEnc, createdAtrepository/GraphSourceRepository.javaservice/GraphSourceService.java + Impl — CRUD + 测试连接service/Neo4jExecutorService.java + Impl — 动态 driver 缓存(按 graphId)controller/GraphSourceController.java — CRUD + 图谱数据查询(返回 cytoscape elements 格式)views/kb/GraphSourceManagement.vue — 左图谱列表 + 右图谱可视化components/kb/GraphSourceForm.vue — 连接配置表单components/kb/GraphViewer.vue — cytoscape + cose-bilkent 布局 + 节点点击详情components/kb/NodeDetailPanel.vue — 节点属性展示api/graphsource.jsMATCH (n)-[r]->(m)
RETURN n, r, m
LIMIT 500
后端转换为 cytoscape elements:
{
nodes: [{ data: { id, label, ...properties } }],
edges: [{ data: { id, source, target, label, ...properties } }]
}
router/index.js{ path: '/kb/documents', name: 'KbDocumentManagement',
component: () => import('../views/kb/DocumentManagement.vue') },
{ path: '/kb/datasources', name: 'KbDataSourceManagement',
component: () => import('../views/kb/DataSourceManagement.vue') },
{ path: '/kb/graphs', name: 'KbGraphSourceManagement',
component: () => import('../views/kb/GraphSourceManagement.vue') },
components/layout/AppSidebar.vue新增「知识库」分组,3 个子菜单:
/kb/documents,DocumentTextOutline)/kb/datasources,ServerOutline)/kb/graphs,GitNetworkOutline)@Configuration
@ConditionalOnProperty(name = "app.milvus.enabled", havingValue = "true", matchIfMissing = false)
public class MilvusConfig {
@Bean
public VectorStore vectorStore(...) { ... }
}
// VectorStoreServiceImpl 中所有方法都先检查 bean 是否存在
@Override
public List<String> upsert(List<float[]> vectors, List<Map<String,Object>> metadatas) {
if (!vectorStoreEnabled) {
throw new ServiceException("Milvus 未启用或未连接,请在 application.yml 配置 app.milvus.enabled=true");
}
...
}
// Neo4jExecutorService 用懒加载 driver,不预连接
// 调用时 try-catch ServiceUnavailable,转换为业务异常
// EmbeddingServiceImpl 调用智谱 embedding-2 失败时
// 1. 不抛出致命错误
// 2. 文档状态置 FAILED + errorMessage="embedding 调用失败:xxx"
// 3. 用户在 UI 看到失败状态,可点击"重新向量化"重试
app.kb.enabled=false 时所有 kb Controller 返回 503,便于运维应急降级。
开发期:Milvus/Neo4j/embedding 全部不可用时:
password 字段使用 Jasypt 加密入库@Transient passwordPlain 仅在内存中临时持有../ 等)uploads/kb/,不允许外部直接访问)| Phase | 内容 | 文件数 | 验证条件 | 当前状态 |
|---|---|---|---|---|
| Phase 1 | 基础设施 + 文档数据管理 | 13 | 文档上传 + 分类 + 向量化入库 | ⏳ 进行中 |
| Phase 2 | 结构化数据源管理 | 18 | 5 类 DB 连接 + SQL Console | ⬜ 待启动 |
| Phase 3 | 知识图谱管理 | 11 | Neo4j 连接 + cytoscape 可视化 | ⬜ 待启动 |
每个 Phase 都能独立运行、独立验证。完成一个 Phase 再启动下一个。
# Docker 快速启动
docker run -d --name milvus-standalone \
-p 19530:19530 -p 9091:9091 \
-v ./milvus/data:/var/lib/milvus \
milvusdb/milvus:latest standalone
# 健康检查
curl http://localhost:9091/healthz
# Docker 快速启动
docker run -d --name neo4j \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/change-me \
-v ./neo4j/data:/data \
neo4j:5-community
# Web UI: http://localhost:7474
登录智谱开放平台 → 模型广场 → embedding-2 → 申请开通 → API Key 即复用现有 GLM 的 key
kbRetrievalgraphQuery| 风险 | 应对 |
|---|---|
| Milvus Spring AI starter 版本兼容 | 优先 1.0.0 已有 BOM 锁定版本,开发时验证 |
| Oracle/SQL Server 驱动体积大 | 仅按需引入,发布版可裁剪 |
| H2 与多数据源共存 | DynamicJdbcService 完全独立,使用单独的 DataSource 实例,不与主 EntityManagerFactory 冲突 |
| Tika 依赖膨胀(~30MB) | 文档管理是核心需求,必须接受 |
| 智谱 embedding-2 维度 1024 | Milvus collection 初始化时硬编码,后期不可变 |
文档版本:v1.0 创建日期:2026-06-15 最后更新:2026-06-15 负责人:开发协作(Claude + 用户)