10 行代码版#
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.org 使用 docling-core 2.106.0 分块。最后一档包含所有 ≥ 512 的分块。
查看数据表
| Token 数 | 层级分块 | 混合分块 · 256 token | 混合分块 · 512 token |
|---|---|---|---|
| 0–63 | 13 | 2 | 0 |
| 64–127 | 27 | 10 | 4 |
| 128–191 | 10 | 10 | 6 |
| 192–255 | 5 | 24 | 3 |
| 256–319 | 2 | 2 | 5 |
| 320–383 | 0 | 0 | 3 |
| 384–447 | 0 | 0 | 4 |
| 448–511 | 2 | 0 | 4 |
| 512+ | 2 | 0 | 1 |
| 分块器 | 分块数 | 平均 token | 最大 | 超过 256 token |
|---|---|---|---|---|
| HierarchicalChunker | 61 | 144 | 1,102(参考文献列表) | 61 个中 5 个(2 个超过 512) |
HybridChunker,max_tokens=256(默认) | 48 | 182 | 256 | 无 |
HybridChunker,max_tokens=512 | 30 | 290 | 512 | 30 个中 16 个(符合设计:上限为 512) |
分块器的区别#
HierarchicalChunker
每个文档元素(段落、列表、表格)一个分块,并附带标题路径。不感知 token:再长的表格或列表也只是一个分块。适合查看结构,用于嵌入有风险。
HybridChunker
从层级分块出发,用你的分词器拆分超过 max_tokens 的块,再合并标题相同的过小相邻块(merge_peers=True)。必须拆分的表格会重复表头(repeat_table_header=True)。
HybridChunker 参数
| 参数 | 默认值 | 含义 |
|---|---|---|
tokenizer | all-MiniLM-L6-v2 分词器 | 用于计数 token;请使用嵌入模型的分词器 |
max_tokens | 分词器自身的上限(此处为 256) | 每个分块的硬上限,包含标题 |
merge_peers | True | 合并标题相同的小型相邻块 |
repeat_table_header | True | 拆分表格时重复表头行 |
omit_header_on_overflow | False | 若仅标题上下文就会超限,则省略它 |
always_emit_headings | False | 为空章节输出只含标题的分块 |
默认值读取自 docling-core 2.106.0 中 HybridChunker 的模型字段。
使用嵌入模型的分词器
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])。
在命令行中分块#
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 组件。
pip install "langchain-docling[local]"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
pip install llama-index-readers-docling llama-index-node-parser-doclingfrom 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 指定分词器。
资料来源
- docling-core 2.106.0 分块器(docling_core/transforms/chunker)
- 官方文档:分块概念
- PyPI 上的 langchain-docling 3.0.0
- PyPI 上的 llama-index-readers-docling 与 llama-index-node-parser-docling
- PyPI 上的 docling-haystack