换行问题
PDF 经常把一句话切成多行,需要处理异常换行,否则会影响语义连续性。
RAG 的效果很大程度取决于建库前的数据处理。文档如果读错、噪声太多、分块不合理,后面的 Embedding 和向量检索都会被拖累。
选择源文档
明确哪些资料应该进入知识库,常见格式包括 PDF、Markdown、Word、HTML、TXT、数据库记录等。
读取文档
使用 Loader 把不同格式文档读成统一的 Document 对象,通常包含 page_content 和 metadata。
清洗文本
去掉异常换行、无意义空格、页眉页脚、乱码、重复内容等噪声。
切分文档
由于单个文档的长度往往会超过模型支持的上下文,如果不切分,检索得到的知识可能太长,超出模型的处理能力。切分文档就是把长文档拆成多个 chunk,每个 chunk 是后续检索的基本单位。
保留元数据
保存来源、标题、页码、章节、更新时间等信息,方便引用、过滤和排错。
LangChain 读取文档后,通常会得到 Document 列表:
| 字段 | 作用 |
|---|---|
page_content |
文档正文内容 |
metadata |
来源、页码、文件路径、标题等描述信息 |
PDF 常用 PyMuPDFLoader 读取。优点是速度快,并且能保留页码、文件路径等元数据。
Markdown 可以用 UnstructuredMarkdownLoader 或按标题结构解析。标题层级对后续分块很有帮助。
from langchain_community.document_loaders import PyMuPDFLoader
loader = PyMuPDFLoader("knowledge.pdf")pages = loader.load()
first_page = pages[0]print(first_page.page_content)print(first_page.metadata)换行问题
PDF 经常把一句话切成多行,需要处理异常换行,否则会影响语义连续性。
噪声字符
页码、项目符号、重复空格、乱码、广告信息等都可能降低检索质量。
结构保留
标题、章节、页码不要随便丢,它们是后续引用和过滤的重要元数据。
清洗不是越狠越好。对于法律、合同、技术文档,标点、编号和章节结构本身可能很重要。
分块的本质,是把“整篇文档”变成“适合检索和放入上下文的知识片段”。这样既能控制输入长度,也能让模型拿到更聚焦的参考内容。
| 参数 | 含义 | 影响 |
|---|---|---|
chunk_size |
单个 chunk 的最大长度 | 太大容易噪声多,太小容易语义不完整 |
chunk_overlap |
相邻 chunk 的重叠长度 | 防止切分边界丢失上下文 |
separators |
分块时优先使用的分隔符 | 影响是否按段落、句子、标题切开 |
length_function |
如何计算长度 | 可以按字符,也可以按 token |
常见起步值可以先用 chunk_size=500、chunk_overlap=50,再根据检索效果调整。
from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50,)
split_docs = text_splitter.split_documents(pages)| 文档类型 | 建议策略 |
|---|---|
| 普通长文 | 递归字符分割,优先按段落和句子切 |
| Markdown | 优先按标题层级切,再按长度补切 |
| 代码文档 | 尽量按函数、类、模块边界切 |
| 合同/制度 | 保留条款编号和章节结构 |
| FAQ | 一问一答可以作为天然 chunk |