📋 MBE Desktop 创建知识库和上传文档完整流程
🎯 完整流程概览
创建知识库 → 上传文档 → 处理文档 → 知识库就绪
📝 阶段 1-6: 创建知识库流程
(详见 KB_CREATE_COMPLETE_FLOW.md)
简要总结:
- ✅ 用户填写表单(名称、描述、分块大小等)
- ✅ 提交创建请求
- ✅ 后端创建知识库(状态:
pending) - ✅ 显示成功提示
- ✅ 列表刷新
创建后的状态: pending(等待上传文件)
📤 阶段 7: 文档上传流程(新增)
7.1 上传方式
方式 1: 拖放上传(推荐)
位置: 知识库卡片上
操作步骤:
- 创建知识库后,在知识库列表中看到新创建的知识库卡片
- 将文件(PDF/TXT/MD)拖放到卡片上
- 卡片高亮显示(蓝色边框)
- 释放鼠标,文件开始上传
代码实现 (index.tsx:343-353):
const handleDrop = async (e: React.DragEvent) => {
e.preventDefault()
e.stopPropagation()
setDragActive(false)
const files = Array.from(e.dataTransfer.files)
const file = files.find(f => /\.(pdf|txt|md)$/i.test(f.name))
if (file) {
await onUpload(kb.id, file)
}
}
方式 2: 点击上传按钮
位置: 知识库卡片上的上传按钮
操作步骤:
- 点击卡片上的上传图标
- 选择文件(PDF/TXT/MD)
- 文件开始上传
代码实现 (index.tsx:355-360):
const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0]
if (file && /\.(pdf|txt|md)$/i.test(file.name)) {
await onUpload(kb.id, file)
}
}
方式 3: 详情页面上传
位置: 知识库详情模态框
操作步骤:
- 点击知识库卡片上的"查看详情"按钮
- 在详情页面中上传文件
- 文件开始上传
代码实现 (index.tsx:692-697):
const handleUpload = async (file: File) => {
setUploading(true)
try {
await onUpload(kb.id, file)
await onRefresh()
} finally {
setUploading(false)
}
}
7.2 前端上传处理
文件: src/renderer/pages/KnowledgeBase/index.tsx
处理函数 (handleUploadFile):
const handleUploadFile = async (kbId: string, file: File) => {
// 1. 设置上传状态
setUploadingFile(kbId) // 显示"上传中..."
try {
// 2. 调用上传 API
const result = await knowledgeService.uploadFile(kbId, file, {
use_ocr: false, // 是否使用 OCR(扫描版 PDF 需要)
ocr_lang: 'ch', // OCR 语言
})
// 3. 上传成功,刷新列表
if (result.success) {
await loadKnowledgeBases()
}
return result
} catch (error) {
console.error('Failed to upload file:', error)
throw error
} finally {
// 4. 清除上传状态
setUploadingFile(null)
}
}
上传状态显示:
- ✅ 卡片显示"上传中..."状态
- ✅ 显示加载动画
- ✅ 禁用上传按钮
7.3 API 调用
文件: src/renderer/services/knowledgeService.ts
API 方法:
async uploadFile(
kbId: string,
file: File,
options?: {
use_ocr?: boolean
ocr_lang?: string
}
): Promise<UploadFileResponse> {
// 1. 创建 FormData
const formData = new FormData()
formData.append('file', file)
formData.append('use_ocr', String(options?.use_ocr || false))
formData.append('ocr_lang', options?.ocr_lang || 'ch')
// 2. 获取 Token
const token = getAccessToken()
// 3. 发送 POST 请求
const { data } = await axios.post<UploadFileResponse>(
`${API_BASE_URL}/admin/knowledge/upload/${kbId}`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
...(token ? { Authorization: `Bearer ${token}` } : {}),
},
}
)
return data
}
请求详情:
- URL:
POST /admin/knowledge/upload/{kb_id} - 方法: POST
- Content-Type:
multipart/form-data - Body: FormData(包含文件和选项)
7.4 后端处理
文件: mises-behavior-engine/src/api/knowledge.py
API 端点 (@router.post("/upload/{kb_id}")):
@router.post("/upload/{kb_id}")
async def upload_file(
kb_id: str,
background_tasks: BackgroundTasks,
file: UploadFile = File(...),
use_ocr: bool = False,
ocr_lang: str = 'ch'
):
# 1. 检查知识库是否存在
kb = manager.get_knowledge_base(kb_id)
if not kb:
raise HTTPException(status_code=404, detail="知识库不存在")
# 2. 检查文件类型
ext = filename.split(".")[-1].lower()
if ext not in ["pdf", "txt", "md"]:
raise HTTPException(status_code=400, detail="不支持的文件类型")
# 3. 读取文件内容
content = await file.read()
# 4. 大文件处理(> 1MB)- 异步处理
if len(content) > 1024 * 1024:
# 提交到消息队列
result = process_document_upload_task.apply_async(...)
return {
"success": True,
"status": "processing",
"message": "文件正在后台处理,请稍后查看状态"
}
# 5. 小文件处理 - 同步处理
kb = await manager.upload_file(kb_id, filename, content, use_ocr, ocr_lang)
return {
"success": True,
"kb_id": kb_id,
"status": kb.status,
"message": "文件上传成功"
}
7.5 文件处理流程
文件: mises-behavior-engine/src/knowledge/knowledge_manager.py
处理步骤 (upload_file 方法):
async def upload_file(...) -> KnowledgeBase:
# 1. 设置状态为 "processing"
kb.status = "processing"
kb.updated_at = datetime.utcnow().isoformat()
# 2. 保存上传的文件
save_path = UPLOAD_DIR / f"{kb_id}_{file_path.name}"
with open(save_path, "wb") as f:
f.write(file_content)
# 3. 提取文本
if file_type == "pdf":
text, metadata = self.pdf_processor.extract_text(
str(file_path),
use_ocr=use_ocr,
ocr_lang=ocr_lang
)
kb.page_count = metadata.pages
kb.language = metadata.language
elif file_type in ["txt", "md"]:
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
text = f.read()
kb.language = self._detect_language(text)
# 4. 文档质量评估
quality_report = self.pdf_processor.evaluate_quality(text, metadata)
kb.quality_score = quality_report.overall_score
kb.quality_level = quality_report.quality_level
# 5. 权威性评估
authority_report = evaluator.evaluate(...)
kb.authority_score = authority_report.score
kb.authority_level = authority_report.level
# 6. 文本分块
chunks = self._chunk_text(
text,
kb.chunk_size, # 使用创建时设置的分块大小
kb.chunk_overlap # 使用创建时设置的重叠大小
)
kb.chunk_count = len(chunks)
kb.char_count = len(text)
# 7. 生成向量嵌入(如果启用)
if kb.enable_embedding:
embeddings = await self._generate_embeddings(chunks)
kb.embedding_file = save_embeddings(embeddings)
# 8. 更新状态为 "ready"
kb.status = "ready"
# 9. 保存到索引
self._save_index()
return kb
7.6 知识库状态流转
pending (创建后,等待上传文件)
↓
processing (上传文件后,正在处理)
↓
ready (处理完成,可以使用)
↓
error (如果处理失败)
状态说明:
- pending: 知识库已创建,等待上传文件
- processing: 文件正在处理(提取文本、分块、生成向量)
- ready: 处理完成,知识库可以使用
- error: 处理失败,显示错误信息
7.7 上传反馈
上传中
- ✅ 卡片显示"上传中..."状态
- ✅ 显示加载动画(旋转图标)
- ✅ 禁用上传按钮
- ✅ 卡片半透明显示(
opacity-50)
上传成功
- ✅ 列表自动刷新
- ✅ 知识库状态更新为 "processing" 或 "ready"
- ✅ 显示统计信息:
- 块数(
chunk_count) - 字符数(
char_count) - 页数(
page_count,仅 PDF) - 文件类型(
file_type)
- 块数(
上传失败
- ❌ 显示错误信息
- ❌ 知识库状态可能变为 "error"
- ❌ 显示错误消息(
error_message)
📊 完整流程时序图
用户操作流程
↓
1. 点击"创建知识库"
↓
2. 填写表单(名称、描述、分块大小、重叠大小)
↓
3. 点击"创建"按钮
↓
4. POST /admin/knowledge/create
↓
5. 后端创建知识库(状态:pending)
↓
6. 返回成功响应
↓
7. 显示成功提示
↓
8. 关闭创建模态框
↓
9. 刷新知识库列表
↓
10. 用户看到新创建的知识库(状态:pending)
↓
11. 【文档上传步骤】
↓
12. 拖放文件到知识库卡片(或点击上传按钮)
↓
13. POST /admin/knowledge/upload/{kb_id}
↓
14. 后端处理文件:
- 保存文件
- 提取文本
- 质量评估
- 权威性评估
- 文本分块(使用创建时设置的分块大小和重叠大小)
- 生成向量嵌入(如果启用)
↓
15. 更新知识库状态为 "ready"
↓
16. 返回成功响应
↓
17. 刷新知识库列表
↓
18. 用户看到知识库状态变为 "ready"
↓
19. 显示统计信息(块数、字符数、页数等)
🔍 关键点检查
✅ 创建知识库时设置的分块参数
在创建知识库时设置:
chunk_size: 1000(默认)chunk_overlap: 200(默认)enable_embedding: true(默认)
这些参数在文档上传时使用:
- ✅ 文本分块时使用
chunk_size和chunk_overlap - ✅ 如果
enable_embedding为 true,会生成向量嵌入
✅ 文档上传后的处理
处理步骤:
- ✅ 保存文件到服务器
- ✅ 提取文本(PDF/TXT/MD)
- ✅ 文档质量评估
- ✅ 权威性评估
- ✅ 文本分块(使用创建时的参数)
- ✅ 生成向量嵌入(如果启用)
- ✅ 更新知识库状态
📋 完整流程检查清单
创建知识库阶段
- 打开创建模态框
- 填写名称(必填)
- 填写描述(可选)
- 设置分块大小(默认 1000)
- 设置重叠大小(默认 200)
- 选择是否启用向量嵌入(默认 true)
- 点击"创建"按钮
- 显示"创建中..."状态
- 显示成功提示
- 模态框关闭
- 列表刷新
- 新知识库出现在列表中(状态:pending)
文档上传阶段
- 选择上传方式(拖放/点击/详情页)
- 选择文件(PDF/TXT/MD)
- 文件开始上传
- 显示"上传中..."状态
- 后端接收文件
- 后端处理文件(提取文本、分块、生成向量)
- 知识库状态更新为 "processing" 或 "ready"
- 列表刷新
- 显示统计信息(块数、字符数、页数)
🎯 总结
完整流程包含两个主要阶段
创建知识库(阶段 1-6)
- 用户填写表单
- 创建空的知识库
- 状态:
pending
上传文档(阶段 7)
- 用户上传文件
- 后端处理文件
- 状态:
processing→ready
关键点
- ✅ 创建知识库时设置的分块参数会在文档上传时使用
- ✅ 文档上传是独立的步骤,在创建知识库之后进行
- ✅ 支持多种上传方式(拖放、点击、详情页)
- ✅ 大文件会自动异步处理
- ✅ 上传后会进行质量评估和权威性评估
最后更新:2026-02-08