高质量的数据是 RAG 系统效果的基石。本节我们将处理“垃圾进,垃圾出”(Garbage In, Garbage Out)的问题。
不同来源的文档需要转换为统一的中间格式(各类 Parser)。
- PDF:使用
PyMuPDF或Marker提取文本和表格。注意去除页眉页脚的干扰信息。 - Markdown:保留标题层级结构(Header Metadata),这对于后续检索至关重要。
- Word/Excel:使用
python-docx/pandas提取内容。
- 去除乱码和不可见字符。
- 合并断行的段落(PDF 常见问题)。
- 去除无意义的短文本(如“版权所有”)。
我们在第 5 章讨论过分块策略,这里的示例采用 递归字符/结构切分 + overlap 的组合策略。它不是完整语义分块器,但能保留段落和句子边界,适合作为第一版可运行管线。
# 示例:RecursiveCharacterTextSplitter 默认按字符长度度量 chunk_size
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=512, # 字符级块大小;如需 token 级切分,应传入 tokenizer 版本的 length_function
chunk_overlap=64, # 字符级重叠部分,保证上下文连续性
separators=["\n\n", "\n", "。", "!", "?"] # 优先按段落和句子切分
)实战技巧:
- 父子索引 (Parent-Child Indexing):切分成小块(Child)用于向量检索,但检索到后返回其所属的大块(Parent)或全文给 LLM。这能兼顾检索的精准度和上下文的完整性。
可参考公开的嵌入评测(如 MTEB 等)选择候选模型,并结合自身语料与任务评测集做最终选型。
- 开源方向:中文/多语言嵌入模型、指令式嵌入模型等。
- 商用方向:通用嵌入服务,按质量/成本/延迟权衡。
使用向量数据库或带向量扩展的数据库存储向量。务必为每个 Chunk 附带元数据(Metadata):
source: 来源文件名page: 页码created_at: 创建时间category: 文档分类(用于后续过滤)
配套实验把本节的数据读取、分块和元数据保留落成了标准库实现,可先用小样本跑通接口边界:
python3 examples/enterprise_know/enterprise_know.py --query "差旅报销需要在多久内提交?"实验代码位于 examples/enterprise_know/,其中 sample_docs/ 展示了带部门权限元数据的知识库文档。真实系统可以替换为 PDF/Office 解析器、领域嵌入模型和持久化向量库,但应保留来源、权限、版本和分块参数等元数据。
{ "content": "公司差旅报销标准...", "vector": [0.12, -0.05, ...], "metadata": { "source": "员工手册2026版.pdf", "page": 12, "category": "HR" } }