ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

文档处理流水线详解:PDF解析与文本分块策略最佳实践

文档处理流水线详解:PDF解析与文本分块策略最佳实践 文档处理流水线PDF解析与分块策略详解RAG系统的效果好不好很大程度上取决于知识库的质量。而知识库的质量第一步就在文档处理。文档从原始文件到变成可以检索的向量块中间要经过好几步。加载、解析、清洗、分块、向量化。每一步没做好都会影响最终的检索效果。很多人做RAG上来就搞向量数据库、搞高级检索算法。结果文档处理没做好后面再怎么优化都有限。地基打歪了楼盖得再高也不结实。这一篇我们讲文档处理的完整流程。每一步做什么有哪些常见的坑怎么选择合适的分块策略。文档处理的完整流程一个标准的文档处理流水线大概分这么几步。第一步加载。把原始文件读进来PDF、Word、Excel、网页各种格式都有。这一步的目标是把不同格式的文件统一转换成纯文本。第二步清洗。原始文本里有很多没用的东西。页眉页脚、页码、目录、水印、广告、导航栏。这些东西要清理掉不然会混进检索结果里影响质量。第三步分块。把长文本切成一小块一小块的。块太大了搜不准太小了又丢失上下文。切多大、怎么切里面有学问。第四步向量化。把每个文本块转换成向量存到向量数据库里。这样后面才能做语义检索。第五步元数据。给每个块加上元数据。来源文件、页码、章节、作者、时间。这些信息后面检索的时候能用得上也方便溯源。这五步看起来简单每一步都有不少细节。我们一个一个说。文档加载加载是第一步不同格式有不同的加载器。上一篇文件处理工具里讲过这里简单回顾一下。PDF用PyMuPDFLoader或者UnstructuredPDFLoader。效果好的优先选PyMuPDF有图片和复杂排版的用Unstructured加OCR。Word用Docx2txtLoader。需要结构信息用python-docx自己解析。Excel用pandas处理最方便。网页用BeautifulSoup或者UnstructuredHTMLLoader。加载阶段最容易出的问题是格式解析不准确。特别是PDF同样是PDF用不同工具生成的解析出来的质量天差地别。我的建议是先拿你实际的文档样本测一下。看看解析出来的文本对不对、顺序乱不乱、表格能不能读、图片里的文字要不要OCR。测完了再选合适的工具。别想当然地觉得所有PDF都能用同一种方式处理。实际项目里不同来源的PDF可能要写不同的处理逻辑。文本清洗加载出来的原始文本通常是不干净的。有很多噪音需要清理。常见的噪音有这些。页眉页脚和页码。几乎所有长文档都有。每页重复出现不清理的话会被当成正文内容影响检索。目录和索引。文档前面的目录后面的索引都是导航用的不是正文。重复的版权声明和免责声明。很多文档每页底部都有重复很多遍。网页的导航栏、广告、推荐阅读。爬下来的网页大部分内容都是这些正文只占一小部分。乱码和特殊字符。格式转换的时候容易出现。清理的方法根据不同的情况来。页眉页脚可以根据位置信息去掉。PyMuPDF能拿到每个文本块的坐标根据坐标判断是不是页眉页脚。重复内容可以用相似度检测。连续很多页都出现的相同内容大概率是页眉页脚或者版权声明。网页用专门的正文提取库。比如BeautifulSoup配合规则或者用newspaper3k、trafilatura这类专门的正文提取工具。清洗这一步很重要。脏数据进脏数据出。文本不干净后面检索出来的结果也会乱七八糟。文本分块分块是文档处理里最关键的一步。切多大、怎么切直接影响检索效果。分块太大有什么问题。一个块里内容太多可能只有一小部分跟问题相关但整块都被检索出来了。无关信息太多会稀释有效内容影响大模型的判断。也浪费Token。分块太小又有什么问题。一个完整的意思被切成好几块单看哪一块都不完整。检索的时候可能只搜到一半上下文丢了回答就不准确。所以块大小要合适。多大算合适没有标准答案。跟你的文档类型、用户提问方式、用的Embedding模型都有关系。常见的经验值是普通文档200到500个中文字或者500到1000个英文词。代码文档可以大一点800到1500个Token。FAQ类的可以小一点一个问答对就是一块。这只是经验值。实际项目里最好的办法是做实验。试几种不同的块大小看哪种效果最好。常见的分块方法固定大小分块。最简单的方法。按字符数或者Token数切每块固定大小。块之间可以有一些重叠防止意思被切断。LangChain里的RecursiveCharacterTextSplitter就是干这个的。它会优先按段落、句子、单词来切尽量保持语义完整。fromlangchain.text_splitterimportRecursiveCharacterTextSplitter splitterRecursiveCharacterTextSplitter(chunk_size500,chunk_overlap50,separators[\n\n,\n,。,, ],)chunkssplitter.split_text(long_text)这种方法简单通用大部分场景都能用。效果也还可以。按结构分块。根据文档的结构来切。标题、段落、列表、表格按结构单元来分。一块就是一个相对完整的语义单元。比如Markdown文档可以按标题层级来分。一个H2下面的内容作为一块。或者一个H3下面的内容作为一块。Word和HTML也可以按结构来分。标题、段落、表格每个元素单独处理。按结构分块的好处是语义更完整。一个章节讲的是同一个主题放在一块很合理。效果通常比固定大小分块好。缺点是需要解析文档结构。格式不规范的文档结构解析不准分出来的块也有问题。语义分块。更高级的分法。用Embedding来判断每句话的语义相似度语义变化大的地方就切一刀。这样每一块内部的语义是连贯的。听起来很美好实际用起来效果不一定更好。而且速度慢、成本高。除非对分块质量要求特别高不然不太推荐。我的建议说了这么多分块方法到底用哪个。我的建议是先用最简单的。递归字符分割chunk_size设500overlap设50。先把系统跑起来看效果怎么样。效果不好再分析原因。是检索不到相关内容还是搜到的内容不完整。是块太大了还是太小了。然后针对性地调。不要一开始就追求最复杂的方案。很多时候固定大小分块就够用了。把精力花在更影响效果的地方比如重排序、Prompt优化、HyDE这些收益更大。还有一个经验。块里最好带上上文信息。比如每一块的开头加上所属的文档标题和章节标题。这样检索的时候块的上下文更完整相关性判断也更准。元数据每个文本块除了内容本身还要附上一些元数据。常见的元数据有这些。来源信息。文件名、文件路径、URL。用来溯源。位置信息。页码、行号、章节。告诉用户答案在文档的什么位置。分类信息。文档类型、产品分类、部门。用来做过滤。时间信息。创建时间、更新时间。可以按时间排序也可以判断新旧。作者信息。谁写的谁负责。元数据的用处很大。检索的时候可以按元数据过滤只在指定的范围内搜。回答问题的时候可以引用来源增加可信度。不要嫌麻烦。加元数据花不了多少时间后面会很有用。下一篇我们讲向量数据库。切好的文本块怎么存进去怎么搜出来。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表