pdfmux
pdfmux
범용 PDF 추출 오케스트레이터입니다. 각 페이지를 최적의 백엔드로 라우팅하고, 결과를 감사하며, 실패 시 재추출합니다. 5가지 규칙 기반 추출기 + BYOK LLM 폴백을 지원합니다. 하나의 CLI, 하나의 API, 제로 설정으로 작동합니다.
PDF ──> pdfmux router ──> best extractor per page ──> audit ──> re-extract failures ──> Markdown / JSON / chunks
|
├─ PyMuPDF (digital text, 0.01s/page)
├─ OpenDataLoader (complex layouts, 0.05s/page)
├─ RapidOCR (scanned pages, CPU-only)
├─ Docling (tables, 97.9% TEDS)
├─ Surya (heavy OCR fallback)
└─ YOUR LLM (Gemini / Claude / GPT-4o / Ollama — BYOK via 5-line YAML)설치
pip install pdfmux이것으로 충분합니다. 디지털 PDF는 즉시 처리됩니다. 더 복잡한 문서를 위해 백엔드를 추가하세요:
pip install "pdfmux[ocr]" # RapidOCR — scanned/image pages (~200MB, CPU-only)
pip install "pdfmux[tables]" # Docling — table-heavy docs (~500MB)
pip install "pdfmux[opendataloader]" # OpenDataLoader — complex layouts (Java 11+)
pip install "pdfmux[llm]" # LLM fallback — Gemini, Claude, GPT-4o, Ollama
pip install "pdfmux[all]" # everythingPython 3.11 이상이 필요합니다.
빠른 시작
CLI
# zero config — just works
pdfmux convert invoice.pdf
# invoice.pdf -> invoice.md (2 pages, 95% confidence, via pymupdf4llm)
# RAG-ready chunks with token limits
pdfmux convert report.pdf --chunk --max-tokens 500
# cost-aware extraction with budget cap
pdfmux convert report.pdf --mode economy --budget 0.50
# schema-guided structured extraction (5 built-in presets)
pdfmux convert invoice.pdf --schema invoice
# BYOK any LLM for hardest pages
pdfmux convert scan.pdf --llm-provider claude
# batch a directory
pdfmux convert ./docs/ -o ./output/Python
import pdfmux
# text -> markdown
text = pdfmux.extract_text("report.pdf")
# structured data -> dict with tables, key-values, metadata
data = pdfmux.extract_json("report.pdf")
# RAG chunks -> list of dicts with token estimates
chunks = pdfmux.chunk("report.pdf", max_tokens=500)아키텍처
┌─────────────────────────────┐
│ Segment Detector │
│ text / tables / images / │
│ formulas / headers per page │
└─────────────┬───────────────┘
│
┌────────────────────────────────────────┐
│ Router Engine │
│ │
│ economy ── balanced ── premium │
│ (minimize $) (default) (max quality)│
│ budget caps: --budget 0.50 │
└────────────────────┬───────────────────┘
│
┌──────────┬──────────┬────────┴────────┬──────────┐
│ │ │ │ │
PyMuPDF OpenData RapidOCR Docling LLM
digital Loader scanned tables (BYOK)
0.01s/pg complex CPU-only 97.9% any provider
layouts TEDS
│ │ │ │ │
└──────────┴──────────┴────────┬────────┴──────────┘
│
┌────────────────────────────────────────┐
│ Quality Auditor │
│ │
│ 4-signal dynamic confidence scoring │
│ per-page: good / bad / empty │
│ if bad -> re-extract with next backend│
└────────────────────┬───────────────────┘
│
┌────────────────────────────────────────┐
│ Output Pipeline │
│ │
│ heading injection (font-size analysis)│
│ table extraction + normalization │
│ text cleanup + merge │
│ confidence score (honest, not inflated)│
└────────────────────────────────────────┘주요 설계 결정
추출기가 아닌 라우터. pdfmux는 PyMuPDF나 Docling과 경쟁하지 않습니다. 페이지별로 최적의 도구를 선택합니다.
에이전트 기반 다중 패스. 추출, 신뢰도 감사, 더 강력한 백엔드로 실패 항목 재추출을 수행합니다. 잘못된 페이지는 자동으로 재시도됩니다.
세그먼트 수준 감지. 각 페이지는 라우팅 전에 콘텐츠 유형(텍스트, 표, 이미지, 수식, 헤더)별로 분류됩니다.
4가지 신호 신뢰도. 문자 밀도, OCR 노이즈 비율, 표 무결성, 헤딩 구조를 통한 동적 품질 점수 산정. 하드코딩된 임계값이 아닙니다.
문서 캐시. 각 PDF는 추출기당 한 번이 아니라 전체 파이프라인에서 공유되어 한 번만 열립니다.
데이터 플라이휠. 로컬 텔레메트리가 문서 유형별로 어떤 추출기가 우수한지 추적합니다. 사용량이 늘어날수록 라우팅이 개선됩니다.
기능
기능 | 설명 | 명령어 |
제로 설정 추출 | 자동으로 최적의 백엔드로 라우팅 |
|
RAG 청킹 | 토큰 추정치를 포함한 섹션 인식 청크 |
|
비용 모드 | 예산 제한이 있는 economy / balanced / premium 모드 |
|
스키마 추출 | 5가지 내장 프리셋 (송장, 영수증, 계약서, 이력서, 논문) |
|
BYOK LLM | Gemini, Claude, GPT-4o, Ollama, 모든 OpenAI 호환 API |
|
벤치마크 | 설치된 모든 추출기를 정답 데이터와 비교 평가 |
|
Doctor | 설치된 백엔드, 커버리지 격차, 권장 사항 표시 |
|
MCP 서버 | AI 에이전트가 stdio 또는 HTTP를 통해 PDF 읽기 |
|
배치 처리 | 전체 디렉토리 변환 |
|
스트리밍 | 대용량 파일을 위한 제한된 메모리 페이지 반복 |
|
CLI 참조
pdfmux convert
pdfmux convert <file-or-dir> [options]
Options:
-o, --output PATH Output file or directory
-f, --format FORMAT markdown | json | csv | llm (default: markdown)
-q, --quality QUALITY fast | standard | high (default: standard)
-s, --schema SCHEMA JSON schema file or preset (invoice, receipt, contract, resume, paper)
--chunk Output RAG-ready chunks
--max-tokens N Max tokens per chunk (default: 500)
--mode MODE economy | balanced | premium (default: balanced)
--budget AMOUNT Max spend per document in USD
--llm-provider PROVIDER LLM backend: gemini | claude | openai | ollama
--confidence Include confidence score in output
--stdout Print to stdout instead of filepdfmux serve
AI 에이전트 통합을 위한 MCP 서버를 시작합니다.
pdfmux serve # stdio mode (Claude Desktop, Cursor)
pdfmux serve --http 8080 # HTTP modepdfmux doctor
pdfmux doctor
# ┌──────────────────┬─────────────┬─────────┬──────────────────────────────────┐
# │ Extractor │ Status │ Version │ Install │
# ├──────────────────┼─────────────┼─────────┼──────────────────────────────────┤
# │ PyMuPDF │ installed │ 1.25.3 │ │
# │ OpenDataLoader │ installed │ 0.3.1 │ │
# │ RapidOCR │ installed │ 3.0.6 │ │
# │ Docling │ missing │ -- │ pip install pdfmux[tables] │
# │ Surya │ missing │ -- │ pip install pdfmux[ocr-heavy] │
# │ LLM (Gemini) │ configured │ -- │ GEMINI_API_KEY set │
# └──────────────────┴─────────────┴─────────┴──────────────────────────────────┘pdfmux benchmark
pdfmux benchmark report.pdf
# ┌──────────────────┬────────┬────────────┬─────────────┬──────────────────────┐
# │ Extractor │ Time │ Confidence │ Output │ Status │
# ├──────────────────┼────────┼────────────┼─────────────┼──────────────────────┤
# │ PyMuPDF │ 0.02s │ 95% │ 3,241 chars │ all pages good │
# │ Multi-pass │ 0.03s │ 95% │ 3,241 chars │ all pages good │
# │ RapidOCR │ 4.20s │ 88% │ 2,891 chars │ ok │
# │ OpenDataLoader │ 0.12s │ 97% │ 3,310 chars │ best │
# └──────────────────┴────────┴────────────┴─────────────┴──────────────────────┘Python API
텍스트 추출
import pdfmux
text = pdfmux.extract_text("report.pdf") # -> str (markdown)
text = pdfmux.extract_text("report.pdf", quality="fast") # PyMuPDF only, instant
text = pdfmux.extract_text("report.pdf", quality="high") # LLM-assisted구조화된 추출
data = pdfmux.extract_json("report.pdf")
# data["page_count"] -> 12
# data["confidence"] -> 0.91
# data["ocr_pages"] -> [2, 5, 8]
# data["pages"][0]["key_values"] -> [{"key": "Date", "value": "2026-02-28"}]
# data["pages"][0]["tables"] -> [{"headers": [...], "rows": [...]}]RAG 청킹
chunks = pdfmux.chunk("report.pdf", max_tokens=500)
for c in chunks:
print(f"{c['title']}: {c['tokens']} tokens (pages {c['page_start']}-{c['page_end']})")스키마 가이드 추출
data = pdfmux.extract_json("invoice.pdf", schema="invoice")
# Uses built-in invoice preset: extracts date, vendor, line items, totals
# Also accepts a path to a custom JSON Schema file스트리밍 (제한된 메모리)
from pdfmux.extractors import get_extractor
ext = get_extractor("fast")
for page in ext.extract("large-500-pages.pdf"): # Iterator[PageResult]
process(page.text) # constant memory, even on 500-page PDFs유형 및 오류
from pdfmux import (
# Enums
Quality, # FAST, STANDARD, HIGH
OutputFormat, # MARKDOWN, JSON, CSV, LLM
PageQuality, # GOOD, BAD, EMPTY
# Data objects (frozen dataclasses)
PageResult, # page: text, page_num, confidence, quality, extractor
DocumentResult, # document: pages, source, confidence, extractor_used
Chunk, # chunk: title, text, page_start, page_end, tokens
# Errors
PdfmuxError, # base -- catch this for all pdfmux errors
FileError, # file not found, unreadable, not a PDF
ExtractionError, # extraction failed
ExtractorNotAvailable,# requested backend not installed
FormatError, # invalid output format
AuditError, # audit could not complete
)프레임워크 통합
LangChain
pip install langchain-pdfmuxfrom langchain_pdfmux import PDFMuxLoader
loader = PDFMuxLoader("report.pdf", quality="standard")
docs = loader.load() # -> list[Document] with confidence metadataLlamaIndex
pip install llama-index-readers-pdfmuxfrom llama_index.readers.pdfmux import PDFMuxReader
reader = PDFMuxReader(quality="standard")
docs = reader.load_data("report.pdf") # -> list[Document]MCP 서버 (AI 에이전트)
mcpservers.org에 등록되어 있습니다. 한 줄 설정:
{
"mcpServers": {
"pdfmux": {
"command": "npx",
"args": ["-y", "pdfmux-mcp"]
}
}
}또는 Claude Code를 통해:
claude mcp add pdfmux -- npx -y pdfmux-mcp노출된 도구: convert_pdf, analyze_pdf, extract_structured, get_pdf_metadata, batch_convert.
BYOK LLM 구성
pdfmux는 5줄의 YAML로 모든 LLM을 지원합니다. 직접 키를 가져오세요. 구성하지 않는 한 데이터는 기기 밖으로 나가지 않습니다.
# ~/.pdfmux/llm.yaml
provider: claude # gemini | claude | openai | ollama | any OpenAI-compatible
model: claude-sonnet-4-20250514
api_key: ${ANTHROPIC_API_KEY}
base_url: https://api.anthropic.com # optional, for custom endpoints
max_cost_per_page: 0.02 # budget cap지원되는 제공업체:
제공업체 | 모델 | 로컬? | 비용 |
Gemini | 2.5 Flash, 2.5 Pro | 아니오 | ~$0.01/페이지 |
Claude | Sonnet, Opus | 아니오 | ~$0.015/페이지 |
GPT-4o | GPT-4o, GPT-4o-mini | 아니오 | ~$0.01/페이지 |
Ollama | 모든 로컬 모델 | 예 | 무료 |
사용자 지정 | 모든 OpenAI 호환 API | 구성 가능 | 가변 |
벤치마크
opendataloader-bench에서 테스트됨 -- 재무 보고서, 법률 문서, 학술 논문, 스캔 문서 등 200개의 실제 PDF 대상.
엔진 | 전체 | 읽기 순서 | 표 (TEDS) | 헤딩 | 요구 사항 |
opendataloader hybrid | 0.909 | 0.935 | 0.928 | 0.828 | API 호출 ($) |
pdfmux | 0.905 | 0.920 | 0.911 | 0.852 | CPU 전용, $0 |
docling | 0.877 | 0.900 | 0.887 | 0.802 | ~500MB 모델 |
marker | 0.861 | 0.890 | 0.808 | 0.796 | GPU 권장 |
opendataloader local | 0.844 | 0.913 | 0.494 | 0.761 | CPU 전용 |
mineru | 0.831 | 0.857 | 0.873 | 0.743 | GPU + ~2GB 모델 |
전체 2위, 무료 도구 중 1위. 유료 1위 점수의 99.5%를 페이지당 비용 없이 달성. 테스트된 모든 엔진 중 최고의 헤딩 감지 성능. 이미지 표 OCR은 이미지로 삽입된 표를 추출합니다.
신뢰도 점수
모든 결과에는 4가지 신호 신뢰도 점수가 포함됩니다:
95-100% -- 깨끗한 디지털 텍스트, 완전 추출 가능
80-95% -- 양호한 추출, 일부 페이지에 경미한 OCR 노이즈
50-80% -- 부분 추출, 일부 페이지 복구 불가
<50% -- 상당한 콘텐츠 누락, 경고 포함
신뢰도가 80% 미만으로 떨어지면 pdfmux는 무엇이 잘못되었는지, 어떻게 수정해야 하는지 정확히 알려줍니다:
Page 4: 32% confidence. 0 chars extracted from image-heavy page.
-> Install pdfmux[ocr] for RapidOCR support on 6 image-heavy pages.비용 모드
모드 | 동작 | 일반적인 비용 |
economy | 규칙 기반 백엔드만 사용. LLM 호출 없음. | $0/페이지 |
balanced | 규칙 기반 추출에 실패한 페이지에만 LLM 사용. | 평균 ~$0.002/페이지 |
premium | 최대 품질을 위해 모든 페이지에 LLM 사용. | ~$0.01/페이지 |
엄격한 예산 제한 설정: --budget 0.50은 문서당 지출이 $0.50에 도달하면 LLM 호출을 중단합니다.
왜 pdfmux인가?
pdfmux는 또 다른 PDF 추출기가 아닙니다. 페이지별로 올바른 추출기를 선택하고, 결과를 검증하며, 실패 시 재시도하는 오케스트레이션 계층입니다.
도구 | 장점 | 한계 |
PyMuPDF | 빠른 디지털 텍스트 | 스캔본이나 이미지 레이아웃 처리 불가 |
Docling | 표 (97.9% 정확도) | 표가 아닌 문서에서 느림 |
Marker | GPU ML 추출 | GPU 필요, 디지털 PDF에는 과함 |
Unstructured | 엔터프라이즈 플랫폼 | 복잡한 설정, 유료 티어 |
LlamaParse | 클라우드 네이티브 | API 키 필요, 로컬 아님 |
Reducto | 높은 정확도 | $0.015/페이지, 비공개 소스 |
pdfmux | 위의 모든 것을 오케스트레이션 | 페이지별 라우팅, 감사, 재추출 |
오픈 소스 Reducto 대안: 다른 곳에서 페이지당 $0.015가 드는 작업이 pdfmux의 규칙 기반 백엔드로는 무료이며, BYOK LLM 폴백 사용 시 평균 ~$0.002/페이지입니다.
개발
git clone https://github.com/NameetP/pdfmux.git
cd pdfmux
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest # 151 tests
ruff check src/ tests/
ruff format src/ tests/기여
저장소 포크
브랜치 생성 (
git checkout -b feature/your-feature)새로운 기능에 대한 테스트 작성
pytest및ruff check통과 확인PR 열기
라이선스
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/NameetP/pdfmux'
If you have feedback or need assistance with the MCP directory API, please join our Discord server