Docling 应用实例详解:从最小转换到 RAG、富化与分块序列化的端到端实战指南
Docling 官方文档的 示例索引 汇集了从单文档转换、图表导出、VLM/ASR 管线,到 RAG 集成、结构化抽取、分块与序列化、图片富化的完整应用配方。本篇以该索引为主线,逐一解读每类示例的真实代码(均位于 docs/examples/ 目录),并结合 DocumentConverter 等核心源码说明参数含义与底层机制,帮助读者把官方示例直接落地为自己的文档处理工作流。
示例总览:官方推荐的五大类别
示例索引页把全部配方分为五组,这也是使用 Docling 的典型能力分层:
| 类别 | 代表示例 | 解决什么问题 |
|---|---|---|
| 转换(conversion) | 最小转换、导出图片、导出表格、VLM 管线、音频管线、XBRL | 把 PDF/DOCX/HTML/音频等输入转成统一的 Docling 文档 |
| RAG 集成 | LangChain、LlamaIndex、Haystack、视觉定位、Milvus、Weaviate、Qdrant | 把文档接入三大框架与多种向量库,构建可溯源的检索增强生成 |
| 结构化抽取(beta) | extraction.ipynb | 从文档中抽取结构化的键值数据 |
| 序列化与分块 | 序列化、混合分块、高级定制 | 控制 Docling 文档的文本输出格式,以及面向嵌入模型的分块策略 |
| 图片富化 | 图片标注、远程标注、API 用量捕获、富化已有文档 | 用视觉模型为图片生成描述,并可对已转换文档做后处理富化 |
所有示例统一采用「文件头部 # %% [markdown] 注释块 + 可运行代码」的组织方式,注释块内写明用途、前置依赖(Prerequisites)、运行方式(How to run)和关键选项(Key options),本身即可当作使用说明书阅读。
最小转换示例:三行代码完成文档解析
docs/examples/minimal.py 是最简入口,完整代码如下:
from docling.document_converter import DocumentConverter
# Change this to a local path or another URL if desired.
source = "https://arxiv.org/pdf/2408.09869"
converter = DocumentConverter()
result = converter.convert(source)
# Print Markdown to stdout.
print(result.document.export_to_markdown())
它的要点在于:
- 输入自动识别:
DocumentConverter会根据后缀/内容自动路由到对应后端(PDF、DOCX、HTML、PPTX、图片等),source可以是本地路径(如Path("/path/to/file.pdf"))也可以是 URL;使用默认 URL 需要网络访问,离线场景应换成本地文件。 - 零配置:不传任何
format_options时使用默认 PDF 管线(PdfPipelineOptions)与默认后端,适合快速验证。 - 输出统一:
result.document是DoclingDocument对象,export_to_markdown()只是其众多序列化方法之一(JSON、HTML、doctags、纯文本等见下文批量导出示例)。
运行方式:在仓库根目录执行 python docs/examples/minimal.py;批量处理场景则参考 docs/examples/batch_convert.py。
批量转换与多格式导出:convert_all 与 save_as_*
docs/examples/batch_convert.py 演示了工程化批处理的标准姿势,核心分为两步:
第一步,配置管线并批量转换。示例显式指定了 PdfPipelineOptions 与后端,并通过 convert_all(..., raises_on_error=False) 保证单个文件失败不中断整体:
pipeline_options = PdfPipelineOptions()
pipeline_options.generate_page_images = True # HTML 内嵌图片预览需要页图
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(
pipeline_options=pipeline_options, backend=DoclingParseDocumentBackend
)
}
)
conv_results = doc_converter.convert_all(
input_doc_paths,
raises_on_error=False, # 让所有文件跑完,最后再汇总检查
)
第二步,按 ConversionStatus 分类处理结果,并对每个成功文档调用一组 save_as_* 辅助方法落盘:
conv_res.document.save_as_json(output_dir / f"{doc_filename}.json",
image_mode=ImageRefMode.PLACEHOLDER)
conv_res.document.save_as_html(output_dir / f"{doc_filename}.html",
image_mode=ImageRefMode.EMBEDDED)
conv_res.document.save_as_doctags(output_dir / f"{doc_filename}.doctags.txt")
conv_res.document.save_as_markdown(output_dir / f"{doc_filename}.md",
image_mode=ImageRefMode.PLACEHOLDER)
conv_res.document.save_as_markdown(output_dir / f"{doc_filename}.txt",
image_mode=ImageRefMode.PLACEHOLDER,
strict_text=True)
这里可以学到三个易被忽略的细节:
ImageRefMode三态:EMBEDDED(base64 内嵌)、REFERENCED(引用外部图片文件)、PLACEHOLDER(占位符文本)。JSON 与 Markdown 用占位符保持文件轻量,HTML 用内嵌便于直接预览。strict_text=True导出纯文本(.txt),适合直接喂给 LLM。- 结果状态机:除
SUCCESS外还有PARTIAL_SUCCESS(部分页失败,conv_res.errors中带有每条错误信息),批量脚本据此输出成功/部分成功/失败三种计数,任一失败则最后抛出RuntimeError。 - 除
save_as_*外,示例还展示了底层export_to_dict()(经yaml.safe_dump写成 YAML)、export_to_doctags()、export_to_markdown(strict_text=True)等原始方法,二者输出可能重叠但可控性更强。
导出页面、图片与元素截图:export_figures.py 全解
docs/examples/export_figures.py 展示了如何从 PDF 中批量导出「整页图 + 每张图表/插图截图」,关键配置有三个:
IMAGE_RESOLUTION_SCALE = 2.0 # scale=1 约等于 72 DPI,2.0 翻倍
pipeline_options = PdfPipelineOptions()
pipeline_options.images_scale = IMAGE_RESOLUTION_SCALE
pipeline_options.generate_page_images = True # 保留整页图片
pipeline_options.generate_picture_images = True # 为插图元素附加图片
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
}
)
images_scale控制渲染分辨率;generate_page_images/generate_picture_images两个开关决定哪些元素会被附上图片数据——不开启时page.image与element.get_image()将不可用。- 保存整页图:遍历
conv_res.document.pages,用page.image.pil_image.save(fp, format="PNG")写出{文档名}-{页号}.png。 - 保存图表/插图截图:用
doc.iterate_items()遍历所有元素,按TableItem/PictureItem类型分派,调用element.get_image(conv_res.document)得到该元素在页面上的裁剪图并落盘。 - 多种图片引用模式:同一文档分别导出为内嵌图片的 Markdown(
ImageRefMode.EMBEDDED)、引用图片的 Markdown(ImageRefMode.REFERENCED)和引用图片的 HTML。
示例还用一个实用技巧控制 CI 时长:读取 CI 环境变量,在 CI 中只转换第 3–4 页(CI_PAGE_RANGE = (3, 4)),本地则用 DEFAULT_PAGE_RANGE 转换全文,通过 converter.convert(input_doc_path, page_range=page_range) 传入。输入默认取仓库自带的测试 PDF tests/data/pdf/sources/2206.01062.pdf,输出全部写入 scratch/ 目录。
表格导出为 DataFrame / CSV / HTML
docs/examples/export_tables.py 演示表格的结构化消费方式。转换后直接遍历 conv_res.document.tables(表格对象列表),每个表格提供两种导出通道:
for table_ix, table in enumerate(conv_res.document.tables):
# 结构化:pandas DataFrame,便于后续处理
table_df: pd.DataFrame = table.export_to_dataframe(doc=conv_res.document)
print(f"## Table {table_ix}")
print(table_df.to_markdown()) # 可选,需要 tabulate
table_df.to_csv(output_dir / f"{doc_filename}-table-{table_ix + 1}.csv")
# 保真:带合并单元格语义的 HTML
with (output_dir / f"{doc_filename}-table-{table_ix + 1}.html").open("w") as fp:
fp.write(table.export_to_html(doc=conv_res.document))
注意事项(来自示例头部注释):export_to_dataframe() 返回 pandas.DataFrame,依赖 pandas;DataFrame.to_markdown() 需要可选包 tabulate(pip install tabulate),若不可用可改用 to_csv()。两个 export_to_* 方法都需要传入 doc=conv_res.document,用于解析表格单元格中的图片等跨引用。
VLM 管线:三种递进式配置(默认 / 预设 / 运行时覆盖)
docs/examples/minimal_vlm_pipeline.py 演示用视觉语言模型驱动 PDF 转换的三种写法,由简到繁:
写法一:纯默认。 只指定 VlmPipeline 作为管线类,模型与运行时全部自动选择(默认 GraniteDocling 模型,按平台自动挑最佳运行时):
converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_cls=VlmPipeline),
}
)
doc = converter.convert(source=source).document
print(doc.export_to_markdown())
写法二:显式预设(推荐)。 通过 VlmConvertOptions.from_preset("granite_docling") 指定预设,行为与默认一致但更显式、可配置,再包进 VlmPipelineOptions 传入:
vlm_options = VlmConvertOptions.from_preset("granite_docling")
converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(
pipeline_cls=VlmPipeline,
pipeline_options=VlmPipelineOptions(vlm_options=vlm_options),
),
}
)
写法三:预设 + 运行时覆盖(高级)。 用 engine_options 参数强制指定推理后端,示例按平台区分:macOS/ARM(Apple Silicon)用 MlxVlmEngineOptions(),其余平台(含 Linux CI)回退到 TransformersVlmEngineOptions():
engine_options = (
MlxVlmEngineOptions()
if platform.system() == "Darwin" and platform.machine() == "arm64"
else TransformersVlmEngineOptions()
)
vlm_options = VlmConvertOptions.from_preset("granite_docling", engine_options=engine_options)
print("Using model: "
f"{vlm_options.model_spec.get_repo_id(vlm_options.engine_options.engine_type)}")
最后一行揭示了预设的工作方式:预设会根据所选运行时(engine_type)自动挑选匹配的模型变体(如 MLX 版与 Transformers 版的权重仓库),因此运行时覆盖后模型仓库 ID 也会随之变化。前置条件:安装带 VLM extras 的 Docling 与相应后端(Transformers 或 MLX),且环境能下载模型权重。向后兼容的旧式写法见 docs/examples/legacy/minimal_vlm_pipeline_legacy.py。
ASR 管线:音频转 Markdown(自动模型选择)
docs/examples/minimal_asr_pipeline.py 演示语音转写。核心是把 AsrPipeline 绑定到 InputFormat.AUDIO,并选用模型规格 WHISPER_TURBO:
pipeline_options = AsrPipelineOptions()
pipeline_options.asr_options = asr_model_specs.WHISPER_TURBO
converter = DocumentConverter(
format_options={
InputFormat.AUDIO: AudioFormatOption(
pipeline_cls=AsrPipeline,
pipeline_options=pipeline_options,
)
}
)
asr_model_specs.WHISPER_TURBO 是「自动选择」入口:若 Apple Silicon 上安装了 mlx-whisper,则用 MLX Whisper Turbo;否则回退原生 Whisper Turbo。要实验其他规模模型,可换成 docling.datamodel.asr_model_specs 中的其他规格。转换后用 assert result.status == ConversionStatus.SUCCESS 校验状态,输出的 Markdown 带有时间戳分段,例如:
[time: 0.0-4.0] Shakespeare on Scenery by Oscar Wilde
[time: 5.28-9.96] This is a LibriVox recording. All LibriVox recordings are in the public domain.
前置条件:安装 Docling 的 ASR extras;部分音频格式需要 ffmpeg 编解码器在 PATH 上。输入默认为仓库测试音频 tests/data/audio/sources/sample_10s.mp3(同目录还提供 aac/flac/m4a/ogg/wav/avi/mp4 等多种格式样本)。
RAG 集成:LangChain / LlamaIndex / Haystack 与向量库选择
索引页列出的 RAG 示例覆盖了三个主流框架、三种向量库和一个进阶能力:
LangChain(rag_langchain.ipynb):基于官方的 LangChain Docling 集成(参见 docs/integrations/langchain.md),配合 Milvus 向量库与 sentence-transformers 嵌入。DoclingLoader 支持两种导出模式,由参数 EXPORT_TYPE 切换:
ExportType.MARKDOWN:把每个输入文档作为一张 LangChain 文档整体捕获;ExportType.DOC_CHUNKS(默认):先把文档分块,再把每个 chunk 作为独立的 LangChain 文档向下游传递。
Notebook 按「Setup → 文档加载 → 确定分块 → 检查样例分块 → 入库 → RAG」组织,嵌入在本地、向量库在本地、生成式 LLM 走 Hugging Face Inference API(可用环境变量 HF_TOKEN 提高配额),并建议用 GPU 运行时加速转换。
LlamaIndex(rag_llamaindex.ipynb):使用官方扩展的 DoclingReader 与 DoclingNodeParser(参见 docs/integrations/llamaindex.md),演示两种路线——「Markdown 导出 + 标准 MarkdownNodeParser」的简单管线,以及「JSON 导出 + DoclingNodeParser」的原生格式管线;后者使检索结果携带文档级定位信息(页码、边界框)。还演示了与 SimpleDirectoryReader 组合读取整个文档目录的用法。
Haystack(rag_haystack.ipynb):DoclingConverter 同样支持 ExportType.MARKDOWN 与 ExportType.DOC_CHUNKS(默认)两种模式(参见 docs/integrations/haystack.md),notebook 分别构建「入库管线」与「RAG 管线」;使用 DOC_CHUNKS 时,打印出的检索结果源同样包含页码/边界框等定位信息。
向量库与视觉定位:rag_milvus.ipynb、rag_weaviate.ipynb、retrieval_qdrant.ipynb 展示不同向量库的接入差异;visual_grounding.ipynb 进一步演示检索命中后如何借助文档定位信息(bounding box)在页面上做视觉定位,实现「答案可溯源到具体页区」。
结构化抽取、序列化与分块
结构化抽取(beta):extraction.ipynb 演示从文档中抽取结构化键值数据(索引页标注为 beta 特性)。抽取能力的实现入口在 docling/document_extractor.py,相关管线位于 docling/pipeline/extraction_vlm_pipeline.py。
序列化:serialization.ipynb 展示 序列化概念 的用法,覆盖四层能力:
- 对转换产物应用内置
BaseDocSerializer(如HTMLDocSerializer、MarkdownDocSerializer); - 配置序列化器:更换组件级序列化策略(如表格改用 triplet 格式以提升向量表示质量)、覆盖用户参数(如图片占位文本);
- 自定义序列化器:先开启图片描述富化(见 enrichments 文档),再定义把图片描述写进输出的自定义图片序列化器,并组装进新的文档序列化器;
- 索引化图片占位符:从
self_ref派生每张图片的序号,在占位串中使用{index}令牌,使序列化输出中的每张图片都有唯一标识,便于与DoclingDocument交叉引用。
分块:hybrid_chunking.ipynb 演示在文档层级分块之上叠加「tokenization 感知」的 HybridChunker(原理见 chunking 概念文档):
- 嵌入文本应取
contextualize()返回的上下文增强版本; - 显式参数化 tokenizer,保证分块器与嵌入模型使用同一 tokenizer(支持 HuggingFace transformers tokenizer;OpenAI tiktoken 需安装
docling-core[chunking-openai]); - 输出可观察到三类行为:能塞进 64 token 上限(元数据增强序列化形式)就塞满、必要时提前停(例如 63 token 以避免截断逗号)、可合并过小的同级 chunk;
- 宽表分块支持「表头重复」:每个 chunk 都带上表头行,保证独立消费时列语义不丢失;更高级的
omit_header_on_overflow等参数见 line_based_chunking.ipynb。
高级定制:advanced_chunking_and_serialization.ipynb 聚焦「分块期间使用的序列化策略」定制:切换表格序列化(默认 triplet → Markdown)、修改图片占位符参数、实现利用图片标注的自定义图片序列化策略,以及处理「图片内 OCR 文本」——默认 traverse_pictures=False 会跳过嵌套在 PictureItem 下的 OCR TextItem(因为图片 OCR 文本通常是低质量噪声,序列化扁平化后难以与正文区分);若文档中图片内文本确有价值,可通过自定义序列化器设置 traverse_pictures=True 显式开启。
图片富化:本地 VLM、远程 API 与后转换富化
本地模型图片标注:pictures_description.ipynb 演示在本地运行 Granite Vision(granite-vision-3.1-2b-preview)与 SmolVLM(SmolVLM-256M-Instruct)两类模型生成图片描述,并说明可通过 PictureDescriptionVlmOptions 指定 Hugging Face Hub 上的任意视觉模型。
远程 API 标注:pictures_description_api.py 演示通过 OpenAI 兼容的 chat-completions 端点远程描述图片,配置载体是 PictureDescriptionApiOptions(url、headers、params、prompt 等),需要在 PdfPipelineOptions 上开启 do_picture_description = True 与 enable_remote_services = True。
API 用量捕获:picture_description_api_usage.py 是一个更精细的生产级示例,把 API 返回的原始 usage 载荷保留到每张图片描述的自定义元数据里,供计费/审计使用:
pipeline_options = PdfPipelineOptions()
pipeline_options.do_picture_description = True
pipeline_options.picture_description_options = _build_picture_description_options()
pipeline_options.enable_remote_services = True
PictureDescriptionApiOptions 的关键参数(均可通过环境变量覆盖):
url:chat-completions 端点,支持直接指定PICTURE_DESCRIPTION_API_URL,或按 Azure OpenAI 约定由AZURE_API_BASE+AZURE_OPENAI_DEPLOYMENT+AZURE_OPENAI_API_VERSION拼接;headers:Azure 场景用api-key头(AZURE_API_KEY),普通 OpenAI 兼容端点用Authorization: Bearer(PICTURE_DESCRIPTION_API_KEY);params:附加进请求体的 JSON 对象(PICTURE_DESCRIPTION_PARAMS_JSON),非 Azure 场景会自动注入model(PICTURE_DESCRIPTION_MODEL);picture_area_threshold:参与描述的最小图片面积占比,默认0.0保证小图不被静默跳过;usage_response_key:指定从响应 JSON 中保留哪个键/点路径作为用量元数据,默认usage。
捕获结果存放在 picture.meta.description.get_custom_part()["docling__usage"],客户端可用自己的 Pydantic 模型校验该原始载荷(不同供应商的 token 计费结构不同)。若未配置任何端点环境变量,脚本会提前安全退出,因此可以在 CI 中直接运行。
后转换富化:enrich_doclingdocument.py 演示「不再转换、只富化已有文档」的模式:
DoclingDocument.load_from_json(...)加载之前转换产出的 JSON;- 用
PyPdfiumDocumentBackend打开对应 PDF(要求 JSON 与 PDF 是同一文档/版本,保证 provenance 边界框可对齐裁剪); - 对每个元素,先经
model.is_processable()过滤,再按model.expansion_factor向外扩边界框,用page_backend.get_page_image(scale=model.images_scale, cropbox=expanded_bbox)裁剪上下文区域,组装成ItemAndImageEnrichmentElement; - 用
chunkify(..., BATCH_SIZE)按批送入富化模型(批越大吞吐越高、内存占用越大),模型就地写回doc。
示例使用的模型是 DocumentPictureClassifier(from_preset("document_figure_classifier_v2")),把分类元数据写入 pic.meta。这一模式说明富化(enrichment)可以与转换解耦:先低成本批量转换并存档 JSON,再按需对历史文档补跑新的富化模型。
更多示例与进一步阅读
除本文详解的示例外,docs/examples/ 目录还有大量可直接运行的配方,可按需检索:
- 更多转换:custom_convert.py、run_with_formats.py、gpu_standard_pipeline.py、full_page_ocr.py、translate.py;
- 图表理解:chart_extraction.py、export_figures.py、granite_vision_table_structure.py;
- 图片/代码/公式富化:develop_picture_enrichment.py、develop_formula_understanding.py、code_formula_granite_docling.py、pii_obfuscate.py;
- 媒体处理:video_pipeline.ipynb、asr_pipeline_performance_comparison.py、mlx_whisper_example.py;
- VLM 工程化:compare_vlm_models.py、post_process_ocr_with_vlm.py、granitedocling_repetition_stopping.py。
概念层面,docs/concepts/ 下的 docling_document.md(统一文档模型)、chunking.md(分块策略)、serialization.md(序列化机制)与 OCR.md 是理解上述示例的配套阅读;CLI 用法可参考 docs/reference/cli.md,管线参数详见 docs/reference/pipeline_options.md。所有示例均可从仓库根目录以 python docs/examples/<脚本名> 直接运行(notebook 除外),输出默认写入 scratch/ 目录,便于清理与复跑。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00

