Document-to-Graph Pipeline (docling-graph)#
docling-graph transforms documents (PDF, DOCX, PPTX, images, Markdown, HTML, DocLang, and everything else Docling supports) into validated, queryable knowledge graphs . It targets high-precision use cases — chemistry, finance, legal — where exact entity relationships matter more than text embeddings .
Two extraction backends are available :
- LLM — routed through LiteLLM; works with OpenAI, Gemini, Mistral, IBM watsonx, vLLM, Ollama, and more
- VLM — local Docling-native visual language model extraction
Install:
pip install docling-graph # core + LLM backend
pip install "docling-graph[vlm]" # adds VLM backend
The main entry points are run_pipeline(config) (Python) and docling-graph convert (CLI), both returning a PipelineContext with knowledge_graph, extracted_models, and graph_metadata .
Pipeline Stages#
All stages are defined in docling_graph/pipeline/stages.py as independent PipelineStage subclasses that pass a PipelineContext forward:
| Stage | What it does | Key source |
|---|---|---|
InputNormalizationStage | Detects input type (URL, file, DoclingDocument JSON, DocLang), routes to validator + handler | |
TemplateLoadingStage | Loads Pydantic BaseModel template from a class reference or dotted-path string | |
ExtractionStage | Runs Docling conversion + LLM/VLM extraction; skips conversion for pre-parsed inputs; captures provenance ledger | |
DoclingExportStage | Exports parsed DoclingDocument as JSON, Markdown, and/or DocLang | |
GraphConversionStage | Calls GraphConverter.pydantic_list_to_graph() to build a NetworkX DiGraph; binds provenance; reconciles aliases | |
ExportStage | Writes graph as CSV, Cypher, and/or JSON; writes provenance.json | |
VisualizationStage | Generates report.md + interactive graph.html (Cytoscape) |
Short-circuit for pre-parsed inputs: When the source is a DoclingDocument JSON or DocLang file, InputNormalizationStage sets skip_document_conversion=True and ExtractionStage routes directly to extract_from_document() — no OCR or layout models are invoked . This is the recommended way to re-extract with a different template without re-paying the conversion cost .
Extraction — Docling Conversion & LLM Backends#
ExtractionStage delegates to ExtractorFactory.create_extractor(), configured by the backend, extraction_contract, and processing_mode settings .
Docling conversion (OCR, layout, table structure, formula/code extraction) produces a DoclingDocument — a schema-versioned JSON carrying all text, tables, figures, and page-level bounding boxes. The LLM then receives this structured representation rather than raw bytes.
Extraction contracts (set via extraction_contract) control how document content is sent to the LLM:
"auto"(default) — selectsdirectordenseper-document based on size"direct"— single LLM call over the full document; optional gleaning pass for recall"dense"— two-phase skeleton→fill for large or complex documents
See Document Extraction Strategies for the complete comparison .
LLM input format (llm_input_format): "doclang-geo" (DocLang XML with bounding-box geometry) pairs with direct; "doclang" (without geometry) pairs with dense; "auto" resolves automatically .
Remote Docling conversion: Setting docling_serve_url delegates the conversion step to a running docling-serve instance while keeping LLM extraction local .
Graph Construction & Provenance#
GraphConversionStage calls GraphConverter.pydantic_list_to_graph() to turn the list of extracted Pydantic models into a NetworkX DiGraph. Each Pydantic model class annotated is_entity=True becomes a node type; fields declared with edge("REL_TYPE", ...) become directed edges .
Stable node IDs are derived deterministically from graph_id_fields in the template's model_config .
Provenance is attached by default (provenance="standard") to every node as a __provenance__ attribute pointing to the source chunk and page — no extra LLM calls . The full provenance ledger is written to provenance.json alongside the graph outputs . Setting provenance="detailed" additionally embeds character spans directly on node attributes .
Alias reconciliation collapses duplicate entity mentions after extraction using an LLM identity call ; the VLM backend skips this step.
Export Formats & Neo4j Integration#
ExportStage writes to the docling_graph/ subdirectory of the output folder. JSON (graph.json) is always written; export_format selects whether CSV or Cypher is also emitted .
| Format | Files | Best for |
|---|---|---|
| CSV (default) | nodes.csv, edges.csv | Excel, Pandas, SQL |
| Cypher | graph.cypher | Neo4j direct import |
| JSON | graph.json (always) | Python APIs, in-memory use |
Cypher Export#
CypherExporter generates ;-terminated, self-contained Cypher statements ready for cypher-shell. It emits per-label UNIQUE constraints at the top of the script so every MERGE/MATCH is index-backed . Property types are preserved: numbers, booleans, and homogeneous scalar lists become Cypher literals; dicts (including __provenance__) become JSON strings .
Two styles:
"merge"(default) — idempotent; re-running updates properties in place without duplicating nodes"create"— plainCREATEstatements; faster for a one-shot bulk load into an empty database
Importing into Neo4j#
Three options :
# Recommended: cypher-shell
cypher-shell -u neo4j -p password -f outputs/graph.cypher
# Python neo4j driver (statement-by-statement)
from neo4j import GraphDatabase
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password"))
code = "\n".join(l for l in cypher_script.splitlines() if not l.startswith("//"))
with driver.session() as session:
for stmt in code.split(";\n"):
if stmt.strip():
session.run(stmt)
Or paste into the Neo4j Browser at http://localhost:7474.
In-Memory Round-Trip (no files)#
Use graph_to_dict() / load_graph_from_dict() to avoid writing to disk when serving graphs over HTTP or in tests .
Key Files & References#
| File | Purpose |
|---|---|
docling_graph/pipeline/stages.py | All pipeline stage implementations |
docling_graph/core/exporters/cypher_exporter.py | Cypher script generation |
docs/fundamentals/graph-management/export-formats.md | Export formats guide (CSV, Cypher, JSON) |
docs/fundamentals/graph-management/neo4j-integration.md | Neo4j setup, import methods, query examples |
README.md | Project overview, quick-start, template examples |
Related KB articles:
- Document Extraction Strategies —
direct/dense/autoextraction contracts in depth - Docling Python Library Reference —
DocumentConverter,DoclingDocument, chunking