Docling RAG 实战:如何用 HybridChunker 把文档切分成大模型友好的知识块
【免费下载链接】doclingGet your documents ready for gen AI项目地址: https://gitcode.com/GitHub_Trending/do/docling
Docling 是一款"为生成式 AI 准备文档"的开源文档解析工具,能把 PDF、DOCX、HTML 等文件转成结构化文档;在 RAG(检索增强生成)项目中,它的内置 HybridChunker 混合切分器可以把文档直接切成带上下文、可控 token 数的知识块(chunk),是连接"原始文档"和"大模型检索"的关键一步。本文将带你快速上手这套切分流程。
一、为什么 RAG 效果差,往往输在切分环节
用过大模型的同事应该都遇到过这个问题:知识库检索出来的内容"驴唇不对马嘴",或者答案总是缺一块上下文。问题多半不在模型,而在文档切分:
- 按固定字数硬切:一句话被拦腰截断,语义残缺,向量检索命中率骤降;
- 切分不感知标题层级:检索到"1910s–1950s"这段文字,却不知道它属于"IBM 历史"这一章,大模型容易答非所问;
- token 数失控:切出来的块要么超出 embedding 模型的上下文窗口,要么短到毫无信息量。
Docling 的 HybridChunker 正是针对这三个痛点设计的。
二、HybridChunker 工作原理:只在该切时切,只在该并时并
根据官方切分概念文档的说明,HybridChunker 采用的是"混合策略",分两趟处理:
- 继承层级切分(Hierarchical Chunking):先利用 Docling 解析出的文档结构(标题、段落、列表、表格),按元素天然地分成初始块,并自动挂上所属标题、图片说明等元数据;
- token 感知优化:
- 拆分趟:只有当某个块超出你设定的 token 上限时才拆,且尽量在逗号等标点处断开,保留句子完整性;
- 合并趟:把连续且同属一个标题的小块合并,避免碎片化(可用参数
merge_peers关闭,默认开启)。
简单说就是:只在该切时切,只在该并时并。这套机制的代码入口在 docling/chunking/__init__.py,它从 docling-core 导出了HybridChunker、HierarchicalChunker等全部切分器类。
如上图所示,Docling 的DoclingDocument内部是一棵带层级关系的文档树——"Hybrid"里的"H"就体现在这里:结构信息 + token 计数双管齐下,这正是普通切分库(按字符数硬切)做不到的。
三、三步完成第一次知识块切分
安装后(pip install docling transformers),三步走:
from docling.document_converter import DocumentConverter from docling.chunking import HybridChunker # 1. 解析文档为 DoclingDocument doc = DocumentConverter().convert(source="wiki.md").document # 2. 创建混合切分器(默认参数即可用) chunker = HybridChunker() # 3. 迭代得到知识块,contextualize() 生成带标题上下文的文本 for chunk in chunker.chunk(dl_doc=doc): enriched = chunker.contextualize(chunk) # 把 enriched 送入你的向量库做 embedding注意一个容易踩的坑:chunk.text是"裸文本",而真正适合送给 embedding 模型的是contextualize(chunk)的返回值——它会把文档标题、章节标题拼在正文前面。比如一段正文会被增强成:
IBM 1910s–1950s IBM originated with several technological innovations ...检索命中时,大模型就知道这段话出自"IBM 的 1910s–1950s 章节",回答质量立竿见影。更多交互细节可以参考 hybrid_chunking.ipynb 这个官方示例 Notebook。
四、关键配置:token 数对齐 embedding 模型
实战中最重要的一条经验:切分器的 tokenizer 必须和 embedding 模型的 tokenizer 保持一致。否则"按 512 token 切"可能只是切分器单方面认为的 512,embedding 模型那边早已超长。
Docling 支持 HuggingFace tokenizer(默认)和 OpenAI tiktoken,配置如下:
from transformers import AutoTokenizer from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer tokenizer = HuggingFaceTokenizer( tokenizer=AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2"), max_tokens=512, ) chunker = HybridChunker(tokenizer=tokenizer, merge_peers=True)max_tokens建议设为 embedding 模型上下文窗口略小的值(如 512),给标题上下文预留空间。
五、进阶:跨块表格也能"自带表头"
表格是 RAG 切分的重灾区——一张大表被切到第 3 块时,"列名是什么"已经丢了。HybridChunker 提供了两个贴心参数:
| 参数 | 默认值 | 作用 |
|---|---|---|
repeat_table_header | True | 表格跨块时,每个块开头自动重复表头 |
omit_header_on_overflow | False | 宽表行太宽装不下表头时,允许省略表头保行完整 |
官方在示例中用一份 12 列的客户 CSV 表格演示:切出的每个块都以表头行开头,保证每块独立可理解。完整演示见 hybrid_chunking.ipynb 的表格章节。如果你处理的是代码、日志这类"行结构"敏感的内容,还可以看看 line_based_chunking.ipynb。
六、延伸阅读:从切分到完整 RAG 管线
- docs/concepts/chunking.md:三种切分器(Base / Hybrid / Hierarchical)的完整设计说明;
- docs/examples/rag_langchain.ipynb:HybridChunker 接入 LangChain 构建完整 RAG 应用;
- docs/examples/advanced_chunking_and_serialization.ipynb:高级切分与序列化技巧;
- docs/examples/minimal.py:Docling 最简转换示例。
小结:RAG 的知识块质量 = 文档结构感知 + token 精准控制 + 上下文增强。Docling 的 HybridChunker 把这三件事封装成了一个类:chunk()切块、contextualize()增强,两行核心代码就能让大模型的检索答案从"缺胳膊少腿"变得"上下文完备"。
【免费下载链接】doclingGet your documents ready for gen AI项目地址: https://gitcode.com/GitHub_Trending/do/docling
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考