上一篇文章中介绍了RAG的总体架构,本篇将对第一个部分RAG文档导入进行介绍和讨论
总体流程
基本流程:原始数据 -> 文本解析 -> 文本切片 (Chunking) -> 向量化 (Embedding) -> 存入向量数据库。

节点一:入口与类型判断 (node_entry)
作为数据加载流程的"总调度员",负责接收外部输入的文件,识别文件类型(PDF或Markdown),并根据类型开启相应的处理分支。同时,它提取文件名作为全局元数据,并初始化任务追踪状态,确保后续流程可追溯、可监控。
实现思路:
- 路由分发 : 采用轻量级的条件判断逻辑,通过文件后缀 (
.pdf/.md) 决定激活is_pdf_read_enabled还是is_md_read_enabled状态位,实现不同格式文件的差异化处理。 - 元数据提取 : 在入口处统一提取文件名 (
file_title),作为贯穿整个知识库构建流程的唯一标识,避免后续节点重复解析。 - 任务监控初始化 : 集成
task_utils,记录当前任务 ID 和初始状态,为前端提供实时的进度反馈。
节点二:PDF 转 Markdown (node_pdf_to_md)
解决非结构化 PDF 文档难以直接处理的痛点,利用 MinerU 高精度解析能力,将 PDF 转换为结构清晰、包含图片引用的 Markdown 格式,为后续的文本切分和图片理解打下基础。
实现思路:
- 云端算力卸载: 考虑到本地 OCR 和布局分析的资源消耗巨大,本节点采用"云端 API"模式,将繁重的解析任务卸载到 MinerU 服务端。
- 异步轮询机制 : 针对大文件解析耗时较长的问题,设计了"上传 -> 提交 -> 轮询 -> 下载"的异步交互流程,通过指数退避或固定间隔轮询状态,避免长连接超时。
- 完整性保障: 解析完成后,不仅提取 Markdown 文本,还同步下载并解压关联的图片资源,保持文档的多模态完整性。
关于解析PDF的两种方案对比
- UnstructuredPDFLoader的核心问题:
信息提取不完整:它主要是一个文本提取工具,在处理包含超链接、复杂表格、数学公式的文档时能力不足,常导致关键信息丢失。
依赖环境复杂:作为封装工具,其正常运作严重依赖unstructured库及其底层组件(如pdfplumber、poppler),安装过程容易出现依赖缺失或版本冲突问题。
- MinerU的局限性:
- 部署与运行成本高:其基于深度学习的模型需要GPU以获得最佳性能,且安装部署比纯Python库复杂,对只想进行简单文本提取的用户来说门槛较高。
- 处理扫描件时可能能力受限:对于纯图像格式的PDF,其OCR能力依赖于集成或额外的OCR引擎,并非其核心优势。
如果你的首要任务是构建RAG系统或处理简单文档,快速上手,应选UnstructuredPDFLoader;如果你的核心需求是深度解析含复杂表格、公式、版面的专业文档,并追求极致精度,则应选择MinerU。
节点三:图片处理 (node_md_img)
实现文档的"多模态语义对齐"。将 Markdown 中的本地图片路径转换为在线可访问的 MinIO 对象存储链接,并利用多模态大模型(VLM)生成图片内容的文字摘要,填入 alt 属性,使纯文本检索模型也能理解图片内容,将图片处理成需要的格式 多模态模型对图片的识别(自己 文件服务器 url 地址,避免相对地址切换无法访问问题)
实现思路:
- 图文解耦与持久化: 将图片从本地文件系统迁移到 MinIO 对象存储,实现计算节点与存储分离,确保知识库在不同环境下的可访问性。
- 语义增强: 引入 qwen3-vl-flash 或其他 VLM 模型(多模态模型),对每张图片进行"看图说话",将视觉信息转化为文本摘要。这使得原本不可被搜索的图片,能够通过文本语义被检索到(如搜索"架构图"能找到对应的图片)。
- 速率控制: 在调用 VLM API 时加入速率限制(Rate Limit),防止因图片过多触发并发风控。
节点四:文档切分 (node_document_split)
将长文档转化为适合向量检索的微观语义单元(Chunk)。通过智能切分策略,在保持语义完整性的前提下,控制切片长度,最大化检索的召回率和准确率。
实现思路:
- 结构化优先: 摒弃简单的固定字符数切分,优先依据 Markdown 标题层级(Headers)进行逻辑分块,确保同一知识点的连贯性。
- 递归优化: 对于超长段落,采用"段落 -> 句子"的递归切分策略。先按换行符切,若仍超长则按句号切,确保切片不会在句子中间截断。
- 上下文保留 : 在每个切片中保留
file_title和parent_title(父级标题),为后续的 LLM 回答提供丰富的上下文背景。
为什么需要对文本分块?
- 模型上下文窗口限制
嵌入/重排序模型:如 BGE-base-zh-v1.5 的上下文窗口为 512 token,若直接处理超过此长度的文本,会导致语义截断,生成的信息不够精确或者有所缺失。
LLM:目前主流大模型上下文长度支持超过32k,但更消耗资源
- 检索精度优化
提升相关性准确性:分块后,每个文本块的语义更集中,无关内容更少,向量相似度计算更精准,能够快速检索到与用户查询最相关的内容,减少误召回。
避免噪声干扰:长文本中可能包含与查询无关的噪声信息,分块可将噪声信息与核心信息分离,避免噪声"稀释"核心内容的权重,提升检索效果。
保持语义完整性: 通过合理的分块策略(如 RecursiveCharacterTextSplitter 递归字符分块),可在拆分长文档的同时,保留文本的语义完整性,避免因切分导致的逻辑断裂,确保大模型能基于完整的证据生成连贯、准确的回答。
常见的文本分块方法固定长度分块(Fixed-Size Chunking)
核心逻辑:按照固定的字符数或 token 数(如 512 token)切分文本,设置固定的重叠长度(overlap),确保上下文连续性。
优点:实现简单、效率高,无需复杂逻辑,适合快速验证 RAG 流程。
缺点:易打断文本语义链路,破坏逻辑完整性,适合结构简单、语义连贯的短文本。
- 递归字符分块(Recursive Character Splitting)
核心逻辑:按层次化分隔符列表(如 \n\n、\n、.、, 等)进行递归切分,优先按大分隔符(段落分隔)切分,若块长度仍超标,再按小分隔符(句子分隔)切分,结合滑动窗口设置重叠。
优点:最大程度保留文本的自然语义边界,减少语义断裂,是目前最常用、适配性最广的分块方法(LangChain 中 RecursiveCharacterTextSplitter 为默认推荐)。
缺点:对分隔符不规范的文档(如无段落分隔的纯文本)效果较差。
- 小-大分块(Small-Large Chunking)
核心逻辑:维护两套向量数据库,一套按句子粒度切分(小块),用于精准匹配用户查询;另一套按段落粒度切分(大块),用于保留完整语义。检索时,先通过小块检索定位相关句子,再通过句子关联到对应的大块,获取完整上下文。
优点:兼顾检索精度和语义完整性,适合长文档、多段落的复杂场景。
缺点:架构复杂,维护成本高,需要额外处理小块与大块的关联关系。
- 基于 LLM 分块(LLM-Based Chunking)
核心逻辑:利用 LLM Agent 模拟人类的阅读理解过程,输入文本后,让 LLM 动态判断语义边界,自主决定分块大小和切分位置,生成符合语义的文本块。
优点:语义划分最精准,能够处理复杂结构、多领域的专业文档,适配性极强。
缺点:成本高,需频繁调用 LLM,效率低,不适合批量处理大量文档。
节点五:主体识别 (node_item_name_recognition)
提取文档的核心实体(如产品名称、特定概念),用于后续的精确过滤和去重。这是构建"实体-切片"关联的关键一步,支持基于实体的结构化查询。
实现思路:
- 上下文压缩: 取文档的前 K 个切片(通常包含标题和摘要)构建 Prompt,利用 LLM 强大的理解能力提取核心实体名称。
- 错误鲁棒性: 考虑到 LLM 输出的不确定性,增加了空结果处理和默认值兜底机制,确保流程不会因识别失败而中断。
- 向量化准备: 识别出的实体名称也会被向量化,用于在 Milvus 中进行基于实体的语义对齐(如搜索"iPhone"能关联到"苹果手机"的切片)。
节点六:向量化 (node_bge_embedding)
将人类可读的文本切片转化为机器可计算的向量表示。采用 BGE-M3 模型,同时生成稠密向量(Dense)和稀疏向量(Sparse),为"混合检索"提供底层数据支持。
实现思路:
- 双路编码: 利用 BGE-M3 的特性,一次推理同时产出语义向量(Dense,捕获语义相似度)和词汇向量(Sparse,捕获关键词匹配),兼顾语义理解和精确匹配。
- 归一化处理: 对稀疏向量进行 L2 归一化,消除文本长度带来的权重偏差,确保检索评分的公平性。
- 批处理优化: 针对大量切片,采用 Batch 处理模式调用模型,大幅提升 GPU/CPU 的计算利用率。
节点七:存入 Milvus (node_import_milvus)
数据加载流程的终点,负责将处理好的结构化数据(切片内容、元数据、向量)持久化存储到向量数据库中,构建可供即时查询的索引。
实现思路:
- 幂等性设计 : 在插入新数据前,根据
item_name或文件 ID 清理旧数据,防止重复导入导致的数据污染。 - Schema 适配: 严格按照 Milvus 集合的 Schema 定义(主键、Dense字段、Sparse字段、JSON元数据字段)组织数据,确保插入成功率。
- 混合索引构建: 确保存入的数据能够支持 Milvus 的 Hybrid Search(Dense + Sparse 加权),最大化检索效果。