独立指南——与 IBM 及 Docling 项目无隶属关系。 所有命令均在 Docling 2.148.0 上验证。
  1. 首页
  2. RAG 与分块
RAG 指南

Docling 用于 RAG——尊重文档结构的分块

Docling 在 RAG 上的优势是结构:它知道章节、表格和列表从哪里开始、到哪里结束,分块器正是利用这一点。但默认设置仍可能产生被嵌入模型悄悄截断的分块——我们实测了这一点。

已在 Docling 上验证 2.148.0更新于 2026年10月27日含本站实测数据11 分钟阅读
要点速览
  • 使用 HybridChunker:先按文档结构切分,再强制 token 上限并合并过小的相邻块。
  • 让 max_tokens 与嵌入模型一致。在我们的测试论文上,HierarchicalChunker 产生了一个 1,102 token 的分块——超过 all-MiniLM-L6-v2 的 256 token 上限 4 倍多。
  • 嵌入 chunker.contextualize(chunk),而不是 chunk.text:前者会在前面加上章节标题。
  • LangChain:langchain-docling(本地转换需加 [local])· LlamaIndex:llama-index-readers-docling + llama-index-node-parser-docling · Haystack:docling-haystack。

10 行代码版#

pythonchunk.py
from docling.chunking import HybridChunker
from docling.document_converter import DocumentConverter

doc = DocumentConverter().convert("https://arxiv.org/pdf/2408.09869").document

chunker = HybridChunker(max_tokens=256)          # 与嵌入模型一致
for chunk in chunker.chunk(doc):
    text = chunker.contextualize(chunk)          # 标题 + 正文:嵌入这个
    pages = {p.page_no for item in chunk.meta.doc_items for p in item.prov}
    print(len(text), chunk.meta.headings, sorted(pages))

每个分块都带有 meta.headings(所属章节路径)和 meta.doc_items(源元素及其页码和边界框)——足以展示能跳回页面精确位置的引用。

查看真实分块#

我们转换了 9 页的 Docling 技术报告,并用 docling-core 2.106.0 以三种方式分块。下面是实际输出:颜色表示元素类型,条形显示每个分块相对上限的大小,红色表示超出上限。

实测结果#

真实文档上的分块大小分布Docling 技术报告的 token 数(all-MiniLM-L6-v2 分词器,含标题上下文)。
层级分块61 块 · max 1102混合分块 · 256 token48 块 · max 256混合分块 · 512 token30 块 · max 512064128192256320384448512+

docling.org 使用 docling-core 2.106.0 分块。最后一档包含所有 ≥ 512 的分块。

查看数据表
真实文档上的分块大小分布
Token 数层级分块混合分块 · 256 token混合分块 · 512 token
0–631320
64–12727104
128–19110106
192–2555243
256–319225
320–383003
384–447004
448–511204
512+201
分块器分块数平均 token最大超过 256 token
HierarchicalChunker611441,102(参考文献列表)61 个中 5 个(2 个超过 512)
HybridChunker,max_tokens=256(默认)48182256无
HybridChunker,max_tokens=5123029051230 个中 16 个(符合设计:上限为 512)

分块器的区别#

HierarchicalChunker

每个文档元素(段落、列表、表格)一个分块,并附带标题路径。不感知 token:再长的表格或列表也只是一个分块。适合查看结构,用于嵌入有风险。

HybridChunker

从层级分块出发,用你的分词器拆分超过 max_tokens 的块,再合并标题相同的过小相邻块(merge_peers=True)。必须拆分的表格会重复表头(repeat_table_header=True)。

HybridChunker 参数

参数默认值含义
tokenizerall-MiniLM-L6-v2 分词器用于计数 token;请使用嵌入模型的分词器
max_tokens分词器自身的上限(此处为 256)每个分块的硬上限,包含标题
merge_peersTrue合并标题相同的小型相邻块
repeat_table_headerTrue拆分表格时重复表头行
omit_header_on_overflowFalse若仅标题上下文就会超限,则省略它
always_emit_headingsFalse为空章节输出只含标题的分块

默认值读取自 docling-core 2.106.0 中 HybridChunker 的模型字段。

使用嵌入模型的分词器

python
from docling.chunking import HybridChunker
from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer
from transformers import AutoTokenizer

EMBED_MODEL = "BAAI/bge-small-zh-v1.5"           # 换成你用来嵌入的模型
tokenizer = HuggingFaceTokenizer(
    tokenizer=AutoTokenizer.from_pretrained(EMBED_MODEL),
    max_tokens=512,
)
chunker = HybridChunker(tokenizer=tokenizer)

对于 OpenAI 嵌入模型,docling-core 还提供了基于 tiktoken 的 OpenAITokenizer 封装(安装 docling-core[chunking-openai])。

在命令行中分块#

bash
docling convert report.pdf --to chunks --chunks-max-tokens 512 --output chunks/
docling convert report.pdf --to chunks --chunks-type hierarchical
docling convert report.pdf --to chunks --chunks-tokenizer BAAI/bge-small-zh-v1.5

框架加载器#

LangChain

从 langchain-docling 3.0 起,基础包是 docling-serve 的轻量客户端;本地转换需要 local 组件。

bash
pip install "langchain-docling[local]"
python
from langchain_docling import DoclingLoader
from langchain_docling.loader import ExportType

loader = DoclingLoader(
    file_path=["https://arxiv.org/pdf/2408.09869"],
    export_type=ExportType.DOC_CHUNKS,           # 默认;或 ExportType.MARKDOWN
)
docs = loader.load()                             # 每个分块一个 LangChain Document
print(docs[0].metadata.keys())

LlamaIndex

bash
pip install llama-index-readers-docling llama-index-node-parser-docling
python
from llama_index.node_parser.docling import DoclingNodeParser
from llama_index.readers.docling import DoclingReader

reader = DoclingReader(export_type=DoclingReader.ExportType.JSON)
docs = reader.load_data(file_path="https://arxiv.org/pdf/2408.09869")
nodes = DoclingNodeParser().get_nodes_from_documents(documents=docs)

把 JSON 导出与 DoclingNodeParser 搭配使用,节点的元数据中才会保留标题和页面来源。

Haystack 及其他

docling-haystack 提供了 Haystack 转换器组件。Docling 的 README 还把 Crew AI 列为集成之一,docling-mcp 则把转换功能作为工具提供给支持 MCP 的智能体。

实用建议#

  • 为每个向量保存 doc_items 来源,这样回答可以引用页码和位置。
  • 嵌入带上下文的文本,展示原始文本。标题有助于检索,而用户想看的是原文段落。
  • 保留 DoclingDocument JSON。换分词器重新分块时,从 JSON 开始是瞬间完成,从 PDF 开始则很慢。
  • 检查表格。表格是逐行序列化的(我们测试中的形如“Caption, human human = 84-89. …”)。如果答案依赖数字,请专门针对表格问题测试检索效果。
  • 中文文档注意分词器。英文分词器会把中文切成很多 token,同样的文字 token 数可能高得多;请使用与你的中文嵌入模型匹配的分词器来计数。

常见问题

Docling 用于 RAG 最好的分块器是哪个?

大多数情况下是 HybridChunker。它从文档结构出发(与 HierarchicalChunker 相同),拆分超过 token 上限的块,并合并标题相同的过小相邻块。在我们的测试论文上,它让每个分块都在上限之内,而 HierarchicalChunker 产生的分块最大达 1,102 token。

Docling 的 HybridChunker 应该设置多大的 max_tokens?

设为嵌入模型的最大输入长度,并传入该模型的分词器。HybridChunker 默认使用 sentence-transformers/all-MiniLM-L6-v2 的分词器及其 256 token 上限。对于更大的模型(512 或 8,192 token),相应提高 max_tokens。

Docling 的 contextualize() 有什么作用?

它返回在前面加上标题路径的分块文本(例如在段落前加“1 Introduction”)。嵌入带上下文的文本通常能改善检索,因为向量知道这段文字属于哪个章节。

表格如何分块?

表格逐行序列化,能放下时保持在一起。如果表格超出 token 上限,HybridChunker 会拆分它,并默认在每一部分重复表头(repeat_table_header=True)。

能从 Docling 命令行得到分块吗?

可以:docling convert file.pdf --to chunks --chunks-max-tokens 512。用 --chunks-type hierarchical 得到只按结构的分块,用 --chunks-tokenizer 指定分词器。

资料来源