Skip to main content
Glama

pdfmux

CI PyPI Python 3.11+ License: MIT Downloads

Универсальный оркестратор извлечения данных из PDF. Направляет каждую страницу на лучший бэкенд, проверяет результат, повторно извлекает данные при сбоях. 5 экстракторов на основе правил + резервный LLM (BYOK). Один 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]"            # everything

Требуется Python 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 открывается один раз, а не по разу для каждого экстрактора. Общий доступ для всего конвейера.

  • Маховик данных. Локальная телеметрия отслеживает, какие экстракторы лучше справляются с определенными типами документов. Маршрутизация улучшается по мере использования.

Функции

Функция

Что делает

Команда

Извлечение без настройки

Автоматически направляет на лучший бэкенд

pdfmux convert file.pdf

RAG-чанкинг

Чанки с учетом разделов и оценкой токенов

pdfmux convert file.pdf --chunk --max-tokens 500

Режимы стоимости

эконом / сбалансированный / премиум с лимитами бюджета

pdfmux convert file.pdf --mode economy --budget 0.50

Извлечение по схеме

5 встроенных пресетов (счет, чек, договор, резюме, статья)

pdfmux convert file.pdf --schema invoice

BYOK LLM

Gemini, Claude, GPT-4o, Ollama, любой API, совместимый с OpenAI

pdfmux convert file.pdf --llm-provider claude

Бенчмарк

Оценка всех установленных экстракторов относительно эталона

pdfmux benchmark

Доктор

Показ установленных бэкендов, пробелов в покрытии, рекомендаций

pdfmux doctor

MCP-сервер

ИИ-агенты читают PDF через stdio или HTTP

pdfmux serve

Пакетная обработка

Конвертация целых директорий

pdfmux convert ./docs/

Потоковая передача

Итерация страниц с ограниченной памятью для больших файлов

for page in ext.extract("500pg.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 file

pdfmux serve

Запуск MCP-сервера для интеграции с ИИ-агентами.

pdfmux serve              # stdio mode (Claude Desktop, Cursor)
pdfmux serve --http 8080  # HTTP mode

pdfmux 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-pdfmux
from langchain_pdfmux import PDFMuxLoader

loader = PDFMuxLoader("report.pdf", quality="standard")
docs = loader.load()  # -> list[Document] with confidence metadata

LlamaIndex

pip install llama-index-readers-pdfmux
from llama_index.readers.pdfmux import PDFMuxReader

reader = PDFMuxReader(quality="standard")
docs = reader.load_data("report.pdf")  # -> list[Document]

MCP-сервер (ИИ-агенты)

Список доступен на 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 поддерживает любой LLM через 5 строк YAML. Используйте свои ключи — ничего не покидает вашу машину, если вы не настроите это специально.

# ~/.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

Любая локальная модель

Да

Бесплатно

Custom

Любой API, совместимый с OpenAI

Настраиваемо

Разная

Бенчмарк

Протестировано на 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

~500МБ модели

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 + ~2ГБ модели

№2 в общем зачете, №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 остановит вызовы LLM, когда расходы достигнут $0.50 на документ.

Почему pdfmux?

pdfmux — это не очередной экстрактор PDF. Это уровень оркестрации, который выбирает правильный экстрактор для каждой страницы, проверяет результат и повторяет попытки при сбоях.

Инструмент

В чем хорош

Ограничение

PyMuPDF

Быстрый цифровой текст

Не работает со сканами или сложной версткой

Docling

Таблицы (точность 97.9%)

Медленный на документах без таблиц

Marker

GPU ML извлечение

Нужен GPU, избыточен для цифровых PDF

Unstructured

Корпоративная платформа

Сложная настройка, платные уровни

LlamaParse

Облачный

Требует API ключи, не локальный

Reducto

Высокая точность

$0.015/стр, закрытый код

pdfmux

Оркестрирует все вышеперечисленное

Маршрутизирует по страницам, проверяет, переизвлекает

Альтернатива Reducto с открытым кодом: то, что стоит $0.015/стр в других местах, бесплатно с бэкендами pdfmux на основе правил, или ~$0.002/стр в среднем с резервным LLM (BYOK).

Разработка

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/

Вклад в проект

  1. Сделайте форк репозитория

  2. Создайте ветку (git checkout -b feature/your-feature)

  3. Напишите тесты для новой функциональности

  4. Убедитесь, что pytest и ruff check проходят

  5. Откройте PR

Лицензия

MIT

Install Server
A
security – no known vulnerabilities
A
license - permissive license
A
quality - A tier

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