Docling: Document Parsing Cerdas untuk Pipeline AI dan RAG
Dalam era AI generatif, kemampuan untuk mengekstrak informasi dari dokumen secara otomatis menjadi sangat krusial. Baik itu PDF laporan tahunan, presentasi PowerPoint, dokumen Word, atau halaman web HTML, kita membutuhkan alat yang mampu mengubah format-format tersebut menjadi data terstruktur yang siap dikonsumsi oleh model AI. Di sinilah Docling hadir sebagai solusi.
Docling adalah library open-source dari IBM Research yang dirancang untuk melakukan parsing dokumen secara cerdas. Library ini mendukung berbagai format input dan mampu menghasilkan output dalam format Markdown atau JSON yang bersih, siap untuk digunakan dalam pipeline AI, khususnya Retrieval-Augmented Generation (RAG).
Dalam tutorial ini, kita akan mempelajari cara menggunakan Docling mulai dari instalasi, konversi dokumen dasar, hingga membangun pipeline ingestion dokumen yang lengkap untuk RAG.
Prasyarat
Sebelum memulai, pastikan Anda memiliki:
- Python 3.10 atau lebih baru
- pip package manager
- Pemahaman dasar tentang Python
- (Opsional) GPU untuk OCR yang lebih cepat
Instalasi
Instalasi Docling cukup mudah menggunakan pip. Ada beberapa opsi instalasi tergantung kebutuhan Anda.
Instalasi Dasar
pip install docling
Instalasi dengan Dukungan OCR
pip install "docling[ocr]"
Instalasi Lengkap (Semua Fitur)
pip install "docling[all]"
Verifikasi Instalasi
import docling
print(f"Docling version: {docling.version}")
Format yang Didukung
Docling mendukung berbagai format dokumen sebagai input:
| Format | Ekstensi | Keterangan |
|--------|----------|------------|
| PDF | .pdf | Termasuk PDF dengan scan/gambar |
| Microsoft Word | .docx | Format Open XML |
| Microsoft PowerPoint | .pptx | Format Open XML |
| HTML | .html, .htm | Halaman web |
| Gambar | .png, .jpg, .tiff | Melalui OCR |
| AsciiDoc | .adoc | Format dokumentasi |
| Markdown | .md | Format markdown |
Konversi Dokumen Dasar
Mari mulai dengan konversi dokumen sederhana. Docling menyediakan API yang intuitif melalui class DocumentConverter.
Konversi PDF ke Markdown
from docling.documentconverter import DocumentConverter
Inisialisasi converter
converter = DocumentConverter()
Konversi dokumen PDF
result = converter.convert("laporan
tahunan.pdf")
Dapatkan output dalam format Markdown
markdownoutput = result.document.exporttomarkdown()
print(markdownoutput)
Konversi dari URL
Docling juga mendukung konversi langsung dari URL:
from docling.documentconverter import DocumentConverter
converter = DocumentConverter()
Konversi dari URL
result = converter.convert("https://example.com/dokumen.pdf")
markdown
output = result.document.exporttomarkdown()
print(markdownoutput)
Konversi DOCX
from docling.documentconverter import DocumentConverter
converter = DocumentConverter()
result = converter.convert("proposalproyek.docx")
markdownoutput = result.document.exporttomarkdown()
Simpan ke file
with open("proposalproyek.md", "w", encoding="utf-8") as f:
f.write(markdownoutput)
print("Konversi selesai!")
Format Output
Docling mendukung beberapa format output yang dapat Anda pilih sesuai kebutuhan.
Export ke Markdown
from docling.documentconverter import DocumentConverter
converter = DocumentConverter()
result = converter.convert("dokumen.pdf")
Export ke Markdown
md
content = result.document.exporttomarkdown()
Simpan ke file
with open("output.md", "w", encoding="utf-8") as f:
f.write(mdcontent)
Export ke JSON (Document Format)
import json
from docling.documentconverter import DocumentConverter
converter = DocumentConverter()
result = converter.convert("dokumen.pdf")
Export ke dictionary/JSON
docdict = result.document.exporttodict()
Simpan ke file JSON
with open("output.json", "w", encoding="utf-8") as f:
json.dump(docdict, f, indent=2, ensureascii=False)
Export ke Teks Biasa
from docling.documentconverter import DocumentConverter
converter = DocumentConverter()
result = converter.convert("dokumen.pdf")
Export ke teks biasa
textcontent = result.document.exporttotext()
print(textcontent)
Ekstraksi Tabel
Salah satu fitur unggulan Docling adalah kemampuannya mengekstrak tabel dari dokumen dengan akurat.
from docling.documentconverter import DocumentConverter
converter = DocumentConverter()
result = converter.convert("laporan
keuangan.pdf")
Iterasi semua tabel dalam dokumen
for tableix, table in enumerate(result.document.tables):
print(f"\n=== Tabel {tableix + 1} ===")
# Export tabel ke DataFrame pandas
df = table.exporttodataframe()
print(df)
# Simpan ke CSV
df.tocsv(f"tabel{tableix + 1}.csv", index=False)
print(f"Tabel {tableix + 1} disimpan ke CSV")
Konfigurasi Ekstraksi Tabel
from docling.documentconverter import DocumentConverter, PdfFormatOption
from docling.datamodel.pipeline
options import PdfPipelineOptions
from docling.datamodel.basemodels import InputFormat
Konfigurasi pipeline untuk tabel
pipelineoptions = PdfPipelineOptions()
pipelineoptions.dotablestructure = True
pipelineoptions.tablestructureoptions.docellmatching = True
converter = DocumentConverter(
formatoptions={
InputFormat.PDF: PdfFormatOption(
pipelineoptions=pipelineoptions
)
}
)
result = converter.convert("dokumendengantabel.pdf")
for table in result.document.tables:
df = table.exporttodataframe()
print(df.tostring())
Ekstraksi Gambar
Docling dapat mengekstrak gambar yang terdapat dalam dokumen.
from docling.documentconverter import DocumentConverter, PdfFormatOption
from docling.datamodel.pipeline
options import PdfPipelineOptions
from docling.datamodel.basemodels import InputFormat
from pathlib import Path
Aktifkan ekstraksi gambar
pipelineoptions = PdfPipelineOptions()
pipelineoptions.imagesscale = 2.0
pipelineoptions.generatepictureimages = True
converter = DocumentConverter(
formatoptions={
InputFormat.PDF: PdfFormatOption(
pipelineoptions=pipelineoptions
)
}
)
result = converter.convert("dokumenbergambar.pdf")
Simpan gambar yang diekstrak
outputdir = Path("extractedimages")
outputdir.mkdir(existok=True)
for idx, picture in enumerate(result.document.pictures):
if picture.image:
imagepath = outputdir / f"gambar{idx + 1}.png"
picture.image.pilimage.save(str(imagepath))
print(f"Gambar {idx + 1} disimpan ke {imagepath}")
Dukungan OCR
Untuk dokumen yang berupa scan atau gambar, Docling menyediakan dukungan OCR (Optical Character Recognition).
from docling.documentconverter import DocumentConverter, PdfFormatOption
from docling.datamodel.pipelineoptions import (
PdfPipelineOptions,
EasyOcrOptions,
TesseractOcrOptions,
)
from docling.datamodel.basemodels import InputFormat
Menggunakan EasyOCR
pipelineoptions = PdfPipelineOptions()
pipelineoptions.doocr = True
pipelineoptions.ocroptions = EasyOcrOptions(
lang=["id", "en"], # Bahasa Indonesia dan Inggris
forcefullpageocr=False,
)
converter = DocumentConverter(
formatoptions={
InputFormat.PDF: PdfFormatOption(
pipelineoptions=pipelineoptions
)
}
)
result = converter.convert("dokumenscan.pdf")
markdownoutput = result.document.exporttomarkdown()
print(markdownoutput)
Menggunakan Tesseract OCR
from docling.datamodel.pipelineoptions import TesseractOcrOptions
Konfigurasi Tesseract
pipeline
options = PdfPipelineOptions()
pipelineoptions.doocr = True
pipelineoptions.ocroptions = TesseractOcrOptions(
lang=["ind", "eng"], # Kode bahasa Tesseract
)
converter = DocumentConverter(
formatoptions={
InputFormat.PDF: PdfFormatOption(
pipelineoptions=pipelineoptions
)
}
)
result = converter.convert("dokumenscan.pdf")
print(result.document.exporttomarkdown())
Chunking untuk RAG
Fitur chunking sangat penting untuk pipeline RAG. Docling menyediakan beberapa strategi chunking yang cerdas.
Hierarchical Chunking
from docling.documentconverter import DocumentConverter
from docling.chunking import HierarchicalChunker
converter = DocumentConverter()
result = converter.convert("dokumen
panjang.pdf")
Gunakan hierarchical chunker
chunker = HierarchicalChunker()
chunks = list(chunker.chunk(result.document))
for i, chunk in enumerate(chunks):
print(f"\n--- Chunk {i + 1} ---")
print(f"Text: {chunk.text[:200]}...")
print(f"Metadata: {chunk.meta}")
Hybrid Chunking
from docling.chunking import HybridChunker
from tokenizers import Tokenizer
Chunker dengan batasan token
chunker = HybridChunker(
tokenizer=Tokenizer.frompretrained("bert-base-uncased"),
maxtokens=512,
mergepeers=True,
)
converter = DocumentConverter()
result = converter.convert("dokumen.pdf")
chunks = list(chunker.chunk(result.document))
for i, chunk in enumerate(chunks):
print(f"Chunk {i + 1}: {len(chunk.text)} karakter")
print(f"Heading: {chunk.meta.headings}")
print(f"Text preview: {chunk.text[:150]}...")
print()
Batch Processing
Untuk memproses banyak dokumen sekaligus, Docling menyediakan fitur batch processing.
from docling.documentconverter import DocumentConverter
from pathlib import Path
converter = DocumentConverter()
Daftar dokumen yang akan diproses
inputfiles = [
"dokumen1.pdf",
"dokumen2.docx",
"dokumen3.pptx",
"https://example.com/dokumen4.html",
]
Batch convert
results = converter.convertall(inputfiles)
for result in results:
source = result.input.file
print(f"\nMemproses: {source}")
if result.status.value == "success":
md = result.document.exporttomarkdown()
outputfile = Path("output") / f"{Path(str(source)).stem}.md"
outputfile.parent.mkdir(existok=True)
with open(outputfile, "w", encoding="utf-8") as f:
f.write(md)
print(f" -> Berhasil disimpan ke {outputfile}")
else:
print(f" -> Gagal: {result.status}")
Batch Processing dengan Progress Tracking
from docling.documentconverter import DocumentConverter
from pathlib import Path
import time
converter = DocumentConverter()
input
dir = Path("dokumeninput")
pdf
files = list(inputdir.glob(".pdf"))
print(f"Ditemukan {len(pdf
files)} file PDF")
starttime = time.time()
results = converter.convert
all(
[str(f) for f in pdffiles],
raisesonerror=False,
)
successcount = 0
errorcount = 0
for result in results:
if result.status.value == "success":
successcount += 1
md = result.document.exporttomarkdown()
outputpath = Path("output") / f"{Path(str(result.input.file)).stem}.md"
outputpath.parent.mkdir(existok=True)
with open(outputpath, "w", encoding="utf-8") as f:
f.write(md)
else:
errorcount += 1
print(f"Error pada {result.input.file}: {result.status}")
elapsed = time.time() - starttime
print(f"\nSelesai dalam {elapsed:.1f} detik")
print(f"Berhasil: {successcount}, Gagal: {errorcount}")
Kustomisasi Pipeline
Docling memungkinkan Anda untuk menyesuaikan pipeline konversi sesuai kebutuhan.
from docling.documentconverter import DocumentConverter, PdfFormatOption
from docling.datamodel.pipeline
options import PdfPipelineOptions
from docling.datamodel.basemodels import InputFormat
Konfigurasi pipeline kustom
pipelineoptions = PdfPipelineOptions()
pipelineoptions.doocr = True
pipelineoptions.dotablestructure = True
pipelineoptions.tablestructureoptions.docellmatching = True
pipelineoptions.generatepictureimages = True
pipelineoptions.imagesscale = 2.0
converter = DocumentConverter(
allowedformats=[
InputFormat.PDF,
InputFormat.DOCX,
InputFormat.PPTX,
InputFormat.HTML,
InputFormat.IMAGE,
],
formatoptions={
InputFormat.PDF: PdfFormatOption(
pipelineoptions=pipelineoptions
)
}
)
result = converter.convert("dokumenkompleks.pdf")
print(result.document.exporttomarkdown())
Integrasi dengan LlamaIndex
Docling terintegrasi dengan baik dengan LlamaIndex untuk membangun pipeline RAG.
pip install llama-index-readers-docling llama-index
from llamaindex.readers.docling import DoclingReader
from llama
index.core import VectorStoreIndex
Gunakan DoclingReader
reader = DoclingReader()
documents = reader.loaddata(
filepath=["laporan.pdf", "presentasi.pptx"]
)
Buat index untuk RAG
index = VectorStoreIndex.fromdocuments(documents)
Query engine
queryengine = index.asqueryengine()
response = queryengine.query(
"Apa kesimpulan utama dari laporan tersebut?"
)
print(response)
Integrasi dengan LangChain
Docling juga tersedia sebagai document loader untuk LangChain.
pip install langchain-docling langchain-openai langchain
from langchaindocling import DoclingLoader
from langchain.textsplitter import RecursiveCharacterTextSplitter
from langchainopenai import OpenAIEmbeddings, ChatOpenAI
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
Load dokumen dengan Docling
loader = DoclingLoader(
filepath="laporankeuangan.pdf",
exporttype="markdown",
)
documents = loader.load()
Split dokumen
textsplitter = RecursiveCharacterTextSplitter(
chunksize=1000,
chunkoverlap=200,
)
splits = textsplitter.splitdocuments(documents)
Buat vector store
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.fromdocuments(splits, embeddings)
Buat chain RAG
llm = ChatOpenAI(model="gpt-4o", temperature=0)
qachain = RetrievalQA.fromchaintype(
llm=llm,
chaintype="stuff",
retriever=vectorstore.asretriever(searchkwargs={"k": 5}),
)
Query
result = qachain.invoke(
{"query": "Berapa total pendapatan perusahaan tahun ini?"}
)
print(result["result"])
Contoh Praktis: Pipeline Ingestion Dokumen untuk RAG
Berikut adalah contoh lengkap membangun pipeline ingestion dokumen menggunakan Docling untuk sistem RAG.
"""
Pipeline Ingestion Dokumen untuk RAG menggunakan Docling
"""
import json
import hashlib
from pathlib import Path
from datetime import datetime
from dataclasses import dataclass, field
from docling.documentconverter import DocumentConverter, PdfFormatOption
from docling.datamodel.pipelineoptions import PdfPipelineOptions, EasyOcrOptions
from docling.datamodel.basemodels import InputFormat
from docling.chunking import HybridChunker
from tokenizers import Tokenizer
@dataclass
class ProcessedChunk:
"""Representasi chunk yang sudah diproses."""
chunkid: str
text: str
sourcefile: str
headings: list = field(defaultfactory=list)
pagenumbers: list = field(defaultfactory=list)
chunkindex: int = 0
totalchunks: int = 0
processedat: str = ""
class DocumentIngestionPipeline:
"""Pipeline untuk ingestion dokumen ke sistem RAG."""
def init(
self,
outputdir: str = "ragoutput",
maxtokens: int = 512,
enableocr: bool = True,
ocrlanguages: list = None,
):
self.outputdir = Path(outputdir)
self.outputdir.mkdir(parents=True, existok=True)
# Konfigurasi pipeline
pipelineoptions = PdfPipelineOptions()
pipelineoptions.dotablestructure = True
pipelineoptions.tablestructureoptions.docellmatching = True
if enableocr:
pipelineoptions.doocr = True
pipelineoptions.ocroptions = EasyOcrOptions(
lang=ocrlanguages or ["id", "en"],
forcefullpageocr=False,
)
self.converter = DocumentConverter(
allowedformats=[
InputFormat.PDF,
InputFormat.DOCX,
InputFormat.PPTX,
InputFormat.HTML,
InputFormat.IMAGE,
],
formatoptions={
InputFormat.PDF: PdfFormatOption(
pipelineoptions=pipelineoptions
)
}
)
# Konfigurasi chunker
self.chunker = HybridChunker(
tokenizer=Tokenizer.frompretrained("bert-base-uncased"),
maxtokens=maxtokens,
mergepeers=True,
)
def generatechunkid(self, text: str, source: str, index: int) -> str:
"""Generate ID unik untuk setiap chunk."""
content = f"{source}:{index}:{text[:100]}"
return hashlib.md5(content.encode()).hexdigest()
def processdocument(self, filepath: str) -> list[ProcessedChunk]:
"""Proses satu dokumen dan hasilkan chunks."""
print(f"Memproses: {filepath}")
# Konversi dokumen
result = self.converter.convert(filepath)
if result.status.value != "success":
print(f" Gagal mengkonversi: {result.status}")
return []
# Chunking
chunks = list(self.chunker.chunk(result.document))
processedchunks = []
for i, chunk in enumerate(chunks):
chunkid = self.generatechunkid(
chunk.text, filepath, i
)
processed = ProcessedChunk(
chunkid=chunkid,
text=chunk.text,
sourcefile=str(filepath),
headings=chunk.meta.headings if chunk.meta else [],
chunkindex=i,
totalchunks=len(chunks),
processedat=datetime.now().isoformat(),
)
processedchunks.append(processed)
print(f" Dihasilkan {len(processedchunks)} chunks")
return processedchunks
def processdirectory(self, inputdir: str) -> list[ProcessedChunk]:
"""Proses semua dokumen dalam direktori."""
inputpath = Path(inputdir)
supportedextensions = {
".pdf", ".docx", ".pptx", ".html", ".htm",
".png", ".jpg", ".jpeg", ".tiff",
}
files = [
f for f in inputpath.rglob("")
if f.suffix.lower() in supportedextensions
]
print(f"Ditemukan {len(files)} dokumen untuk diproses")
allchunks = []
for filepath in files:
chunks = self.processdocument(str(filepath))
allchunks.extend(chunks)
return allchunks
def savechunks(self, chunks: list[ProcessedChunk]) -> str:
"""Simpan chunks ke file JSON."""
outputfile = self.outputdir / "chunks.json"
chunksdata = []
for chunk in chunks:
chunksdata.append({
"id": chunk.chunkid,
"text": chunk.text,
"metadata": {
"source": chunk.sourcefile,
"headings": chunk.headings,
"chunkindex": chunk.chunkindex,
"totalchunks": chunk.totalchunks,
"processedat": chunk.processedat,
},
})
with open(outputfile, "w", encoding="utf-8") as f:
json.dump(chunksdata, f, indent=2, ensureascii=False)
print(f"\n{len(chunks)} chunks disimpan ke {outputfile}")
return str(outputfile)
def exportforvectordb(self, chunks: list[ProcessedChunk]) -> dict:
"""Export chunks dalam format siap untuk vector database."""
return {
"documents": [c.text for c in chunks],
"ids": [c.chunkid for c in chunks],
"metadatas": [
{
"source": c.sourcefile,
"headings": ", ".join(c.headings) if c.headings else "",
"chunkindex": c.chunkindex,
}
for c in chunks
],
}
Penggunaan pipeline
if name == "main":
# Inisialisasi pipeline
pipeline = DocumentIngestionPipeline(
outputdir="ragoutput",
maxtokens=512,
enableocr=True,
ocrlanguages=["id", "en"],
)
# Proses satu dokumen
chunks = pipeline.processdocument("laporantahunan2025.pdf")
# Atau proses seluruh direktori
# chunks = pipeline.processdirectory("dokumenperusahaan/")
# Simpan hasil
pipeline.savechunks(chunks)
# Export untuk vector database
vectordbdata = pipeline.exportforvectordb(chunks)
# Contoh: masukkan ke ChromaDB
# import chromadb
# client = chromadb.Client()
# collection = client.createcollection("dokumenperusahaan")
# collection.add(vectordbdata)
print("\nPipeline ingestion selesai!")
print(f"Total chunks: {len(chunks)}")
Tips dan Best Practices
convertall() untuk memanfaatkan paralelisme bawaan Docling.Kesimpulan
Docling menyediakan solusi lengkap untuk parsing dokumen dalam pipeline AI. Dengan dukungan untuk berbagai format input, kemampuan OCR, ekstraksi tabel dan gambar, serta integrasi dengan framework RAG populer seperti LlamaIndex dan LangChain, Docling menjadi alat yang sangat berharga dalam membangun aplikasi AI yang membutuhkan pemahaman dokumen.
Fitur chunking cerdas yang disediakan Docling juga memudahkan persiapan data untuk pipeline RAG, memastikan bahwa informasi dari dokumen dapat diakses dan dimanfaatkan secara optimal oleh model AI.
Mulailah bereksperimen dengan Docling pada dokumen-dokumen Anda dan lihat bagaimana library ini dapat meningkatkan kualitas pipeline AI Anda!