Home Projects Blog Resume Contact 中文
Back to list
2026年7月3日 3,528 words 8 min read

02-文档进入知识库之前:解析、清洗、结构化和 metadata

上一篇讲 RAG 的边界时,核心结论是:RAG 适合解决模型回答时缺少外部证据的问题。到了这一篇,问题往前推进一层。

#LLM#检索增强#证据链#RAG

02-文档进入知识库之前:解析、清洗、结构化和 metadata

上一篇讲 RAG 的边界时,核心结论是:RAG 适合解决模型回答时缺少外部证据的问题。到了这一篇,问题往前推进一层。

外部知识不能直接丢进向量库。

在很多 demo 里,RAG 的离线链路看起来很简单:加载文档,切分 chunk,生成 embedding,写入向量库。这个流程能帮助理解 RAG 的基本形态,但真实业务里的文档往往没有这么规整。PDF 解析顺序可能混乱,页眉页脚会反复进入正文,表格结构可能被打散,扫描件会引入 OCR 错字,网页正文里混着导航和推荐内容,旧版本文档还可能和新版本文档同时存在。

这些问题如果在入库之前没有处理好,后面的 embedding、向量检索、Rerank 和生成都会受到影响。模型拿到的证据质量,首先取决于知识库里存进去的内容质量。

所以这一篇关注 RAG 的第一道地基:

文档进入知识库之前,需要先被处理成可检索、可追踪、可过滤、可引用的知识单元。

文档处理在 RAG 链路里的位置

文档处理发生在 embedding 之前。

一条更完整的离线链路大概是这样:

原始文档
  -> 加载
  -> 解析
  -> 清洗
  -> 结构化
  -> 切分 chunk
  -> 补 metadata
  -> embedding
  -> 写入索引

这条链路里的每一步都在为后续检索服务。加载负责把不同来源的文档接进来,解析负责把文档内容读出来,清洗负责去掉噪声,结构化负责保留标题、章节、表格、代码块等关系,metadata 负责记录来源、版本、权限和业务属性。到了 embedding 阶段,系统面对的已经不应该是一堆原始文件,而是一批可以被检索和管理的知识单元。

文档处理的目标可以用三个词概括:可检索、可追踪、可过滤

可检索意味着文本足够干净,语义边界尽量完整,后续 chunk 能形成合适粒度。可追踪意味着每段内容都知道来自哪份文档、哪个章节、哪个页面、哪个版本。可过滤意味着系统能根据用户权限、业务范围、发布时间、文档类型等条件,筛掉当前不该出现的内容。

目标关注点
可检索文本干净、语义边界完整、后续 chunk 粒度合理
可追踪能定位到文档、章节、页面、版本和来源
可过滤能按权限、业务范围、时间、文档类型筛选

这三个能力决定了 RAG 是否能进入真实业务场景。一个没有来源、没有版本、没有权限信息的 chunk,即使能被向量检索召回,也很难安全、稳定地用于生产系统。

原始文档直接入库会放大噪声

真实文档天然带着格式和上下文。

PDF 文档里常见多栏排版、页码、页眉页脚、目录、脚注和表格。解析器如果只按页面坐标抽取文本,可能会把左右栏顺序打乱,也可能把每一页重复出现的页眉页脚都写进正文。扫描件还要经过 OCR,识别错误和断行会混进文本。网页解析时,主体内容之外的导航、广告、推荐区、版权声明也可能一起进入知识库。

表格是一个更典型的问题。表格里的值通常依赖行名、列名、单位和说明。如果解析时只保留单元格文本,后续检索可能召回某个数字,却丢掉它属于哪个指标、单位是什么、适用范围是什么。模型看到这种残缺片段时,很容易给出看似流畅但缺少依据的答案。

代码文档也有类似问题。函数签名、注释、调用关系、模块路径和上下文说明共同构成语义。如果入库时只保留零散代码片段,后续检索可能找到一段函数体,却丢掉它所在类、依赖参数和调用场景。

这些问题会在 RAG 链路里持续放大。解析阶段混入的噪声会影响 embedding;结构丢失会影响 chunking;版本信息缺失会导致旧内容继续被召回;权限信息缺失会带来数据泄露风险;来源信息不完整会让答案无法引用和复核。

原始问题后续影响
页眉页脚、广告、导航混入正文embedding 和召回结果被噪声污染
表格、代码、章节结构丢失chunking 容易切断语义
版本、权限、来源信息缺失旧内容残留、权限越界、引用无法复核

文档处理的目标,是尽量保留文档被理解和检索时需要的结构,而不只是把文件变成一段纯文本。

解析:把内容读出来只是开始

解析的第一层任务是把内容读出来,但真正重要的是读出来以后还能保留合理的顺序和结构。

对于 PDF,解析质量常常取决于版面还原能力。多栏文本需要保持阅读顺序,标题和正文需要区分,表格需要尽量保留行列结构,页眉页脚和页码要从正文里剥离。否则,系统虽然“读到了文字”,但这些文字已经不再按照原文逻辑排列。

对于网页,解析重点是正文抽取。网页上真正有价值的通常是文章主体、标题、发布时间、作者、正文段落和必要图片说明。导航栏、侧边栏、相关推荐、评论区和广告内容进入知识库后,会让检索结果混入大量无关片段。

对于 OCR 文档,解析还要考虑识别质量。错字、断行、标点丢失和段落合并都会影响后续语义表达。OCR 结果最好进入清洗和质量标注流程,低质量片段要么修复,要么在 metadata 中记录解析质量,方便后续检索和排查。

对于代码和技术文档,解析时要尽量保留代码块边界、函数名、类名、模块路径和注释说明。代码的语义不只在文本里,也在结构里。RAG 如果服务于代码问答,这些结构信息会直接影响检索结果是否可用。

解析阶段最容易被低估。它看起来只是把文档读出来,实际决定了后面系统读到的是一份结构清楚的资料,还是一堆顺序混乱的文本。

清洗:去掉噪声,也保留上下文

清洗的目标在于让后续检索和生成面对更干净、更稳定的内容,单纯把文本削到最短并不合适。

有些信息通常应该清理掉,比如重复页眉页脚、页码、广告导航、无关版权声明、模板噪声、异常空白、乱码和重复段落。这些内容如果进入向量库,会制造大量相似但无价值的 chunk。用户提问时,它们可能被召回,挤占上下文窗口。

也有些信息需要保留。标题层级、章节编号、表格说明、图片标题、代码注释、版本说明、生效范围和引用来源,都可能成为回答问题时的关键上下文。清洗如果过度,文档会变短,但语义支撑也可能被删掉。

这里的平衡很重要。

清洗更像是在判断哪些信息会帮助后续理解,哪些信息只会干扰检索。比如目录本身可能对普通问答价值不高,但标题层级对 chunking 很有价值;页脚里的公司版权可以清理,但页脚里的文档密级和版本号可能应该保留到 metadata;表格前后的说明文字看起来像普通段落,但它往往决定表格如何被解释。

RAG 的清洗不是单纯的文本清理,更接近知识整理。清洗完成后,文档应该更利于检索,同时没有丢掉回答问题时必要的上下文。

结构化:让知识保留层级和关系

纯文本可以被 embedding,但结构化信息能让检索更可靠。

一份文档通常有标题、章节、段落、列表、表格、图片、代码块和脚注。这些内容彼此存在层级关系。用户问一个制度条款时,答案可能依赖它所在章节;用户问表格里的参数时,答案需要表头、单位和说明;用户问代码逻辑时,答案需要函数名、参数、注释和调用上下文。

结构化处理的价值,是把这些关系尽量保留下来。

内容类型需要尽量保留的结构
章节文本标题层级、章节路径、段落顺序
表格表头、单位、行列关系、表格说明
代码语言类型、文件路径、函数名、类名、注释
图片标题、说明文字、OCR 结果或图像理解结果

标题层级可以帮助系统判断某段内容属于哪个主题。章节路径可以放进 metadata,让后续答案引用更清晰。表格可以用 Markdown 表格、JSON 或其他结构化格式保存,避免行列关系丢失。代码块可以保留语言类型、文件路径、函数名和类名。图片如果需要参与问答,可以保存标题、说明文字、OCR 结果或图像理解结果。

结构化处理也会影响后面的 chunking。文档结构越清楚,切分越容易贴近语义边界。标题可以帮助确定段落归属,表格可以决定是否整块保留,代码结构可以决定按函数还是按类切分。

这也是文档处理和 chunking 的衔接点。入库前结构越清楚,后面切分时越不容易破坏语义。

metadata:让 chunk 有身份

chunk 的原文负责被模型阅读,向量负责被系统检索,metadata 负责让系统知道这段内容是谁、来自哪里、能不能用。

metadata 经常被当成附属字段,但在生产级 RAG 里,它是知识治理的一部分。

来源信息用于溯源。文档 ID、标题、URL、章节路径、页码、段落位置,可以帮助答案给出引用,也方便回答错误时回查。业务信息用于过滤。产品线、部门、文档类型、适用范围、语言,可以帮助系统缩小检索范围。时间信息用于判断新旧。发布时间、更新时间、生效时间、失效时间,可以减少旧文档继续被引用的风险。权限信息用于安全控制。租户、角色、部门、密级,决定这段内容能不能被当前用户看到。

metadata 类型常见字段主要作用
来源信息文档 ID、标题、URL、章节路径、页码引用、溯源、回查
业务信息产品线、部门、文档类型、适用范围检索过滤、范围收敛
时间信息发布时间、更新时间、生效时间、失效时间判断新旧、避免过期引用
权限信息租户、角色、部门、密级权限控制、安全隔离
工程信息解析方式、chunk 策略、embedding 版本、索引版本排查问题、支持重建

还有一类 metadata 用于工程排查,比如解析方式、chunk 策略、embedding 模型版本、索引版本和入库时间。它们不一定直接影响答案内容,但当系统出错时,这些信息可以帮助定位问题。

没有 metadata 的 chunk 也能被检索出来,但系统很难判断它是否适合当前问题。它可能来自旧版本,可能不属于当前产品线,可能没有权限,可能无法引用。RAG 从 demo 走向生产时,metadata 的重要性会迅速上升。

文档处理失败会影响整条链路

文档处理失败,不会停留在入库阶段。

解析乱了,embedding 学到的语义会变得混乱。噪声太多,召回结果会被无关内容污染。结构丢了,chunk 很容易切断语义。metadata 缺失,系统无法做权限过滤和版本判断。来源信息不完整,答案无法引用。文档更新没有记录,旧 chunk 可能继续被召回。

这些问题最终都会表现成用户侧的坏体验:检索不到、答非所问、引用错误、旧答案残留、权限越界、答案无法复核

这也是 RAG 排查时需要往前看的原因。一个在线回答失败,不一定只是检索参数或 Prompt 的问题。很多时候,错误在离线入库阶段已经写进了系统。

文档处理做得越扎实,后面的 embedding、检索、Rerank、上下文工程和生成约束才有更好的基础。

小结

RAG 的第一道地基是文档处理。

文档进入知识库之前,需要经过加载、解析、清洗、结构化、切分和 metadata 补全。解析要尽量保留正确顺序和结构,清洗要去掉噪声但保留必要上下文,结构化要保留标题、表格、代码、章节之间的关系,metadata 要支持溯源、过滤、权限、版本和排查

这些工作看起来发生在离线阶段,却会持续影响在线检索和最终生成。

下一篇进入 chunking。文档已经被清洗和结构化之后,还要面对一个更具体的工程问题:这些资料进入索引时,应该切成多大的知识块,怎样切才能保留语义完整性。