在 RAGFlow 这样的检索增强生成(RAG)系统中,知识库是其核心。用户上传的文档如何高效、可靠地转化为可检索的知识,是系统稳定运行的关键。今天,我们就来深入探讨 RAGFlow 中文件上传到知识库的完整流程,揭秘其背后的任务调度机制。
RAGFlow 的文件上传并非简单的文件存储,而是一个涉及前端交互、后端 API、消息队列、后台服务和多个数据存储组件的复杂协作过程。它确保了文档从原始文件到结构化知识的平稳转换。
在深入流程之前,我们先认识一下这场“幕后之旅”中的主要参与者:
document_app.py
: 处理文档相关的 API 请求。file_service.py
: 负责文件的物理存储和数据库记录。document_service.py
: 管理文档的数据库记录和处理状态。task_service.py
: 负责任务的创建、管理和排队。task_executor.py
): 独立的后台服务,从 Redis 队列中消费任务并执行实际的文档处理工作。用户在 RAGFlow 的 Web 界面上选择文件并点击上传按钮,同时指定文件要上传到哪个知识库(kb_id
)。
/v1/document/upload
)前端将文件数据和知识库 ID (kb_id
) 打包成 multipart/form-data
格式,通过 HTTP POST
请求发送到后端 API 的 /v1/document/upload
路由。
FileService
)后端 document_app.py
中的 /upload
路由接收到请求后,会调用 FileService.upload_document
。
FileService
会执行以下操作:
Document
记录,包含文件的元数据(如名称、大小、类型、存储位置等),并将其初始处理状态设置为待处理(例如 progress=0
)。此时,后端 API 会立即响应前端上传成功,用户界面会显示文件已上传。但请注意,文件此时尚未被解析和索引。
ragflow_server.py
-> DocumentService.update_progress
)这是整个流程中任务调度的核心。RAGFlow 的主服务器 (ragflow_server.py
) 启动时,会启动一个独立的后台线程,该线程会每隔 6 秒调用一次 DocumentService.update_progress()
方法。
DocumentService.update_progress()
的职责是:
progress < 1
) 的文档。Document
记录已存在但尚未有对应的 Task
记录),它会识别出这些文档需要进行初始处理。TaskService.queue_tasks
)当 DocumentService.update_progress()
识别出需要处理的文档时,它会(间接地)触发 TaskService.queue_tasks
函数。
TaskService.queue_tasks
会根据文档类型和配置,生成一个或多个具体的处理任务(Task
记录),例如:
Task
记录会被插入到数据库中。Task
消息会被推送到 Redis 消息队列中。task_executor.py
)独立的 task_executor.py
服务会持续监听 Redis 消息队列。一旦有新的任务消息到达,它就会立即消费该任务。
task_executor
消费任务后,会执行实际的文档处理:
task_executor
会不断更新 Task
记录的 progress
和 progress_msg
,将处理进度反馈回数据库。如果知识库配置了更高级的解析方法(如 RAPTOR 或 GraphRAG),并且初始分块任务已完成,DocumentService.update_progress()
在下一次扫描时会检测到这一点,并触发 TaskService.queue_raptor_o_graphrag_tasks
,将新的 RAPTOR 或 GraphRAG 任务推送到 Redis 队列。task_executor
会再次消费这些任务并执行相应的复杂处理。
task_executor
在完成每个任务后,会更新 Task
记录的状态。DocumentService.update_progress()
也会汇总所有相关任务的进度,最终标记文档为“已完成”或“失败”。
sequenceDiagram
actor User
participant Frontend
participant BackendAPI as Backend API (Flask)
participant FileService
participant DocumentService
participant Redis
participant TaskExecutor as Task Executor
participant ObjectStorage as Object Storage (MinIO)
participant DocumentStore as Document Store (ES/Infinity)
participant RagflowServer as Ragflow Server (Background Thread)
User->>Frontend: 1. Upload File (file, kb_id)
Frontend->>BackendAPI: 2. POST /v1/document/upload (file, kb_id)
BackendAPI->>FileService: 3. upload_document(file, kb_id)
FileService->>ObjectStorage: 3.1. Store File
FileService->>DocumentService: 3.2. insert(document_metadata)
DocumentService-->>FileService: Document Record Created
FileService-->>BackendAPI: Upload Success
BackendAPI-->>Frontend: 4. Upload Success Response
Frontend->>User: File Uploaded (UI Update)
loop Every 6 seconds
RagflowServer->>DocumentService: 5. update_progress()
DocumentService->>DocumentService: 5.1. get_unfinished_docs()
alt Document has no tasks (Newly Uploaded)
DocumentService->>TaskService: 5.2. queue_tasks(doc, bucket, name, priority)
TaskService->>Redis: 5.3. queue_product(initial_task_message)
end
end
TaskExecutor->>Redis: 6. Consume Task Message
TaskExecutor->>ObjectStorage: 7.1. Get File Binary
TaskExecutor->>TaskExecutor: 7.2. Perform Chunking & Embedding
TaskExecutor->>DocumentStore: 7.3. Insert Chunks & Vectors
TaskExecutor->>DocumentService: 7.4. set_progress(task_id, progress, msg)
DocumentService-->>TaskExecutor: Task Progress Updated
alt All initial tasks for document completed
RagflowServer->>DocumentService: 8. update_progress() (next iteration)
DocumentService->>DocumentService: 8.1. get_unfinished_docs()
DocumentService->>TaskService: 8.2. queue_raptor_o_graphrag_tasks(doc, type, priority) (if configured)
TaskService->>Redis: 8.3. queue_product(advanced_task_message)
TaskExecutor->>Redis: 9. Consume Advanced Task Message
TaskExecutor->>TaskExecutor: 10. Perform RAPTOR/GraphRAG Processing
TaskExecutor->>DocumentStore: 10.1. Insert Advanced Chunks/Graph
TaskExecutor->>DocumentService: 10.2. set_progress(task_id, progress, msg)
DocumentService-->>TaskExecutor: Advanced Task Progress Updated
end
DocumentService->>DocumentService: 11. Update Document Overall Status (e.g., DONE)
将代码放入https://www.processon.com/mermaid
中,查看流程
RAGFlow 的知识库文件上传流程是一个精心设计的异步系统。它将文件接收、存储、任务调度和实际处理解耦,通过 Redis 消息队列和后台定时任务实现了高效、可扩展的文档处理能力。这种架构不仅保证了用户体验的流畅性(上传后立即响应),也确保了后台处理的健壮性和可恢复性。
希望这篇博客能帮助您更清晰地理解 RAGFlow 的内部工作原理!