PDF — это визуальный формат. Он хранит инструкции, где рисовать символы на странице. Спецификация поддерживает Tagged PDF — специальное дерево структуры, которое помечает заголовки, абзацы, списки. Им пользуются в госсекторе и издательских пайплайнах. Но большинство PDF, с которыми вы сталкиваетесь, не имеют тегов. LaTeX, печать в PDF из Chrome, почти все инструменты экспорта теги не ставят. В итоге вы получаете только координаты и размеры шрифта. Экстракторы текста читают команды рисования слева направо, сверху вниз и надеются на лучшее.
Раньше это не имело значения — читали только люди. Но теперь большинство PDF попадает в LLM. Мы загружаем их в ChatGPT, просим Claude сделать саммари, прогоняем через парсеры. И все эти инструменты борются с одной проблемой: восстановить структуру из формата, который её никогда не нёс. LLM видит строку вроде «Project Alpha\nLed a team of 5 engineers\nto deliver the» и угадывает, где заголовок, а где продолжение предложения. Иногда угадывает правильно. Часто — нет.
Автор решил сделать PDF, в котором человек видит отформатированный документ, а машина извлекает чистый markdown. Один файл, никакого нового расширения. Просто .pdf.
Спецификация PDF с версии 1.4 (2001 год) поддерживает свойство, которое позволяет задать замещающий текст для помеченного содержимого. Рендереры его игнорируют — они рисуют то, что написано в потоке контента. Но экстракторы текста, которые поддерживают это свойство, возвращают замещающий текст вместо визуального. В тестах PyMuPDF и Poppler его учитывали. Поддержка разная в зависимости от инструмента и версии, но основные открытые экстракторы с ним работают.
Свойство задумывалось для лигатур и символов, которые не отображаются в Unicode — например, визуальный глиф «fi» должен извлекаться как два символа «f» и «i». Для более крупных задач его не использовали. Автор применяет его на уровне всего документа: через последовательности помеченного контента к потоку данных прикрепляется замещающий текст. Экстракторы, поддерживающие свойство, возвращают структурированный markdown вместо сырого визуального текста. PDF выглядит одинаково — один файл выдаёт два совершенно разных результата в зависимости от того, кто его читает.
Тесты подтверждают: обычный PDF при извлечении теряет иерархию, ломает строки на середине, не отличает маркеры списков от абзацев, таблицы превращает в набор строк. «Умный» PDF выдаёт чистый markdown с #, ##, таблицами и маркированными списками — LLM не приходится гадать. Замеры токенов через tiktoken (cl100k_base) показали, что разница в их количестве незначительна (от -8.5% до +15.7%). Выигрыш не в сокращении, а в том, что те же самые токены теперь несут структуру.
Загрузка таких PDF в ChatGPT и Claude — обе модели вернули именно тот markdown, который был встроен, включая элементы форматирования, которые никакой эвристический анализ разметки не воспроизвёл бы в точности. Получается адаптивный документ: человек видит обычный отформатированный PDF, машина — чистую структуру. Один файл, никаких конвертаций. Автор сейчас работает над расширением для Google Docs, чтобы упростить создание таких документов.