skill.md — Docling Python Library Reference#
For AI coding agents: This is a self-contained reference for writing code that uses the Docling Python library. Use it to quickly find API patterns, class names, and configuration options.
1. Overview#
Docling is a Python SDK and CLI for converting documents into a structured, AI-ready format. It ingests PDF, DOCX, PPTX, XLSX, HTML, Markdown, images, LaTeX, EPUB, audio, and more , and produces a unified DoclingDocument — a schema-versioned JSON representation carrying all texts, tables, pictures, page layout, and provenance .
Key value propositions for gen AI use cases:
- Structured extraction with provenance — every element (paragraph, table cell, figure) carries
page_noand bounding-box coordinates traceable back to the source file - Table, formula, and code extraction — TableFormer models extract structured table grids; VLM models extract LaTeX formulas and code-language labels
- RAG-ready chunking —
HybridChunkerproducesDocChunkobjects with tokenizer-aware splits, contextual headings, and three-layer provenance for citation - Multiple export targets — Markdown, HTML, JSON, plain text, DocTags (VLM training format), DocLang (LLM-compatible XML)
- Integrations — official connectors for LangChain (
langchain-docling) and LlamaIndex (llama-index-readers-docling)
Processing pipeline overview:
Input document
└─► DocumentConverter
├─► Backend (parses raw format)
├─► Layout model (detects regions)
├─► Table structure model (extracts cell grids)
├─► OCR (handles scanned pages)
└─► Enrichment models (code, formula, picture classification)
└─► DoclingDocument
├── export_to_markdown() / export_to_html() / etc.
└── HybridChunker ──► DocChunk[] ──► Vector store
2. Installation#
# Base install — supports all document formats (PDF, DOCX, PPTX, XLSX, HTML, images, etc.)
pip install docling
# VLM support — required for Granite Vision table structure, VLM pipeline presets,
# and picture description via local VLM models
pip install docling[vlm]
# ASR support — audio/video transcription pipeline
pip install docling[asr]
# HTML rendering — headless browser rendering for JavaScript-heavy pages
pip install docling[htmlrender]
# Chunking support in docling-core (HybridChunker + HuggingFace tokenizer)
pip install docling-core[chunking]
# Chunking with OpenAI/tiktoken tokenizer
pip install docling-core[chunking-openai]
LangChain integration :
pip install langchain-docling
LlamaIndex integration :
pip install llama-index-readers-docling llama-index-node-parser-docling
Note: VLM models (Granite Vision, CodeFormulaV2, etc.) are downloaded automatically from HuggingFace on first use. A CUDA GPU is recommended for practical performance, but CPU inference is supported .
3. Core Concepts#
DocumentConverter#
DocumentConverter is the main entry point for all document conversion . It accepts a format_options dict mapping InputFormat enum values to FormatOption instances.
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
# Default converter — all formats with default options
converter = DocumentConverter()
# Custom converter — PDF with specific options
converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(
pipeline_options=PdfPipelineOptions(do_ocr=True, do_table_structure=True)
)
}
)
# Convert a single document
result = converter.convert("path/to/document.pdf")
doc = result.document # DoclingDocument
Pipelines are cached by (pipeline_class, md5(pipeline_options)) — multiple formats sharing the same class and options reuse a single initialized pipeline .
DoclingDocument#
DoclingDocument is the canonical output — a Pydantic model backed by a schema-versioned JSON representation :
| Field | Type | Description |
|---|---|---|
schema_name | str | Always "DoclingDocument" |
version | str | Schema version (e.g. "1.10.0") |
name | str | Working name |
origin | DocumentOrigin | Source file: filename, mimetype, binary_hash, uri |
body | GroupItem | Root tree node for main content |
furniture | GroupItem | Root node for headers/footers |
groups | list[GroupItem] | Structural containers |
texts | list[BaseTextItem] | All text nodes (titles, headings, paragraphs, code, formulas) |
pictures | list[PictureItem] | Image/figure nodes |
tables | list[TableItem] | Table nodes (with structured cell grids) |
pages | dict[str, PageItem] | Page-number → layout/image mapping |
InputFormat and OutputFormat Enums#
from docling.datamodel.base_models import InputFormat, OutputFormat
# InputFormat — 24 supported input types (cite:code_file:4b418ed6)
InputFormat.PDF # PDF documents
InputFormat.DOCX # Microsoft Word
InputFormat.PPTX # Microsoft PowerPoint
InputFormat.XLSX # Microsoft Excel
InputFormat.HTML # HTML pages
InputFormat.MD # Markdown (also: .txt, .text, .qmd, .rmd)
InputFormat.IMAGE # Images (PNG, JPEG, TIFF, BMP, WEBP)
InputFormat.CSV # CSV files
InputFormat.LATEX # LaTeX documents
InputFormat.EPUB # EPUB ebooks
InputFormat.AUDIO # Audio files (with ASR pipeline)
InputFormat.XML_DOCLANG # DocLang XML format
InputFormat.JSON_DOCLING # Docling JSON format (round-trip)
# ... and: ODT, ODS, ODP, XML_USPTO, XML_JATS, XML_XBRL, METS_GBS, VTT, EMAIL, BOXNOTE, ASCIIDOC
# OutputFormat
OutputFormat.MARKDOWN # Markdown
OutputFormat.JSON # JSON
OutputFormat.YAML # YAML
OutputFormat.HTML # HTML
OutputFormat.TEXT # Plain text
OutputFormat.DOCTAGS # DocTags (VLM training format)
OutputFormat.DOCLANG # DocLang XML (LLM-compatible)
OutputFormat.CHUNKS # Chunked output
FormatOption Hierarchy#
Each format has a named FormatOption subclass pre-wired with the correct pipeline and backend :
| Class | Formats |
|---|---|
PdfFormatOption | |
ImageFormatOption | Images |
WordFormatOption | DOCX |
PowerpointFormatOption | PPTX |
ExcelFormatOption | XLSX |
HTMLFormatOption | HTML |
MarkdownFormatOption | Markdown |
AudioFormatOption | Audio |
LatexFormatOption | LaTeX |
EpubFormatOption | EPUB |
Each FormatOption bundles: pipeline_cls, pipeline_options (controls ML models/OCR/enrichment), and backend_options (controls backend-specific parsing).
PipelineOptions Hierarchy#
PipelineOptions ← timeout, accelerator, artifacts_path
└── ConvertPipelineOptions ← picture classification/description, chart extraction
└── PaginatedPipelineOptions ← images_scale, generate_page_images
├── PdfPipelineOptions ← OCR, table structure, layout, formula/code enrichment
└── VlmPipelineOptions ← VLM-based holistic page understanding
AsrPipelineOptions ← speech recognition (audio)
4. Basic Usage Patterns#
Simple Conversion#
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
# From a local file path
result = converter.convert("path/to/document.pdf")
# From a URL
result = converter.convert("https://arxiv.org/pdf/2408.09869")
doc = result.document # DoclingDocument
print(result.status) # ConversionStatus.SUCCESS / FAILURE / PARTIAL_SUCCESS
Batch Conversion#
from pathlib import Path
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
sources = [
"doc1.pdf",
"https://example.com/report.docx",
Path("slides.pptx"),
]
# convert_all returns an iterator of ConversionResult
for result in converter.convert_all(sources):
if result.status.success:
doc = result.document
print(f"{result.input.file}: {len(doc.texts)} text items")
Export to Markdown#
md = doc.export_to_markdown()
# For scanned/image-based PDFs processed with full-page OCR,
# set traverse_pictures=True to include OCR text children (cite:page:53237f2f)
md = doc.export_to_markdown(traverse_pictures=True)
# Control image handling
from docling_core.types.doc import ImageRefMode
md = doc.export_to_markdown(image_mode=ImageRefMode.EMBEDDED) # base64 inline
md = doc.export_to_markdown(image_mode=ImageRefMode.REFERENCED) # file path
# Save directly to file
doc.save_as_markdown("output.md")
Export to JSON#
import json
# As a Python dict (cite:code_file:9f949ac5)
data = doc.export_to_dict()
# As a JSON string
json_str = doc.model_dump_json(indent=2)
# Save to file
doc.save_as_json("output.json")
# Save to file with embedded images
doc.save_as_json("output.json", image_mode=ImageRefMode.EMBEDDED)
Export to HTML#
html = doc.export_to_html()
# With MathML formulas (default: True)
html = doc.export_to_html(formula_to_mathml=True)
# Split by page
html = doc.export_to_html(split_page_view=True)
# Save to file
doc.save_as_html("output.html")
Export to Plain Text#
text = doc.export_to_text()
# Include scanned OCR text
text = doc.export_to_text(traverse_pictures=True)
# Filter to specific page
text = doc.export_to_text(page_no=2)
Export to DocTags (VLM training format)#
# DocTags is the XML-like token format used by vision models (cite:page:767e9838)
doctags = doc.export_to_doctags()
# With bounding-box location tokens
doctags = doc.export_to_doctags(add_location=True, add_page_index=True)
# Save to file
doc.save_as_doctags("output.doctags")
Export to DocLang (LLM-compatible XML)#
# DocLang is an XML semantic markup format for LLM/VLM compatibility (cite:page:01e08bae)
doclang_xml = doc.export_to_doclang()
# Save as .dclg.xml file
doc.save_as_doclang("output.dclg.xml")
# Save as .dclx archive (with embedded images)
doc.save_as_doclang_archive("output.dclx")
CLI Usage#
The docling CLI exposes a convert command :
# Basic conversion — outputs Markdown by default
docling convert document.pdf
# Specify output format(s)
docling convert document.pdf --to md --to json --output ./output/
# Multiple input files
docling convert doc1.pdf doc2.docx --to md
# From URL
docling convert https://arxiv.org/pdf/2408.09869 --to md
# Disable OCR, enable table extraction
docling convert document.pdf --no-ocr --tables --to md
# Force OCR on all pages
docling convert scanned.pdf --force-ocr --to md
# Select PDF backend
docling convert document.pdf --pdf-backend threaded_docling_parse --to md
# Enable enrichments
docling convert document.pdf --enrich-code --enrich-formula --to md
# With chunked output
docling convert document.pdf --to chunks --chunks-type hybrid \
--chunks-tokenizer sentence-transformers/all-MiniLM-L6-v2 \
--chunks-max-tokens 512
# Only process specific input formats
docling convert ./docs/ --from pdf --from docx --to md
# Progress tracking
docling convert document.pdf --progress --to md
# Set verbosity
docling convert document.pdf -vv --to md # debug logging
Key CLI flags :
| Flag | Description |
|---|---|
--from FORMAT | Input format filter (pdf, docx, pptx, etc.) |
--to FORMAT | Output format (md, json, html, text, doctags, chunks) |
--output DIR | Output directory |
--pipeline PIPELINE | PDF/image pipeline to use |
--vlm-model MODEL | VLM preset for PDF/image |
--ocr / --no-ocr | Enable/disable OCR |
--force-ocr | OCR entire page, replacing existing text |
--tables / --no-tables | Enable/disable table structure extraction |
--ocr-engine ENGINE | OCR engine selection |
--ocr-lang LANG | OCR language(s), comma-separated |
--pdf-backend BACKEND | PDF backend (docling_parse, pypdfium2, threaded_docling_parse) |
--enrich-code | Enable code enrichment model |
--enrich-formula | Enable formula enrichment model |
--enrich-picture-classes | Enable picture classification |
--enrich-picture-description | Enable picture description |
--enrich-chart-extraction | Enable chart data extraction |
--image-export-mode MODE | Image export mode for HTML/MD/JSON outputs |
--num-threads N | Number of threads |
--device DEVICE | Accelerator device (cpu, cuda, mps) |
--document-timeout SECS | Per-document processing timeout |
--progress | Enable progress tracking |
5. Pipeline Configuration#
PdfPipelineOptions Reference#
from docling.datamodel.pipeline_options import PdfPipelineOptions
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
# All options with their defaults
pipeline_options = PdfPipelineOptions(
do_ocr=True, # Apply OCR to bitmap regions (default: True)
force_full_page_ocr=False, # OCR entire page (overrides text layer)
do_table_structure=True, # Extract table cell grids (default: True)
do_code_enrichment=False, # VLM code language detection (requires [vlm])
do_formula_enrichment=False, # VLM LaTeX formula extraction (requires [vlm])
do_picture_classification=False,# Classify images (chart, logo, diagram, etc.)
do_picture_description=False, # VLM-based image captioning
images_scale=1.0, # Image resolution multiplier (CLI default 2.0)
generate_page_images=False, # Extract page images
generate_picture_images=False, # Extract picture images
pdf_backend="docling_parse", # Backend: pypdfium2 | docling_parse | threaded_docling_parse
)
converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
}
)
Runtime override: Only
do_*flags can be changed at conversion time, and only fromTrue→False. All other options must be identical to those set at pipeline initialization .
# Disable table extraction for a specific conversion without reinitializing
result = converter.convert(
"document.pdf",
format_options={
InputFormat.PDF: PdfFormatOption(
pipeline_options=PdfPipelineOptions(do_table_structure=False)
)
}
)
OCR Configuration#
from docling.datamodel.pipeline_options import (
PdfPipelineOptions,
EasyOcrOptions,
TesseractCliOcrOptions,
TesseractOcrOptions,
RapidOcrOptions,
OcrMacOptions,
OcrAutoOptions, # default: probes runtime for best engine
)
# EasyOCR — GPU-accelerated, 80+ languages (cite:page:41b5077b)
opts = PdfPipelineOptions()
opts.do_ocr = True
opts.ocr_options = EasyOcrOptions(
lang=["en", "de", "fr"],
use_gpu=True, # None = auto-detect
confidence_threshold=0.5,
)
# Tesseract CLI
opts.ocr_options = TesseractCliOcrOptions(
lang=["eng", "deu"], # ISO 639-2 codes
)
# RapidOCR (lightweight, ONNX-based)
opts.ocr_options = RapidOcrOptions(
backend="onnxruntime", # onnxruntime | openvino | paddle | torch
)
# macOS Vision framework (Apple Silicon)
opts.ocr_options = OcrMacOptions(
lang=["en-US", "de-DE"],
recognition="accurate", # accurate | fast
)
# Force full-page OCR (ignores existing text layer)
opts.ocr_options = EasyOcrOptions(force_full_page_ocr=True)
Table Structure Configuration#
from docling.datamodel.pipeline_options import (
PdfPipelineOptions,
TableStructureOptions, # TableFormer V1
TableStructureV2Options, # TableFormer V2
GraniteVisionTableStructureOptions, # Granite Vision VLM (requires [vlm])
TableFormerMode,
)
opts = PdfPipelineOptions()
opts.do_table_structure = True
# TableFormer V1 (default) — object-detection-based (cite:page:691dc513)
opts.table_structure_options = TableStructureOptions(
do_cell_matching=True, # Match predictions to PDF text cells
mode=TableFormerMode.ACCURATE, # ACCURATE | FAST
)
# TableFormer V2 — improved transformer-based model
opts.table_structure_options = TableStructureV2Options(
do_cell_matching=True,
)
# Granite Vision — VLM-based, OTSL output (requires pip install docling[vlm])
opts.table_structure_options = GraniteVisionTableStructureOptions()
VLM Pipeline#
For holistic VLM-based document understanding (e.g., SmolDocling-style), use VlmPipelineOptions via the --pipeline vlm CLI flag or the vlm_pipeline_preset option :
from docling.datamodel.pipeline_options import (
PdfPipelineOptions,
CodeFormulaVlmOptions,
)
from docling.datamodel.vlm_engine_options import (
TransformersVlmEngineOptions,
MlxVlmEngineOptions, # Apple Silicon only
VllmVlmEngineOptions, # vLLM server
ApiVlmEngineOptions, # OpenAI-compatible API
)
# Code/formula enrichment with default preset (codeformulav2)
opts = PdfPipelineOptions(
do_code_enrichment=True,
do_formula_enrichment=True,
)
# Code/formula with Granite-Docling-258M preset
code_formula_opts = CodeFormulaVlmOptions.from_preset("granite_docling")
opts = PdfPipelineOptions(
do_code_enrichment=True,
do_formula_enrichment=True,
code_formula_options=code_formula_opts,
)
# Code/formula with explicit MLX engine (Apple Silicon)
code_formula_opts = CodeFormulaVlmOptions.from_preset(
"codeformulav2",
engine_options=MlxVlmEngineOptions(),
)
# Using an OpenAI-compatible API endpoint
code_formula_opts = CodeFormulaVlmOptions.from_preset(
"codeformulav2",
engine_options=ApiVlmEngineOptions(
url="http://localhost:11434", # e.g., Ollama
),
)
Format-Specific Backend Options#
from docling.document_converter import DocumentConverter, ExcelFormatOption, HTMLFormatOption
from docling.datamodel.backend_options import MsExcelBackendOptions, HTMLBackendOptions
from docling.datamodel.base_models import InputFormat
# XLSX — filter to specific sheets, parse charts (cite:page:3b5aff37)
converter = DocumentConverter(
format_options={
InputFormat.XLSX: ExcelFormatOption(
backend_options=MsExcelBackendOptions(
sheet_names=["Summary", "Q4"], # Only these sheets
parse_charts=True,
treat_singleton_as_text=True,
)
)
}
)
# HTML — headless browser rendering for JavaScript-heavy pages
# (requires pip install docling[htmlrender])
converter = DocumentConverter(
format_options={
InputFormat.HTML: HTMLFormatOption(
backend_options=HTMLBackendOptions(
render_page=True, # Use headless browser
fetch_images=True, # Fetch referenced images
)
)
}
)
Progress Callbacks#
from docling.datamodel.progress_event import ProgressEvent
from docling.document_converter import DocumentConverter
def on_progress(event: ProgressEvent):
print(f"{event.event_type}: {event.document_name}")
converter = DocumentConverter(progress_callback=on_progress)
result = converter.convert("document.pdf")
6. DoclingDocument API#
Building Documents Programmatically#
DoclingDocument supports a set of add_* builder methods for constructing documents from scratch . All methods append to the appropriate flat list, assign a JSON Pointer self_ref, and wire up parent–child links automatically.
from docling_core.types import DoclingDocument
from docling_core.types.doc import DocItemLabel
from docling_core.types.doc.document import (
TableData, TableCell, ImageRef, ProvenanceItem,
)
from docling_core.types.doc.base import BoundingBox, CoordOrigin, Size
# Initialize an empty document
doc = DoclingDocument(name="My Document")
# Add page metadata
doc.add_page(page_no=1, size=Size(width=595.0, height=842.0))
# --- Text content ---
# Document title (stored in doc.texts)
doc.add_title(text="Quarterly Report 2024")
# Section headers (level 1–100)
sec = doc.add_heading(text="Introduction", level=1)
# Paragraph text
doc.add_text(label=DocItemLabel.PARAGRAPH, text="This report covers Q4 results.", parent=sec)
# Code block
doc.add_code(text='print("hello")', code_language="python")
# Mathematical formula (LaTeX)
doc.add_formula(text=r"\int_0^\infty e^{-x} dx = 1")
# List
list_grp = doc.add_list_group(parent=sec)
doc.add_list_item(text="Item one", enumerated=False, parent=list_grp)
doc.add_list_item(text="Item two", enumerated=False, parent=list_grp)
# Ordered list
ordered_grp = doc.add_list_group(parent=sec)
doc.add_list_item(text="First step", enumerated=True, marker="1.", parent=ordered_grp)
doc.add_list_item(text="Second step", enumerated=True, marker="2.", parent=ordered_grp)
# --- Tables ---
table_data = TableData(num_rows=2, num_cols=2)
cells = [
TableCell(text="Name", row_span=1, col_span=1,
start_row_offset_idx=0, end_row_offset_idx=1,
start_col_offset_idx=0, end_col_offset_idx=1,
column_header=True),
TableCell(text="Value", row_span=1, col_span=1,
start_row_offset_idx=0, end_row_offset_idx=1,
start_col_offset_idx=1, end_col_offset_idx=2,
column_header=True),
TableCell(text="Revenue",row_span=1, col_span=1,
start_row_offset_idx=1, end_row_offset_idx=2,
start_col_offset_idx=0, end_col_offset_idx=1),
TableCell(text="$1M", row_span=1, col_span=1,
start_row_offset_idx=1, end_row_offset_idx=2,
start_col_offset_idx=1, end_col_offset_idx=2),
]
table_data.table_cells = cells
# Add provenance (page + bounding box)
prov = ProvenanceItem(
page_no=1,
bbox=BoundingBox(l=50.0, t=200.0, r=400.0, b=300.0, coord_origin=CoordOrigin.BOTTOMLEFT),
charspan=(0, 0),
)
table_item = doc.add_table(data=table_data, prov=prov)
# --- Export constructed document ---
print(doc.export_to_markdown())
print(doc.export_to_json())
Document-Level Utilities#
# Merge multiple documents (re-numbers pages, re-assigns refs)
merged = DoclingDocument.concatenate([doc1, doc2, doc3])
# Filter to specific pages
page_doc = doc.filter(page_nrs={1, 2})
# Delete items
doc.delete_items(node_items=[some_item])
Iterating Document Elements#
iterate_items() performs a depth-first traversal of the document tree and is the backbone for all export methods :
from docling_core.types.doc import ContentLayer
from docling_core.types.doc.document import (
TextItem, TableItem, PictureItem, GroupItem, SectionHeaderItem
)
# Basic iteration — yields (NodeItem, nesting_level) tuples
# Default: ContentLayer.BODY only, groups excluded
for item, level in doc.iterate_items():
if isinstance(item, TextItem):
print(" " * level + item.text)
elif isinstance(item, TableItem):
print(" " * level + f"[TABLE: {item.data.num_rows}×{item.data.num_cols}]")
elif isinstance(item, PictureItem):
print(" " * level + "[PICTURE]")
# Include structural group nodes
for item, level in doc.iterate_items(with_groups=True):
if isinstance(item, GroupItem):
print(" " * level + f"[GROUP: {item.name}]")
# Include page headers/footers (FURNITURE layer)
for item, level in doc.iterate_items(
included_content_layers={ContentLayer.BODY, ContentLayer.FURNITURE}
):
...
# Scanned PDFs: OCR text is stored as children of PictureItem
for item, level in doc.iterate_items(traverse_pictures=True):
...
# Restrict to a single page
for item, level in doc.iterate_items(page_no=3):
...
# Traverse a subtree
for item, level in doc.iterate_items(root=some_section_node):
...
Accessing Provenance#
Every document item carries a prov list with page and bounding-box information :
from docling_core.types.doc.document import ProvenanceItem
for item, _ in doc.iterate_items():
for prov in item.prov:
print(f"Page {prov.page_no}: bbox=({prov.bbox.l}, {prov.bbox.t}, {prov.bbox.r}, {prov.bbox.b})")
print(f" charspan: {prov.charspan}") # (start, end) character offsets
# Access tables by index
for table in doc.tables:
print(f"Table on page {table.prov[0].page_no if table.prov else 'unknown'}")
# Export individual table
df = table.export_to_dataframe(doc=doc)
md = table.export_to_markdown(doc=doc)
html = table.export_to_html(doc=doc)
# Access pictures
for pic in doc.pictures:
if pic.prov:
print(f"Picture on page {pic.prov[0].page_no}")
if pic.meta and pic.meta.classification:
print(f" Classification: {pic.meta.classification}")
if pic.meta and pic.meta.description:
print(f" Description: {pic.meta.description}")
Loading from DocTags Format#
DocTags is the XML-like token format emitted by VLMs (e.g., SmolDocling) :
from docling_core.types.doc.document import DocTagsDocument, DoclingDocument
from PIL import Image
# From per-page (tokens_str, PIL.Image) pairs
doctags_doc = DocTagsDocument.from_doctags_and_image_pairs([
("<title>My Doc</title><text>Hello world</text>", pil_image),
])
doc = DoclingDocument.load_from_doctags(doctags_doc, document_name="my_doc")
# Round-trip back to DocTags
doctags_str = doc.export_to_doctags()
7. Chunking for RAG#
Basic Setup#
# Requires: pip install docling-core[chunking]
from docling.chunking import HybridChunker
from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer
from transformers import AutoTokenizer
EMBED_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
# The chunker tokenizer MUST match the embedding model's tokenizer (cite:page:ff0a9205)
tokenizer = HuggingFaceTokenizer(
tokenizer=AutoTokenizer.from_pretrained(EMBED_MODEL),
max_tokens=512, # optional; defaults to model max
)
chunker = HybridChunker(tokenizer=tokenizer)
Warning: HuggingFace Transformers may warn
"Token indices sequence length is longer than the specified maximum sequence length"during HybridChunker initialization — this is a false alarm and can be safely ignored .
HybridChunker Constructor Parameters#
| Parameter | Default | Description |
|---|---|---|
tokenizer | HuggingFaceTokenizer("all-MiniLM-L6-v2") | Controls token-count split boundaries |
max_tokens | derived from tokenizer | Hard token cap per chunk |
merge_peers | True | Merge undersized sibling chunks |
repeat_table_header | True | Repeat header rows for split table chunks |
omit_header_on_overflow | False | Drop header when row + header exceeds budget |
serializer_provider | ChunkingSerializerProvider() | Controls table serialization format |
Chunking a Document#
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
result = converter.convert("report.pdf")
chunks = list(chunker.chunk(result.document))
for chunk in chunks:
print(chunk.text) # The chunk's plain text
print(chunk.meta.headings) # Section headings in scope
print(chunk.meta.origin) # DocumentOrigin: filename, mimetype, binary_hash
Contextualized Text for Embedding#
The text you embed should be the context-enriched form from chunker.contextualize(), which prepends in-scope section headings to chunk.text :
for chunk in chunker.chunk(doc):
# Use this string for embedding — includes heading context
embed_text = chunker.contextualize(chunk)
# embed_text = "## Section Heading\n\nChunk body text..."
OpenAI Tokenizer#
# Requires: pip install docling-core[chunking-openai]
import tiktoken
from docling_core.transforms.chunker.tokenizer.openai import OpenAITokenizer
tokenizer = OpenAITokenizer(
tokenizer=tiktoken.encoding_for_model("gpt-4o"),
max_tokens=128 * 1024,
)
chunker = HybridChunker(tokenizer=tokenizer)
DocChunk Metadata and Provenance#
Every DocChunk carries a DocMeta with three-layer traceability :
DocChunk
├── text: str # chunk text content
└── meta: DocMeta
├── doc_items: list[DocItem] # source nodes this chunk covers
│ └── .prov: list[ProvenanceItem]
│ ├── page_no: int # 1-indexed page
│ ├── bbox: BoundingBox # l/t/r/b coordinates
│ └── charspan: (int, int) # character offsets
├── headings: list[str] # section headings in scope
└── origin: DocumentOrigin # filename, mimetype, binary_hash
for chunk in chunks:
# Inspect provenance
for item in chunk.meta.doc_items:
for prov in item.prov:
print(f" Page {prov.page_no}, bbox: {prov.bbox}")
# Source file
if chunk.meta.origin:
print(f" File: {chunk.meta.origin.filename}")
Table Serialization Strategies#
The default TripletTableSerializer emits flat "**Column**, row = value" strings that lose cell-to-header bindings. For table-heavy documents, switch to MarkdownTableSerializer :
from docling_core.transforms.chunker.hierarchical_chunker import (
ChunkingDocSerializer,
ChunkingSerializerProvider,
)
from docling_core.transforms.serializer.markdown import MarkdownParams, MarkdownTableSerializer
class MDTableSerializerProvider(ChunkingSerializerProvider):
def get_serializer(self, doc):
return ChunkingDocSerializer(
doc=doc,
table_serializer=MarkdownTableSerializer(),
params=MarkdownParams(compact_tables=True),
)
chunker = HybridChunker(
tokenizer=tokenizer,
repeat_table_header=True, # Each chunk re-includes column headers
serializer_provider=MDTableSerializerProvider(),
)
Why this matters: For RAG pipelines where 50%+ of chunks are tables, the serialization format is the dominant factor in embedding quality. The triplet format loses the column-to-value relationship; Markdown format preserves it .
End-to-End RAG Example#
from docling.document_converter import DocumentConverter
from docling.chunking import HybridChunker
from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer
from transformers import AutoTokenizer
EMBED_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
# Step 1: Convert document
converter = DocumentConverter()
result = converter.convert("https://arxiv.org/pdf/2408.09869")
doc = result.document
# Step 2: Configure chunker with matching tokenizer
tokenizer = HuggingFaceTokenizer(
tokenizer=AutoTokenizer.from_pretrained(EMBED_MODEL)
)
chunker = HybridChunker(tokenizer=tokenizer)
# Step 3: Chunk the document
chunks = list(chunker.chunk(doc))
# Step 4: Prepare embedding-ready texts with context
texts_to_embed = [chunker.contextualize(chunk) for chunk in chunks]
# Step 5: Build metadata for vector store
metadatas = []
for chunk in chunks:
meta = {
"headings": chunk.meta.headings,
"filename": chunk.meta.origin.filename if chunk.meta.origin else None,
"page_no": chunk.meta.doc_items[0].prov[0].page_no
if chunk.meta.doc_items and chunk.meta.doc_items[0].prov else None,
}
metadatas.append(meta)
# texts_to_embed and metadatas are now ready for any vector store
# e.g., for FAISS, Chroma, Milvus, Pinecone, etc.
8. Enrichments#
All enrichment models are disabled by default because they require additional model inference. Enable them individually in PdfPipelineOptions .
Note on
do_ocranddo_table_structure: These two are enabled by default (True). All other enrichments (code, formula, picture classification/description, chart extraction) are disabled by default.
OCR#
from docling.datamodel.pipeline_options import PdfPipelineOptions, EasyOcrOptions
opts = PdfPipelineOptions(
do_ocr=True, # Enable OCR for bitmap regions (default: True)
ocr_options=EasyOcrOptions(
force_full_page_ocr=False, # If True: OCR entire page, ignoring text layer
lang=["en"],
),
)
Table Structure Extraction#
from docling.datamodel.pipeline_options import (
PdfPipelineOptions, TableStructureV2Options
)
opts = PdfPipelineOptions(
do_table_structure=True, # Extract structured cell grids (default: True)
table_structure_options=TableStructureV2Options(
do_cell_matching=True, # Match to PDF text cells
),
)
Code Enrichment#
Sets CodeItem.code_language (e.g., "python", "javascript") using the CodeFormulaVlmModel :
from docling.datamodel.pipeline_options import PdfPipelineOptions
opts = PdfPipelineOptions(
do_code_enrichment=True, # VLM detects programming language
# Requires pip install docling[vlm]
)
Formula Enrichment#
Extracts LaTeX text from FORMULA-labeled TextItem elements :
opts = PdfPipelineOptions(
do_formula_enrichment=True, # VLM produces LaTeX string
# Requires pip install docling[vlm]
)
# After conversion, formulas are in TextItem elements:
for item, _ in doc.iterate_items():
from docling_core.types.doc.document import TextItem
from docling_core.types.doc import DocItemLabel
if isinstance(item, TextItem) and item.label == DocItemLabel.FORMULA:
print(item.text) # LaTeX string, e.g. "\int_0^\infty e^{-x} dx"
Picture Classification#
Classifies images by type: bar chart, pie chart, line chart, photograph, logo, diagram, chemistry structure, barcode, etc. :
from docling.datamodel.pipeline_options import PdfPipelineOptions, ConvertPipelineOptions
# do_picture_classification is on ConvertPipelineOptions (parent of PdfPipelineOptions)
opts = PdfPipelineOptions(
do_picture_classification=True,
)
# After conversion, classification is in PictureItem.meta:
for pic in doc.pictures:
if pic.meta and pic.meta.classification:
for pred in pic.meta.classification:
print(f" {pred.predicted_classes}") # list of (class, confidence)
Picture Description#
VLM-based image captioning stored in PictureItem.meta.description :
opts = PdfPipelineOptions(
do_picture_classification=True, # Classification enables filtering
do_picture_description=True,
# Optional: only describe specific picture types
picture_description_options=None, # use preset default
)
# After conversion:
for pic in doc.pictures:
if pic.meta and pic.meta.description:
print(pic.meta.description)
Chart Extraction#
Extracts chart data (bar, pie, line) into tabular format :
from docling.datamodel.pipeline_options import (
PdfPipelineOptions, ChartExtractionModelKind
)
opts = PdfPipelineOptions(
do_picture_classification=True,
chart_extraction_model=ChartExtractionModelKind.GRANITE_VISION,
# or: ChartExtractionModelKind.GRANITE_VISION_V4 (runs chart2csv, chart2code, chart2summary)
)
Combined Enrichment Example#
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import (
PdfPipelineOptions,
EasyOcrOptions,
TableStructureV2Options,
ChartExtractionModelKind,
)
opts = PdfPipelineOptions(
do_ocr=True,
ocr_options=EasyOcrOptions(lang=["en"]),
do_table_structure=True,
table_structure_options=TableStructureV2Options(),
do_code_enrichment=True,
do_formula_enrichment=True,
do_picture_classification=True,
chart_extraction_model=ChartExtractionModelKind.GRANITE_VISION,
generate_picture_images=True, # Store picture images in DoclingDocument
)
converter = DocumentConverter(
format_options={InputFormat.PDF: PdfFormatOption(pipeline_options=opts)}
)
result = converter.convert("document.pdf")
Debug Visualization#
from docling.datamodel.settings import settings, DebugSettings, scoped
# Global debug output
settings.debug = DebugSettings(
visualize_ocr=True,
visualize_layout=True,
visualize_tables=True,
debug_output_path="/tmp/docling_debug",
)
# Scoped debug (restores settings after block)
with scoped(debug=DebugSettings(visualize_layout=True)):
result = converter.convert("document.pdf")
9. Common Integration Patterns#
LangChain#
Install: pip install langchain-docling
from langchain_docling import DoclingLoader
from langchain_docling.loader import ExportType
from docling.chunking import HybridChunker
from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer
from transformers import AutoTokenizer
EMBED_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
# Option A: DOC_CHUNKS — one LangChain Document per Docling chunk (recommended)
# Preserves document-native provenance (cite:page:ff0a9205)
loader = DoclingLoader(
file_path=["https://arxiv.org/pdf/2408.09869"],
export_type=ExportType.DOC_CHUNKS,
chunker=HybridChunker(
tokenizer=HuggingFaceTokenizer(
tokenizer=AutoTokenizer.from_pretrained(EMBED_MODEL)
)
),
)
splits = loader.load()
# Each split has split.metadata["dl_meta"] with DocMeta provenance
# Option B: MARKDOWN — one LangChain Document per file, then split externally
loader = DoclingLoader(
file_path=["document.pdf"],
export_type=ExportType.MARKDOWN,
)
docs = loader.load()
# Then use MarkdownHeaderTextSplitter or similar
# Ingest into a vector store
from langchain_community.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name=EMBED_MODEL)
vector_store = FAISS.from_documents(splits, embeddings)
# Query
retriever = vector_store.as_retriever()
results = retriever.invoke("What are the key findings?")
LlamaIndex#
Install: pip install llama-index-readers-docling llama-index-node-parser-docling
The LlamaIndex integration provides two components :
- DoclingReader — converts documents and populates LlamaIndex
Documentobjects - DoclingNodeParser — parses Docling-format
Documentobjects intoNodeobjects for chunking/embedding
# Option A: Markdown export (simple, lossy)
from llama_index.readers.docling import DoclingReader
reader = DoclingReader()
documents = reader.load_data(
file_path=["report.pdf", "https://arxiv.org/pdf/2408.09869"]
)
# Each document.text contains Markdown representation
# Option B: JSON export + DoclingNodeParser (lossless, preserves rich metadata)
from llama_index.readers.docling import DoclingReader
from llama_index.node_parser.docling import DoclingNodeParser
reader = DoclingReader(export_type=DoclingReader.ExportType.JSON)
node_parser = DoclingNodeParser()
documents = reader.load_data(file_path=["report.pdf"])
nodes = node_parser.get_nodes_from_documents(documents)
# Each node carries Docling metadata: page_no, bbox, headings, etc.
# Use with LlamaIndex pipeline
from llama_index.core import VectorStoreIndex
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
embed_model = HuggingFaceEmbedding(model_name="sentence-transformers/all-MiniLM-L6-v2")
index = VectorStoreIndex(nodes, embed_model=embed_model)
query_engine = index.as_query_engine()
response = query_engine.query("Summarize the key findings.")
Direct Vector Store Integration (Without Framework)#
from docling.document_converter import DocumentConverter
from docling.chunking import HybridChunker
from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer
from transformers import AutoTokenizer
from sentence_transformers import SentenceTransformer
EMBED_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
# Convert + chunk
converter = DocumentConverter()
chunker = HybridChunker(
tokenizer=HuggingFaceTokenizer(
tokenizer=AutoTokenizer.from_pretrained(EMBED_MODEL)
)
)
doc = converter.convert("report.pdf").document
chunks = list(chunker.chunk(doc))
# Embed
embed_model = SentenceTransformer(EMBED_MODEL)
texts = [chunker.contextualize(c) for c in chunks]
embeddings = embed_model.encode(texts, normalize_embeddings=True)
# Store embeddings + metadata in your vector DB of choice
for chunk, embedding in zip(chunks, embeddings):
metadata = {
"text": chunk.text,
"headings": chunk.meta.headings,
"filename": chunk.meta.origin.filename if chunk.meta.origin else None,
"page_no": chunk.meta.doc_items[0].prov[0].page_no
if chunk.meta.doc_items and chunk.meta.doc_items[0].prov else None,
}
# insert (embedding, metadata) into your vector store
10. Key Imports#
Quick-reference imports organized by use case. Copy the block(s) you need.
Core Conversion#
from docling.document_converter import (
DocumentConverter,
PdfFormatOption,
ImageFormatOption,
WordFormatOption,
PowerpointFormatOption,
ExcelFormatOption,
HTMLFormatOption,
MarkdownFormatOption,
AudioFormatOption,
LatexFormatOption,
EpubFormatOption,
)
from docling.datamodel.base_models import InputFormat, OutputFormat
Pipeline Configuration#
from docling.datamodel.pipeline_options import (
PdfPipelineOptions,
PipelineOptions,
# OCR engines
EasyOcrOptions,
TesseractCliOcrOptions,
TesseractOcrOptions,
RapidOcrOptions,
OcrMacOptions,
OcrAutoOptions,
NemotronOcrOptions,
# Table structure
TableStructureOptions, # V1
TableStructureV2Options, # V2
GraniteVisionTableStructureOptions, # Granite Vision (requires [vlm])
TableFormerMode,
# VLM / enrichment
CodeFormulaVlmOptions,
ChartExtractionModelKind,
)
from docling.datamodel.vlm_engine_options import (
TransformersVlmEngineOptions,
MlxVlmEngineOptions,
VllmVlmEngineOptions,
ApiVlmEngineOptions,
)
from docling.datamodel.backend_options import (
MsExcelBackendOptions,
HTMLBackendOptions,
LatexBackendOptions,
EpubBackendOptions,
MarkdownBackendOptions,
)
Document Model#
from docling_core.types import DoclingDocument
from docling_core.types.doc import (
DocItemLabel,
ContentLayer,
ImageRefMode,
)
from docling_core.types.doc.document import (
TextItem,
TableItem,
TableData,
TableCell,
PictureItem,
SectionHeaderItem,
GroupItem,
ListItem,
CodeItem,
FormulaItem,
ProvenanceItem,
DocumentOrigin,
ImageRef,
)
from docling_core.types.doc.base import BoundingBox, CoordOrigin, Size
Chunking#
from docling.chunking import HybridChunker
# or equivalently:
from docling_core.transforms.chunker.hybrid_chunker import HybridChunker
from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer
from docling_core.transforms.chunker.tokenizer.openai import OpenAITokenizer # requires [chunking-openai]
from docling_core.transforms.chunker.doc_chunk import DocChunk, DocMeta
# Table serialization for chunking
from docling_core.transforms.chunker.hierarchical_chunker import (
ChunkingDocSerializer,
ChunkingSerializerProvider,
)
from docling_core.transforms.serializer.markdown import MarkdownParams, MarkdownTableSerializer
Settings and Debug#
from docling.datamodel.settings import settings, DebugSettings, scoped
from docling.datamodel.progress_event import ProgressEvent
LangChain Integration#
from langchain_docling import DoclingLoader
from langchain_docling.loader import ExportType
LlamaIndex Integration#
from llama_index.readers.docling import DoclingReader
from llama_index.node_parser.docling import DoclingNodeParser