尼恩:LLM大模型学习圣经PDF的起源
在40岁老架构师 尼恩的读者交流群(50+)中,经常性的指导小伙伴们改造简历。
经过尼恩的改造之后,很多小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试机会,拿到了大厂机会。
2025年开始,尼恩一直在辅导小伙伴们做 AI 架构面试, 很多小伙伴 拿到了 Java + AI 架构offer ,比如下面的案例:
34岁无路可走,一个月翻盘,拿 3个架构offer,靠 Java+Al 逆天改命!!!
3年 程序媛 被裁, 25W-》40W 上岸, 逆涨60%。 Java+AI 太神了, 架构小白 2个月逆天改命
36岁/失业7个月/彻底绝望 。狠卷 3个月 Java+AI ,终于逆风翻盘,顺利 上岸
尼恩架构团队,通过 梳理一个《LLM大模型学习圣经》 帮助更多的人做LLM架构,拿到年薪100W, 这个内容体系包括下面的内容:
- 《Python学习圣经:从0到1精通Python,打好AI基础》
- 《LLM大模型学习圣经:从0到1吃透Transformer技术底座》
- 《LangChain学习圣经:从0到1精通LLM大模型应用开发的基础框架》
- 《LLM大模型学习圣经:从0到1精通RAG架构,基于LLM+RAG构建生产级企业知识库》
- 《SpringCloud + Python 混合微服务架构,打造AI分布式业务应用的技术底层》
- 《LLM大模型学习圣经:从0到1吃透大模型的顶级架构》
- 《LLM 智能体 学习圣经:从0到1吃透 LLM 智能体 的架构 与实操》
- 《LLM 智能体 学习圣经:从0到1吃透 LLM 智能体 的 中台 架构 与实操》
- 《 阿里面试:RAG 怎么优化?探讨一下 RAG优化的7大黄金法则 ?》
- 《LangChain 源码 + GOF设计模式:基于GOF的设计模式,穿透 LangChain 源码》
2. RAGFlow 项目整体架构设计
在尼恩社群中,很多小伙伴要求 深入学习一个 这个工业级的 RAG 框架 —— RAGFlow。
so, 尼恩团队的架构师们, 就写了新的系列,ragflow 圣经。
RAGFlow圣经(4):RAGFlow 数据解析与知识图谱
你有没有想过,现代化的图书馆是如何运作的?
当你走进一座智能图书馆,扫描书籍条码就能自动借阅,输入关键词就能找到相关资料,甚至还能和智能助手对话获取知识解答。
这一切看似神奇的功能背后,其实是一套精密的系统架构在默默运行。
RAGFlow 就像是这样一座现代化的智能图书馆,它不仅能存储和管理文档,更能深度理解文档内容,并通过智能对话为用户提供精准的答案。
在前一章中,我们了解了 RAGFlow 的核心概念——就像了解了图书馆的基本功能。现在,我们要深入"建筑内部",看看这个智能系统是如何设计和建造的。
想象一下,如果你要设计一座能处理数百万份文档、同时服务成千上万用户的智能图书馆,你会怎么设计?
- 需要一个接待大厅处理用户请求
- 需要专门的文档分析中心理解每份文档
- 需要强大的检索系统快速找到相关信息
- 需要智能对话区域与用户交流
- 需要可靠的存储仓库保管所有资料
RAGFlow 的架构设计就是基于这样的现实需求。它采用了微服务架构——就像图书馆的不同功能区域,每个区域都有专门的工作人员和设备,各司其职又协调配合。通过本章的深入分析,你将理解 RAGFlow 如何通过精巧的架构设计,实现一个高性能、高可用的企业级 RAG 平台。
2.1 架构设计理念 - 像设计现代化图书馆一样思考
2.1.1 微服务架构选择 - 就像专业化的分工协作
想象一下现代医院的运作方式:挂号处、化验科、影像科、各个专科门诊都有自己的专业团队,但它们通过完善的流程协调配合。RAGFlow 的架构设计也是这个思路:

为什么选择微服务?
(1) 专业化分工:就像医院里的科室,每个服务都专注于自己最擅长的事情
(2) 独立扩展能力:文档解析很耗 CPU?单独给它加机器。检索压力大?给检索服务单独扩容
(3) 技术选择自由:Python 写 AI 算法,JavaScript 做前端交互,Go 做高并发服务
(4) 故障隔离:一个服务挂了不会让整个系统瘫痪,就像一个科室停诊不影响其他科室
让我们看看 RAGFlow 项目的实际目录结构,就像参观图书馆的各个功能区域:
2.1.2 RAGFlow 项目目录结构详解
ragflow/
├── 📁 api/ # API网关和前端服务 (像图书馆的接待大厅)
│ ├── apps/ # 各个业务模块的API接口
│ │ ├── conversation_app.py # 对话管理接口
│ │ ├── dataset_app.py # 知识库管理接口
│ │ ├── document_app.py # 文档管理接口
│ │ ├── file_app.py # 文件上传接口
│ │ ├── llm_app.py # 大模型配置接口
│ │ └── user_app.py # 用户管理接口
│ ├── db/ # 数据库操作层
│ │ ├── db_models.py # 数据模型定义
│ │ └── services/ # 业务逻辑服务
│ ├── ragflow_server.py # 主服务器入口
│ └── settings.py # API服务配置
│
├── 📁 rag/ # RAG核心引擎 (像图书馆的智能检索系统)
│ ├── app/ # RAG业务逻辑
│ │ ├── retrieval.py # 检索逻辑
│ │ ├── generator.py # 生成逻辑
│ │ └── qa.py # 问答处理
│ ├── flow/ # 工作流管理
│ ├── llm/ # 大模型适配器
│ │ ├── chat_model.py # 对话模型封装
│ │ ├── embedding_model.py # 嵌入模型封装
│ │ └── rerank_model.py # 重排序模型封装
│ ├── nlp/ # 自然语言处理工具
│ │ ├── rag_tokenizer.py # 分词器
│ │ └── search.py # 搜索算法
│ └── utils/ # 工具函数
│
├── 📁 deepdoc/ # 深度文档理解引擎 (像图书馆的文档分析中心)
│ ├── parser/ # 各种文档解析器
│ │ ├── excel_parser.py # Excel解析器
│ │ ├── pdf_parser.py # PDF解析器
│ │ ├── word_parser.py # Word解析器
│ │ └── presentation_parser.py # PPT解析器
│ └── vision/ # 视觉理解模块
│ ├── layout_recognizer.py # 版面识别
│ ├── ocr.py # 光学字符识别
│ └── table_recognizer.py # 表格识别
│
├── 📁 agent/ # Agent智能体系统 (像图书馆的AI助手)
│ ├── component/ # 智能体组件
│ │ ├── begin.py # 开始节点
│ │ ├── retrieval.py # 检索节点
│ │ ├── generate.py # 生成节点
│ │ └── rewrite.py # 重写节点
│ ├── tools/ # 外部工具集成
│ │ ├── bing_search.py # 必应搜索
│ │ ├── google_search.py # 谷歌搜索
│ │ ├── wikipedia.py # 维基百科
│ │ └── arxiv.py # 学术论文搜索
│ └── templates/ # 工作流模板
│
├── 📁 web/ # 前端用户界面 (像图书馆的用户终端)
│ ├── src/
│ │ ├── components/ # React组件
│ │ ├── pages/ # 页面组件
│ │ ├── hooks/ # React Hooks
│ │ └── utils/ # 前端工具函数
│ ├── package.json # 前端依赖配置
│ └── .umirc.ts # UmiJS配置
│
├── 📁 docker/ # 容器化部署 (像图书馆的基础设施)
│ ├── docker-compose.yml # 主服务编排
│ ├── docker-compose-base.yml # 基础服务编排
│ ├── .env # 环境变量配置
│ ├── service_conf.yaml.template # 服务配置模板
│ └── nginx/ # Nginx反向代理配置
│
├── 📁 conf/ # 配置文件 (像图书馆的管理制度)
│ ├── service_conf.yaml # 主服务配置
│ └── logging.yml # 日志配置
│
├── 📁 sandbox/ # 代码执行沙箱 (像图书馆的安全实验室)
│ ├── executor_manager.py # 执行器管理
│ └── runtime/ # 各语言运行时
│
├── 📁 test/ # 测试代码
├── 📁 docs/ # 项目文档
├── pyproject.toml # Python项目配置
├── Dockerfile # Docker镜像构建文件
└── README.md # 项目说明
2.1.3 分层架构设计 - 像盖楼一样层次分明
RAGFlow 的架构就像一栋设计精良的办公楼,每一层都有明确的功能定位:

2.1.4 云原生设计 - 为现代部署而生
现在的应用就像乐高积木,要能够灵活组装、随时拆换。RAGFlow 从设计之初就考虑了这些现代化需求:
容器化就像标准化的货柜:
- 所有服务都打包成 Docker 镜像,就像把货物装进标准货柜
- 不管是在开发环境、测试环境还是生产环境,都能一致地运行
配置外部化就像换衣服:
- 通过
docker/.env和conf/service_conf.yaml灵活配置 - 同一套代码可以适应不同的运行环境
健康检查就像体检:
- 每个服务都有健康检查接口,系统能及时发现问题
- 不健康的服务会被自动重启或替换
2.2 实际架构分析 - 基于 Docker Compose 的现代化部署
理解 RAGFlow 架构最直观的方式就是分析它的 Docker Compose 配置。就像看一份现代化建筑的设计图纸,这些文件定义了构成 RAGFlow 系统的所有服务容器以及它们之间的依赖关系。
2.2.1 容器化架构总览
通过分析实际的 docker-compose.yml 和 docker-compose-base.yml 文件,我们可以看到 RAGFlow 的完整部署架构:

2.2.2 主要服务组件详解
让我们深入了解每个服务组件,就像详细了解一座现代化图书馆的各个部门:
🚀 ragflow-server (API 网关与前端服务)
这就像图书馆的接待大厅和客服中心,是用户与 RAGFlow 系统交互的唯一入口。
核心职责:
- 处理所有 HTTP 请求和 WebSocket 实时连接
- 用户身份认证和权限管理
- 提供 RESTful API 服务
- 前端静态资源服务
实际配置(根据 docker-compose.yml):
ragflow:
image: ${RAGFLOW_IMAGE} # 使用环境变量指定镜像版本
container_name: ragflow-server
ports:
- ${SVR_HTTP_PORT}:9380 # 主 HTTP 服务端口
- 80:80 # 标准 HTTP 端口
- 443:443 # HTTPS 端口
- 9382:9382 # MCP 服务端口
volumes:
- ./ragflow-logs:/ragflow/logs # 日志目录
- ./nginx/ragflow.conf:/etc/nginx/conf.d/ragflow.conf # Nginx 配置
- ./service_conf.yaml.template:/ragflow/conf/service_conf.yaml.template
代码结构:
api/ragflow_server.py- 主入口文件api/apps/- 各业务模块 API 接口web/- React 前端用户界面
📊 MySQL 8.0.39 (主数据库)
就像图书馆的主要目录系统,存储所有关键的结构化数据。
存储内容:用户账户、知识库元数据、文档元数据、对话历史、系统配置
实际配置:
mysql:
image: mysql:8.0.39
command: --max_connections=1000 --character-set-server=utf8mb4
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD}
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
🔍 Elasticsearch 8.11.0 (检索引擎)
就像图书馆的智能检索系统,能够快速找到相关内容。
存储内容:文档分块文本、文本向量嵌入、全文检索索引、语义相似性检索索引
🟥 Redis/Valkey 8 (缓存系统)
就像图书馆的快速借阅区,存放经常被访问的热门信息。
存储内容:用户会话状态、API 访问频率限制、暂时计算结果缓存、分布式锁和任务队列
📰 MinIO (对象存储)
就像图书馆的大型仓库,存放所有的实体文件和多媒体资料。
存储内容:原始文档文件、处理后的文本文件、图片和多媒体文件、备份和导出数据
2.2.3 数据流转分析 - 一份文档的奇妙之旅
想象一下,当你在图书馆上传一份 PDF 文档时,它会经历一段怎样的奇妙之旅呢?让我们跟随一份文档的完整流程:

这个流程就像一本书在图书馆的完整生命周期:从进馆登记、分类编目、上架存放,到最终被读者查找和阅读。每一步都经过精心设计,确保信息能够被准确理解和快速检索。
2.3 核心模块深度剥析 - 深入各个专业部门
现在让我们走进 RAGFlow 的各个“专业部门”,看看它们是如何各司其职的。
2.3.1 📄 DeepDoc 深度文档理解引擎
这就像图书馆的专业文档分析师,能够理解各种复杂文档的结构和内容。
模块位置:deepdoc/ 目录
核心能力:
| 解析器 | 支持格式 | 核心功能 |
|---|---|---|
| PDF 解析器 | OCR 文字识别、版面分析、表格提取 | |
| Word 解析器 | DOCX/DOC | 样式保持、内嵌对象处理 |
| Excel 解析器 | XLSX/XLS | 表格结构解析、数据类型推断 |
| PPT 解析器 | PPTX/PPT | 幻灯片内容提取、图文结合 |
智能分块策略:
- 语义分块:按照语义逻辑切分,保持内容的完整性
- 结构分块:基于文档结构(标题、段落、表格)进行切分
- 动态分块:根据内容复杂度动态调整分块大小
2.3.2 🔍 RAG 检索增强生成引擎
这就像图书馆的智能检索系统和知识顾问,能够精准找到相关信息并综合生成答案。
模块位置:rag/ 目录
检索策略组合:

多维度检索算法:
(1) 关键词全文检索:传统 BM25 算法,快速匹配关键词
(2) 语义向量检索:基于 Embedding 的语义相似性匹配
(3) 混合检索:结合多种算法,取优补短
(4) 重排序机制:使用专门的排序模型优化结果
2.3.3 🤖 RAG 的Agent 智能体系统
这就像图书馆的专业研究员,能够根据复杂问题设计研究方案,调用各种工具和资源。
模块位置:agent/ 目录
工作流组件:
| 组件类型 | 功能描述 | 应用场景 |
|---|---|---|
| 开始节点 | 工作流入口,接收用户输入 | 所有工作流 |
| 检索节点 | 从知识库检索相关信息 | 知识问答 |
| 生成节点 | 调用大模型生成内容 | 文本生成 |
| 工具节点 | 调用外部 API 和工具 | 信息查询 |
| 条件节点 | 根据条件判断流程走向 | 复杂逻辑 |
可集成工具:
- 搜索引擎:Google、必应、百度等
- 学术资源:arXiv、学术搜索等
- 知识库:维基百科、百度百科等
- 计算工具:代码执行、数学计算等
2.3.4 🌐 Web 前端用户界面
这就像图书馆的现代化用户终端,提供直观友好的操作界面。
模块位置:web/ 目录
技术栈:
- 框架:React 18 + UmiJS 4
- 状态管理:Redux Toolkit + React Query
- UI 组件:Antd 5.x
- 样式方案:Tailwind CSS
- 类型检查:TypeScript
核心功能模块:
| 功能模块 | 主要页面 | 核心特性 |
|---|---|---|
| 知识库管理 | 知识库列表、创建、设置 | 文档上传、分块预览、状态监控 |
| 文档管理 | 文档列表、详情、编辑 | 批量上传、解析进度、错误处理 |
| 对话问答 | 聊天界面、历史记录 | 流式响应、引用源显示、多轮对话 |
| Agent 工作流 | 可视化编辑器、调试 | 拖拽式设计、实时执行、日志查看 |
| 系统管理 | 用户管理、模型配置 | 角色权限、API 配置、监控看板 |
2.4 技术亮点与创新特性
2.4.1 多租户架构设计
就像一座现代化商业大厅,能同时服务多个不同的租户,但每个租户的数据和资源都是完全隔离的。
数据隔离策略:
- 数据库级别:每个租户在 MySQL 中有独立的 tenant_id 标识
- 检索索引级别:Elasticsearch 中每个租户有独立的索引
- 文件存储级别:MinIO 中每个租户有独立的 bucket
- 缓存级别:Redis 中使用租户 ID 作为 key 前缀
2.4.2 流式响应体验
就像与一个知识渊博的朋友聊天,他的回答不是一下子都说出来,而是在思考的过程中逐渐表达。
技术实现:
- Server-Sent Events (SSE):保持长连接,实时推送生成内容
- 分块传输:大模型生成的内容分块传输,减少等待时间
- 前端缓冲:智能合并分块,平滑显示效果
2.4.3 异步任务处理
就像现代化工厂的流水线作业,不同的环节可以并行进行,大大提高整体效率。
任务队列设计:
# 示例:文档处理异步任务
class DocumentProcessor:
def process_document_async(self, document_id: str):
"""异步处理文档的完整流程"""
# 1. 文档解析任务
parse_task = self.create_task('parse_document', {
'document_id': document_id,
'priority': 'high'
})
# 2. 分块任务(依赖解析任务)
chunk_task = self.create_task('chunk_document', {
'document_id': document_id,
'depends_on': parse_task.id
})
# 3. 向量化任务(依赖分块任务)
embed_task = self.create_task('embed_chunks', {
'document_id': document_id,
'depends_on': chunk_task.id
})
# 4. 索引建立任务(依赖向量化任务)
index_task = self.create_task('build_index', {
'document_id': document_id,
'depends_on': embed_task.id
})
return [parse_task, chunk_task, embed_task, index_task]
2.4.4 智能并发控制
就像交通管理系统,根据实时情况动态调节资源分配,确保系统稳定运行。
资源管理策略:
- API 限流:每个用户每分钟最多调用 100 次 API
- 并发控制:文档解析最多同时 10 个任务
- 资源熔断:大模型调用失败时自动降级和重试
2.5 可扩展性设计
2.5.1 水平扩展能力
就像乐高积木,可以根据需要灵活地添加更多的模块。
服务扩展策略:
- 无状态设计:所有服务都是无状态的,可以随意增加实例
- 负载均衡:通过 Nginx 或 Kubernetes 实现自动负载均衡
- 数据分片:支持 Elasticsearch 和 MySQL 的水平分片
2.5.2 功能扩展能力
就像一个开放的平台,可以轻松集成新的功能和服务。
插件化架构:
- 文档解析器扩展:可以轻松添加新的文档格式支持
- 大模型适配器:支持集成各种大模型 API
- 外部工具集成:Agent 系统可以扩展新的工具和能力
2.4 RAGFlow API 服务层: RAGFlow 系统交互的唯一窗口。
-
代码位置:
api/ragflow_server.py为主入口,整个api/目录构成完整的 API 服务层 -
技术栈: 基于 Flask/Werkzeug 的 WSGI 应用,支持多线程并发处理
-
核心功能模块:
-
用户身份验证和权限管理:
# api/apps/user_app.py - 用户认证系统 @manager.route("/login", methods=["POST"]) def login(): """用户登录,JWT Token 认证""" email = request.json.get("email") password = request.json.get("password") # 验证用户密码(支持LDAP、OAuth等多种认证方式) user = UserService.authenticate(email, password) if user: # 生成JWT Token,包含用户ID、租户ID、权限等信息 token = generate_jwt_token({ "user_id": user.id, "tenant_id": user.tenant_id, "permissions": user.get_permissions() }) return {"token": token, "user": user.to_dict()} else: return {"error": "Invalid credentials"}, 401 @manager.route("/datasets", methods=["GET"]) @token_required # JWT认证装饰器 def get_datasets(): """获取用户有权限访问的知识库列表""" user_id = get_current_user_id() datasets = DatasetService.get_by_user(user_id) return {"datasets": [ds.to_dict() for ds in datasets]} -
RESTful API 服务提供:
# api/apps/knowledgebase_app.py - 知识库管理API @manager.route("/datasets", methods=["POST"]) def create_dataset(): """创建新的知识库""" data = request.get_json() # 参数验证 required_fields = ["name", "description", "embedding_model"] for field in required_fields: if field not in data: return {"error": f"Missing required field: {field}"}, 400 # 创建知识库记录 dataset = KnowledgebaseService.create( tenant_id=get_current_tenant_id(), user_id=get_current_user_id(), **data ) # 初始化ES索引 ElasticsearchService.create_index(dataset.id) return {"dataset": dataset.to_dict()}, 201 # api/apps/document_app.py - 文档管理API @manager.route("/datasets/<dataset_id>/documents", methods=["POST"]) def upload_document(dataset_id): """上传文档到知识库""" file = request.files.get('file') if not file: return {"error": "No file provided"}, 400 # 文件类型验证 allowed_extensions = {'pdf', 'docx', 'txt', 'md', 'xlsx', 'pptx'} if not allowed_extension(file.filename, allowed_extensions): return {"error": "Unsupported file type"}, 400 # 异步上传处理 try: # 1. 保存文件到MinIO file_path = MinIOService.upload_file(file) # 2. 创建文档记录 document = DocumentService.create( kb_id=dataset_id, filename=file.filename, file_path=file_path, status="processing" ) # 3. 发送解析任务到队列(异步处理) task = { "doc_id": document.id, "file_path": file_path, "parser_config": request.json.get("parser_config", {}) } TaskQueue.send_task("document.parse", task) return { "document": document.to_dict(), "message": "文档上传成功,正在后台处理" }, 202 except Exception as e: logger.error(f"Document upload failed: {e}") return {"error": "Upload failed"}, 500 -
WebSocket 实时通信:
# api/apps/chat_app.py - 实时对话API @manager.route("/conversations/<conv_id>/completion", methods=["POST"]) def chat_completion(conv_id): """流式对话接口,支持SSE(Server-Sent Events)""" def generate_response(): try: message = request.json.get("message") chat_history = ConversationService.get_history(conv_id) # 调用RAG搜索引擎 search_results = SearchService.search( query=message, kb_ids=request.json.get("kb_ids", []), chat_history=chat_history ) # 构建LLM提示词 prompt = PromptBuilder.build_rag_prompt( query=message, context=search_results, chat_history=chat_history ) # 流式调用LLM for chunk in LLMService.stream_chat(prompt): yield f"data: {json.dumps(chunk)}\n\n" # 保存对话记录 ConversationService.add_message( conv_id, message, response, search_results ) except Exception as e: yield f"data: {json.dumps({'error': str(e)})}\n\n" return Response( generate_response(), mimetype='text/event-stream', headers={ 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' } ) -
任务状态追踪和进度推送:
# api/ragflow_server.py - 后台进度更新线程 def update_progress(): """定期检查任务进度并推送给前端""" while True: try: # 获取所有进行中的任务 active_tasks = TaskService.get_active_tasks() for task in active_tasks: # 从Redis获取最新进度 progress = RedisService.get_progress(task.id) if progress: # 推送进度到WebSocket连接的客户端 SocketIOService.emit_progress( task.user_id, task.id, progress ) # 更新数据库状态 if progress.get('status') == 'completed': TaskService.mark_completed(task.id) time.sleep(2) # 每2秒检查一次 except Exception as e: logger.error(f"Progress update failed: {e}") time.sleep(5) # 启动后台进度更新线程 threading.Timer(1.0, delayed_start_update_progress).start()
-
-
技术特性和设计亮点:
- 多租户架构: 完整的租户隔离,支持 SaaS 模式部署
- JWT 认证: 无状态的 token 认证,支持分布式部署
- 流式响应: 支持 Server-Sent Events,提供实时的对话体验
- 异步任务: 耗时操作立即返回,通过消息队列异步处理
- 进度追踪: 实时的任务进度推送,提升用户体验
- 错误处理: 完整的异常处理和错误日志记录
- API 文档: 自动生成的 OpenAPI 文档,便于前端开发
ragflow-worker (异步任务处理器)
职责定位: 专门处理所有计算密集型和耗时的异步任务,是 RAGFlow 系统的“大脑”和“劳动力”。
-
代码位置:
rag/svr/task_executor.py为核心执行引擎 -
技术栈: 基于 Trio 的异步编程模型,最大化并发性能和资源利用率
-
架构设计: 采用了生产者-消费者模式,通过 RabbitMQ 消费任务,实现了系统的水平扩展和高可用
-
核心功能模块:
-
文档解析和分块处理 (集成 DeepDoc 引擎):
# rag/svr/task_executor.py - 文档处理核心流程 async def handle_document_parse_task(task): """ 文档解析任务处理:从原始文件到结构化知识 这是RAGFlow的核心能力:深度文档理解 """ doc_id = task.get("doc_id") parser_type = task.get("parser_id", "general") try: # 1. 获取文档信息和原始文件 document = DocumentService.get_by_id(doc_id) binary_data = MinIOService.download(document.file_path) # 2. 选择合适的解析器 parser = ParserFactory.create_parser( parser_type=parser_type, config=task.get("parser_config", {}) ) # 3. 深度文档解析(DeepDoc技术) # 支持版面分析、表格识别、图像理解、公式识别等 progress_callback = partial(update_task_progress, task["id"]) parsing_result = await parser.parse( filename=document.filename, binary=binary_data, callback=progress_callback ) # 4. 智能分块策略 # 根据文档类型和结构选择最优分块策略 chunker = ChunkerFactory.create_chunker( chunker_type=task.get("chunker_id", "general"), config={ "chunk_token_size": task.get("chunk_token_size", 256), "chunk_overlap": task.get("chunk_overlap", 0.1), "delimiter": task.get("delimiter", "\n!?;\uff1f\uff01") } ) chunks = await chunker.chunk( sections=parsing_result.sections, images=parsing_result.images, callback=progress_callback ) # 5. 批量向量化处理 embedding_model = task.get("embedding_model", "bge-large-zh-v1.5") # 分批处理,防止内存溢出 batch_size = 32 all_vectors = [] for i in range(0, len(chunks), batch_size): batch_chunks = chunks[i:i + batch_size] batch_texts = [chunk.content_with_weight for chunk in batch_chunks] # 调用MCP服务进行向量化 vectors = await MCPService.embed_texts( texts=batch_texts, model=embedding_model ) all_vectors.extend(vectors) # 更新进度 progress = 0.3 + 0.5 * (i + batch_size) / len(chunks) progress_callback(progress, f"向量化进度: {i+batch_size}/{len(chunks)}") # 6. 存储到Elasticsearch # 构建检索索引,支持后续的混合检索 es_documents = [] for chunk, vector in zip(chunks, all_vectors): es_doc = { "chunk_id": chunk.id, "doc_id": doc_id, "kb_id": task["kb_id"], "content": chunk.content, "content_with_weight": chunk.content_with_weight, "content_vector": vector.tolist(), "page_number": chunk.page_number, "position": chunk.position, "img_id": chunk.img_id, "created_time": datetime.utcnow().isoformat() } es_documents.append(es_doc) # 批量写入ES await ElasticsearchService.bulk_index( index_name=f"ragflow_kb_{task['kb_id']}", documents=es_documents ) # 7. 更新文档状态 await DocumentService.update_status( doc_id=doc_id, status="completed", chunk_count=len(chunks), token_count=sum(chunk.token_count for chunk in chunks) ) progress_callback(1.0, f"处理完成,共生成 {len(chunks)} 个文本块") logger.info(f"Document {doc_id} processed successfully") except Exception as e: # 错误处理和状态回滚 await DocumentService.update_status( doc_id=doc_id, status="failed", error_message=str(e) ) logger.error(f"Document {doc_id} processing failed: {e}") raise -
知识图谱构建 (GraphRAG 功能):
async def handle_graph_construction_task(task): """ 知识图谱构建任务:从文本中提取实体关系,构建GraphRAG """ kb_id = task.get("kb_id") try: # 1. 获取所有文本块 chunks = await ElasticsearchService.get_all_chunks(kb_id) # 2. 实体识别和关系抽取 entities = [] relationships = [] for chunk in chunks: # 使用NER模型识别实体 chunk_entities = await NERService.extract_entities( text=chunk.content, entity_types=["PERSON", "ORG", "LOCATION", "CONCEPT"] ) # 使用关系抽取模型识别关系 chunk_relations = await RelationExtractionService.extract_relations( text=chunk.content, entities=chunk_entities ) entities.extend(chunk_entities) relationships.extend(chunk_relations) # 3. 实体消歧和合并 entities = EntityService.deduplicate_and_merge(entities) relationships = RelationshipService.validate_and_filter(relationships) # 4. 存储到图数据库(Neo4j或其他) await GraphDatabaseService.store_knowledge_graph( kb_id=kb_id, entities=entities, relationships=relationships ) logger.info(f"Knowledge graph built for KB {kb_id}: {len(entities)} entities, {len(relationships)} relationships") except Exception as e: logger.error(f"Graph construction failed for KB {kb_id}: {e}") raise -
Agent 工作流执行:
async def handle_agent_workflow_task(task): """ Agent工作流执行任务:处理复杂的多步骤推理任务 """ workflow_dsl = task.get("workflow_dsl") initial_input = task.get("input", {}) try: # 1. 解析工作流DSL canvas = Canvas( dsl=workflow_dsl, tenant_id=task.get("tenant_id"), task_id=task.get("id") ) # 2. 执行工作流 execution_result = await canvas.run(**initial_input) # 3. 保存执行结果 await AgentExecutionService.save_result( task_id=task["id"], result=execution_result ) logger.info(f"Agent workflow {task['id']} executed successfully") except Exception as e: logger.error(f"Agent workflow {task['id']} execution failed: {e}") raise -
并发控制和资源管理:
# rag/svr/task_executor.py - 任务执行框架 # 全局并发控制 chunk_limiter = trio.Semaphore(3) # 最大同时处理3个文档解析任务 embedding_limiter = trio.Semaphore(10) # 最大同时做10个向量化任务 async def task_executor_main(): """ 任务执行器主循环:采用了高效的异步并发模式 """ logger.info("RAGFlow Worker started") async with trio.open_nursery() as nursery: # 启动多个并发的任务处理协程 for i in range(WORKER_CONCURRENCY): nursery.start_soon(handle_task_loop, f"worker-{i}") # 启动健康检查协程 nursery.start_soon(health_check_loop) # 启动指标上报协程 nursery.start_soon(metrics_reporter_loop) async def handle_task_loop(worker_name: str): """ 单个工作协程的任务处理循环 """ while True: try: # 从RabbitMQ获取任务 task_message = await TaskQueue.consume_task( queue_name="ragflow.tasks", timeout=30 ) if task_message: task = json.loads(task_message.body) # 记录任务开始 CURRENT_TASKS[task["id"]] = { "task": task, "worker": worker_name, "start_time": time.time() } try: # 根据任务类型分发到对应的处理函数 await dispatch_task(task) DONE_TASKS += 1 except Exception as e: FAILED_TASKS += 1 logger.error(f"Task {task['id']} failed: {e}") finally: # 清理任务记录 CURRENT_TASKS.pop(task["id"], None) task_message.ack() # 确认消息处理完成 else: # 暂时没有任务,等待一下 await trio.sleep(1) except Exception as e: logger.error(f"Worker {worker_name} error: {e}") await trio.sleep(5)
-
-
技术特性和设计亮点:
- 异步高并发: 基于 Trio 的异步编程,最大化资源利用率
- 智能并发控制: 通过信号量控制不同类型任务的并发数,防止资源耗尽
- 容错设计: 完整的异常处理和任务回滚机制
- 实时监控: 详细的任务执行指标和进度上报
- 水平扩展: 支持多实例部署,通过消息队列实现负载均衡
- 内存管理: 智能的内存使用优化,防止 OOM 问题
- GPU 加速: 支持 CUDA 和 OpenCL,充分利用 GPU 资源加速模型推理
MCP Server (模型上下文协议服务)
职责定位: 为系统提供统一的模型访问接口,支持多种 LLM 和 Embedding 模型。
- 代码位置:
mcp/server/server.py - 核心功能:
- 统一的模型调用接口
- 模型负载均衡和容错处理
- 支持 SSE 和 HTTP 传输协议
- 技术特性:
- 基于 FastAPI/Starlette 构建
- 支持多种传输协议
- 内置鉴权和限流机制
数据服务组件
Elasticsearch (检索引擎)
- 角色: 系统的核心检索引擎,同时承担全文检索和向量检索两种能力
- 数据结构: 文档解析分块后,文本内容和语义向量都会被索引到 ES 中
- 配置文件:
conf/mapping.json定义了索引结构
MySQL (元数据库)
- 角色: 存储系统的所有结构化数据和元数据
- 数据内容: 用户信息、知识库配置、文档元数据、对话历史等
- 模型定义:
api/db/db_models.py
MinIO (对象存储)
- 角色: S3 兼容的对象存储服务,存储所有非结构化数据
- 存储内容: 用户上传的原始文件、生成的图片、中间结果等
- 服务封装:
rag/utils/storage_factory.py
Redis (缓存)
- 角色: 高性能内存数据库,用于缓存和临时数据存储
- 使用场景: 用户会话缓存、任务状态追踪、分布式锁等
- 连接封装:
rag/utils/redis_conn.py
RabbitMQ (消息队列)
- 角色: 系统实现异步解耦的核心组件
- 队列设计: 支持任务优先级、持久化和消费者组
- 流量控制: 防止系统过载,实现平滑的负载处理
2.5 RAGFlow 请求的生命周期:以“上传文档”为例
为了更具体地理解服务间的协作,我们来追踪一次“上传文档”请求的完整生命周期。

流程解读:
(1) 同步阶段 (用户感知): ragflow-server 接收到文件后,迅速将其存入 minio 并向 postgres 写入一条记录,然后立即向 rabbitmq 推送一个任务。整个过程非常快,用户会立刻得到“上传成功”的响应。
(2) 异步阶段 (后台执行): ragflow-worker 作为一个独立的进程,一直在监听 rabbitmq。当它收到新任务后,才开始执行真正耗时的解析和嵌入工作。
(3) 解耦优势: 这种设计使得系统可以轻松应对大量并发上传。即使有成千上万的用户同时上传大文件,ragflow-server 也不会被阻塞,只是 rabbitmq 中的任务会排队等待 ragflow-worker 处理。我们可以通过增加 ragflow-worker 的容器数量来水平扩展系统的处理能力。
2.6 RAGFlow 模块化代码结构
RAGFlow 的代码结构也体现了其清晰的架构思想。
api/: 负责“同步”逻辑,处理与用户直接交互的 API。rag/: 负责“异步”和核心 RAG 逻辑,如flow(数据处理流),nlp(自然语言处理),svr(服务执行器)。agent/: 封装了与智能体相关的所有逻辑,自成体系。utils/: 提供了对外部依赖(如es_conn.py,redis_conn.py)的连接封装,使得上层业务代码无需关心底层连接细节。
这种结构使得开发者可以快速定位到自己关心的代码区域,极大地提高了开发和维护效率。
本章总结 - 现代化智能图书馆的成功秘诀
通过本章的深入分析,我们看到了 RAGFlow 如何通过精巧的架构设计,构建了一个高性能、高可用的企业级 RAG 平台。就像一座现代化的智能图书馆,它的成功秘诀在于:
1. 专业化分工:每个模块都专注于自己最擅长的领域,就像图书馆的不同部门各司其职。
2. 协调配合:通过清晰的接口定义和数据流转,实现了各个模块的完美配合。
3. 智能化设计:从文档理解到智能问答,每个环节都融入了 AI 技术,提供真正智能的服务。
4. 可扩展性:就像乐高积木一样,可以根据需要灵活地扩展和升级。
5. 用户体验:通过流式响应、实时反馈等细节设计,提供了出色的用户体验。
在下一章中,我们将转向实践层面,带你一步步搭建这个智能图书馆。
基于对架构的深入理解,你将更好地理解每个安装步骤的意义,并能够在遇到问题时快速定位和解决。


3086

被折叠的 条评论
为什么被折叠?



