Dosu LogoDosu Logo
Ask
Join our Discord
DoclingPublic
IBM Docling
DocumentsDocling
PDF-to-RAG Pipeline
PDF-to-RAG Pipeline
Type
Topic
Status
Published
Created
Jul 7, 2026
Updated
Jul 7, 2026

PDF-to-RAG Pipeline#

The PDF-to-RAG pipeline is Docling's primary workflow for preparing documents for retrieval-augmented generation. It chains four core subsystems — document conversion, hierarchical chunking, tokenizer-aware splitting, and vector store ingestion — into a reusable pattern. The canonical end-to-end example is docs/examples/rag_langchain.ipynb.

PDF ──► DocumentConverter ──► DoclingDocument ──► HybridChunker ──► DocChunk[]
                                                                          │
                          VectorStore ◄── embed(contextualize(chunk)) ◄──┘
                               │
                           Retriever ──► LLM

Step 1: PDF Conversion#

DocumentConverter is the entry point. It accepts a file path or URL and returns a ConversionResult whose .document field is a DoclingDocument — the canonical, schema-versioned JSON representation carrying all texts, tables, pictures, and page-level provenance.

For RAG use cases the most important pipeline option is do_table_structure=True, which activates table structure recognition (TableFormer V1/V2 or Granite Vision) . Other useful options:

OptionPurpose
do_table_structureExtract table cell grids (required for table chunking)
do_ocrEnable OCR for scanned PDFs
do_code_enrichment / do_formula_enrichmentEnrich code blocks and math formulas
pdf_backendSelect backend: docling_parse (default), pypdfium2, threaded_docling_parse

See the PDF pipeline options reference for the full option set, and the table structure recognition guide for backend selection.

Step 2: Chunking with HybridChunker#

HybridChunker (importable as from docling.chunking import HybridChunker) applies tokenization-aware refinements on top of document-structure-based hierarchical chunking . It produces DocChunk objects, each with a text field and a meta: DocMeta field.

Key constructor parameters :

ParameterDefaultDescription
tokenizerHuggingFaceTokenizer("sentence-transformers/all-MiniLM-L6-v2")Controls split boundaries
max_tokensderived from tokenizerHard cap per chunk
merge_peersTrueMerge undersized sibling chunks
repeat_table_headerTrueRepeat header rows across table chunks
omit_header_on_overflowFalseDrop header when row + header exceeds budget
serializer_providerChunkingSerializerProvider()Controls table-to-text serialization

Embedding text: The text you embed should be the context-enriched form from chunker.contextualize(chunk), which prepends the in-scope section headings to chunk.text .

Step 3: Tokenizer Configuration#

The chunker tokenizer must match the embedding model's tokenizer. Token counts used for splitting are only meaningful relative to the embedding model's context window .

HuggingFace tokenizer (docling_core/transforms/chunker/tokenizer/huggingface.py):

from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer
from transformers import AutoTokenizer

tokenizer = HuggingFaceTokenizer(
    tokenizer=AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2"),
    max_tokens=512, # optional; defaults to model max if omitted
)

OpenAI / tiktoken (docling_core/transforms/chunker/tokenizer/openai.py) — 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,
# )

Both implement the same BaseTokenizer interface (count_tokens, get_max_tokens, get_tokenizer).

ℹ️ HuggingFace transformers may warn "Token indices sequence length is longer than the specified maximum sequence length" during chunker initialization — this is a false alarm; see the FAQ .

Step 4: Table Chunking Strategies#

Table serialization is the dominant quality lever for RAG pipelines with heavy table content .

Default: Triplet Serialization (avoid for table-heavy docs)#

TripletTableSerializer (the default in ChunkingDocSerializer) emits flat "**Column**, row = value" strings. This destroys cell-to-column-header bindings that carry the semantic payload of structured tables .

Recommended: Markdown Serialization#

Use a custom ChunkingSerializerProvider with MarkdownTableSerializer to preserve column headers in each chunk :

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,
    serializer_provider=MDTableSerializerProvider(),
)

With repeat_table_header=True, each chunk from a split table begins with the column header row . See the advanced chunking and serialization docs for additional strategies .

LineBasedTokenChunker (for structured text / wide tables)#

LineBasedTokenChunker preserves line boundaries — useful for tables, code, and logs . Key parameters:

  • prefix: text prepended to every chunk (e.g., table header row)
  • omit_prefix_on_overflow=True: drop the prefix for rows that exceed the token budget with it — keeps row intact; use when line integrity > context consistency

Step 5: Chunk Provenance and Metadata#

Every DocChunk carries a DocMeta with three-layer traceability back to the source PDF :

DocChunk.meta
  ├── 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)
  ├── headings: list[str] # section headings in scope
  └── origin: DocumentOrigin # filename, mimetype, binary_hash

This chain enables RAG pipelines to cite the exact page and bounding box for any retrieved chunk. The LangChain integration stores this as dl_meta in the LangChain Document.metadata dict .

DocMeta.excluded_embed and excluded_llm class-level lists control which fields flow into contextualize() — by default only headings is included in the embedding string .

Step 6: Vector Store Ingestion (LangChain)#

The DoclingLoader from langchain-docling handles conversion + chunking in one call:

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_ID = "sentence-transformers/all-MiniLM-L6-v2"

loader = DoclingLoader(
    file_path=["https://arxiv.org/pdf/2408.09869"],
    export_type=ExportType.DOC_CHUNKS, # one LangChain doc per chunk
    chunker=HybridChunker(
        tokenizer=HuggingFaceTokenizer(
            tokenizer=AutoTokenizer.from_pretrained(EMBED_MODEL_ID)
        )
    ),
)
splits = loader.load()

ExportType.MARKDOWN is the alternative — returns one LangChain document per PDF, then split externally with MarkdownHeaderTextSplitter . Use DOC_CHUNKS (default) for document-native grounding; use MARKDOWN when you need custom splitting logic.

After loading, ingest into any LangChain-compatible vector store (Milvus, FAISS, Chroma, etc.) using the same EMBED_MODEL_ID that was used for the tokenizer .

Key Source Files#

ComponentFile
HybridChunkerdocling_core/transforms/chunker/hybrid_chunker.py
TripletTableSerializer, ChunkingSerializerProvider, ChunkingDocSerializerdocling_core/transforms/chunker/hierarchical_chunker.py
LineBasedTokenChunkerdocling_core/transforms/chunker/line_chunker.py (see line-based chunking example)
HuggingFaceTokenizerdocling_core/transforms/chunker/tokenizer/huggingface.py
OpenAITokenizerdocling_core/transforms/chunker/tokenizer/openai.py
DocChunk / DocMetadocling_core/transforms/chunker/doc_chunk.py
E2E LangChain RAG exampledocs/examples/rag_langchain.ipynb
Hybrid chunking exampledocs/examples/hybrid_chunking.ipynb
Line-based chunking exampledocs/examples/line_based_chunking.ipynb
PDF pipeline optionsPipeline options reference
Chunk provenance detailsDocument Chunk Metadata and Provenance
Table serialization optionsTable Export and Serialization
Documents
Agentic Document Processing
API Authentication
Apple Silicon Support
How can I set up and run docling-serve on a MacBook Pro using Docker, and what performance and stability considerations should I be aware of?
Bibliography Extraction and Parsing
Bounding Box Visualization
Caption-Figure Linking
Chart Extraction
What are the differences between `vlm_pipeline_model_local` and `picture_description_local` in Docling, and how do image descriptions, OCR, and table extraction work together? Also, how do the `include_annotations` and `mark_annotations` properties affect exported output?
Chemical Notation OCR
Citation Data Modeling
CLI File Staging and Collision Handling
CLI Image Export Modes
How can I improve the resolution or quality of images extracted from a PDF using docling?
Code Chunking
Container Image Variants
How can I set up and run docling-serve on a MacBook Pro using Docker, and what performance and stability considerations should I be aware of?
What is the recommended Azure deployment option for a Docling-based Python SDK application using a custom Dockerfile with PyTorch and OCR, and why?
Cross-Platform Support
Custom Enrichment Models
Custom Layout Plugin Architecture
DocItemLabel Type System
DocLang Format
Docling Image Extraction
How can I improve the resolution or quality of images extracted from a PDF using docling?
What are the differences between `vlm_pipeline_model_local` and `picture_description_local` in Docling, and how do image descriptions, OCR, and table extraction work together? Also, how do the `include_annotations` and `mark_annotations` properties affect exported output?
Docling Model Management
How can I set up and run docling-serve on a MacBook Pro using Docker, and what performance and stability considerations should I be aware of?
What is the recommended Azure deployment option for a Docling-based Python SDK application using a custom Dockerfile with PyTorch and OCR, and why?
Docling Pipeline Configuration
What are the differences between `vlm_pipeline_model_local` and `picture_description_local` in Docling, and how do image descriptions, OCR, and table extraction work together? Also, how do the `include_annotations` and `mark_annotations` properties affect exported output?
Docling Resource Requirements
How can I set up and run docling-serve on a MacBook Pro using Docker, and what performance and stability considerations should I be aware of?
What is the recommended Azure deployment option for a Docling-based Python SDK application using a custom Dockerfile with PyTorch and OCR, and why?
Docling Rust SDK
Docling Serve API Client
How can I use Docling's REST API to convert a PDF from a URL to Markdown with OpenAI-generated image descriptions, and is base64 encoding required for URL sources?
Docling Serve Configuration
How can I set up and run docling-serve on a MacBook Pro using Docker, and what performance and stability considerations should I be aware of?
How can you mount a PersistentVolumeClaim (PVC) in docling-serve on OpenShift to store EasyOCR models, and what steps are required to ensure docling-serve can access these models?
What are the differences between `vlm_pipeline_model_local` and `picture_description_local` in Docling, and how do image descriptions, OCR, and table extraction work together? Also, how do the `include_annotations` and `mark_annotations` properties affect exported output?
Docling Serve Deployment
How can I set up and run docling-serve on a MacBook Pro using Docker, and what performance and stability considerations should I be aware of?
How can you mount a PersistentVolumeClaim (PVC) in docling-serve on OpenShift to store EasyOCR models, and what steps are required to ensure docling-serve can access these models?
Models handling in Docling Serve
skill.md
What is the recommended Azure deployment option for a Docling-based Python SDK application using a custom Dockerfile with PyTorch and OCR, and why?
Docling Serve Worker Architecture
DoclingDocument Builder API
Building a Modular IDP Pipeline with Docling Components
DoclingDocument Data Model
Building a Modular IDP Pipeline with Docling Components
DoclingDocument Hierarchization
DoclingDocument Java Serialization
DoclingDocument Serialization
Document Backends
Building a Modular IDP Pipeline with Docling Components
Document Chunk Metadata and Provenance
Document Chunking
Document Content Classification
Document Extraction Strategies
Document Figure Classification
Document Input Methods
How can I use Docling's REST API to convert a PDF from a URL to Markdown with OpenAI-generated image descriptions, and is base64 encoding required for URL sources?
Document Layout and Reading Order
How does Docling reconstruct reading order without using a large language model (LLM) call in an unsupervised manner?
Document Layout Detection Models
Building a Modular IDP Pipeline with Docling Components
Document Merging and Concatenation
Document Metadata
Document Pagination
Document Rotation and Orientation
Document Serialization Architecture
Document Tree Traversal
Document Type Classification and Routing
Document-to-Graph Pipeline
DocumentConverter Configuration
How can I use granite-docling to process all PDFs in a directory and output doctags?
DOCX Image Extraction
DOCX List Processing
DOCX Numbered Heading Processing
DOCX Reference and Citation Extraction
DOCX SDT Handling
DOCX Table Extraction
DOCX Text Formatting
Email Format Support
Enrichment Pipeline
What are the differences between `vlm_pipeline_model_local` and `picture_description_local` in Docling, and how do image descriptions, OCR, and table extraction work together? Also, how do the `include_annotations` and `mark_annotations` properties affect exported output?
Excel Backend Processing
Models handling in Docling Serve
Extraction Pipeline Prompting
GPU Accelerator Support
GPU Memory Management
Heading Hierarchy Configuration
HTML Export Format
HuggingFace Transformers Integration
IBM Watsonx and Granite Integration
How can I use granite-docling to process all PDFs in a directory and output doctags?
Image Reference Handling
How can I use Docling's REST API to convert a PDF from a URL to Markdown with OpenAI-generated image descriptions, and is base64 encoding required for URL sources?
skill.md
Input Format and Image Support
Knowledge Graph Extraction
Large PDF Memory Management
Layout Detection Configuration
Layout Postprocessor
Layout Prediction Data Structures
Building a Modular IDP Pipeline with Docling Components
LibreOffice Integration
List Marker Normalization
Markdown Export Configuration
How can I use Docling's REST API to convert a PDF from a URL to Markdown with OpenAI-generated image descriptions, and is base64 encoding required for URL sources?
Markdown Processing
MCP Server Integration
Docling MCP in Docling Serve
Multi-Language API Integration
Native Library Compatibility
NuExtract Transformers Compatibility
OCR Engine Configuration
OCR Engine Integration
OCR Language Support
ODF Backend Processing
Open WebUI Integration
Optional Dependency Management
Package Architecture
skill.md
Page Assembly Pipeline
Parsed Page Access and Segmentation
PDF Document Pipeline
Building a Modular IDP Pipeline with Docling Components
PDF Parse Lifecycle Management
PDF Pipeline Configuration
How can I improve the resolution or quality of images extracted from a PDF using docling?
PDF Rendering and OCR Pipeline
How can I improve the resolution or quality of images extracted from a PDF using docling?
PDF Spatial Filtering
PDF Text Extraction
PDF-to-RAG Pipeline
skill.md
Picture Classification Filtering
Picture Detection and Segmentation
Pipeline and Model Caching
skill.md
Pipeline Batch Size Configuration
Pipeline Error Logging
Pipeline Initialization and Dependency Loading
Pipeline Stage Architecture
PPTX Content Extraction
Pydantic-Based Extraction Templates
RAG Framework Connectors
RapidOCR Model Management
Redis Integration
Remote Inference Services
Resource Cleanup and Lifecycle Management
RTL and Bidirectional Text Support
Security Hardening
Spatial Predicates and R-tree Indexing
Structured Information Extraction
How can I use granite-docling to process all PDFs in a directory and output doctags?
skill.md
Table Cell Formatting
Table Cell Text Matching
Table Chunking
Table Export and Serialization
What are the differences between `vlm_pipeline_model_local` and `picture_description_local` in Docling, and how do image descriptions, OCR, and table extraction work together? Also, how do the `include_annotations` and `mark_annotations` properties affect exported output?
Table Structure Recognition
Building a Modular IDP Pipeline with Docling Components
Models handling in Docling Serve
TableFormer Confidence Scoring
Text Element Merging and Dehyphenation
Threaded PDF Backend
Tokenizer Backends
Torch Compile Optimization
VLM Extraction Pipeline
VLM Formula and Code Extraction
VLM Image Cropping
VLM Inference Configuration
VLM Inference Engine
Building a Modular IDP Pipeline with Docling Components
VLM Picture Description
How can I use Docling's REST API to convert a PDF from a URL to Markdown with OpenAI-generated image descriptions, and is base64 encoding required for URL sources?
What are the differences between `vlm_pipeline_model_local` and `picture_description_local` in Docling, and how do image descriptions, OCR, and table extraction work together? Also, how do the `include_annotations` and `mark_annotations` properties affect exported output?
VLM Pipeline
VLM Token Limits and Truncation
XML Backend Architecture
Can I use a custom OCR model in Docling, and how do I set its path in the pipeline options?
Can docling-serve fetch documents from object storage (e.g., S3)?
Comment corriger la phrase : "Je suis allé à l'école en pied et mains je parte par quotidien des beaucoup de kilomètres cela est importante" ?
Content Layers
Does Docling automatically detect the language of a document when sending images to Tesseract OCR, and how can it be configured?
How can I enable and use GPU acceleration with Docling?
How can I find page numbers and bounding box information for content in a chunk produced by the hybrid chunker, and what is the structure of the doc_items list within a chunk?
How can a student build a local, open-source LLM-based system to extract and analyze technical PDF documents (PMS/IDC) and generate instrumentation datasheets, using Python on a PC with limited resources?
How can a student build a local, open-source, privacy-preserving AI system to extract and query technical PDF documents (PMS/IDC) on a PC with limited resources?
How can you make Docling read/understand images embedded in a DOCX file, and what is the correct code to use the VlmPipeline for this purpose?
How can you use Docling's REST API to convert a PDF to Markdown and generate image descriptions using an OpenAI model?
How do I set up a complete multi-format document processing pipeline using Docling that handles technical PDFs, HTML files, images, videos, audio, codebases, and schematics, and exports everything to organized agent-friendly markdown files?
How do you install and use Docling in Python on WSL2, including integration with an AI agent?
How do you use HybridChunker in Docling, including saving and reloading the converted document?
How does Docling support parallel/multiprocessing for document conversion, and what do the key performance parameters (`page_chunk_size`, `doc_batch_concurrency`, `doc_batch_size`) do?
How to properly enable `enable_remote_services` in Docling Serve (CPU image) to use an external OpenAI-compatible API for picture description and formula enrichment, and what is the correct config format?
No Docling, o uso de CUDA é obrigatório para processar PDFs com extração de texto e descrição de imagens, ou é opcional?
Quais são as melhores opções de OCR para extração de tabelas financeiras complexas em PDFs usando Docling, incluindo alternativas externas e integração com plugins?
Quelle est l'origine et le statut des êtres mathématiques selon Platon et John Stuart Mill ?
What are all the parameters of HybridChunker in Docling, and how do you use it with a custom tokenizer?
What are all the pipelines that exist in Docling, including their purposes, selection criteria, and how they handle scanned documents?
What are the detailed pipeline options and processing behaviors for PDF, DOCX, PPTX, and XLSX files in the Python SDK?
What are the steps to convert a complex payment advice PDF to Excel using Docling?
What does 'RFLP' stand for or refer to?
What is the best practice for extracting text from a mixed PDF (digital + scanned pages) for enterprise financial document processing without a GPU and with limited costs?
What is the best practice for processing a mixed PDF (digital + scanned pages) containing sensitive financial data in Docling, given no GPU and limited cost?
What is the general sentiment expressed about the messy nature of documents and content in the Docling project?
What is the recommended architecture and implementation for processing a mixed PDF bundle (digital + scanned pages) for an enterprise financial payment verification system (like MRT Jakarta's AI-Augmented Payment Flow), with constraints of no GPU and limited cost?
When processing large PDFs (700+ pages) with Docling's StandardPdfPipeline, what causes the `std::bad_alloc` errors and what are the recommended workarounds?
Which is the better option for running Docling: using 'docling serve' in Azure Container Apps or code-based deployment in Azure Function App (Windows Premium plan)?
Why are bounding boxes not available for items (such as images, tables, text) when using VlmPipeline with certain VLM presets (like Qwen/Markdown)?
Zoom on Layer 1 (L1): Layout Detection & Routing in a Modular IDP Pipeline
คู่มือการดึงรูปภาพจาก PDF และสร้าง Markdown พร้อม Alternative Text ด้วย Docling