
Я разрабатывал PDF Craft, чтобы превращать сканы книг в Markdown или EPUB, которые действительно удобно читать, искать и упорядочивать. Одного распознавания букв недостаточно. Цифра, обведённый знак или звёздочка в основном тексте должны по-прежнему вести к нужному примечанию внизу исходной страницы. Иначе текст приспосабливается к экрану, но важная для чтения связь пропадает.
Это особенно заметно при работе со старыми книгами, научными источниками и личной библиотекой. Полезный результат должен позволять искать и копировать текст, читать на небольшом экране и находить полное примечание по знаку в тексте. Для проверки образца пригодятся руководство по переводу скана PDF в EPUB и список проверок формул и сносок.
OCR распознаёт символы, но не их роль
OCR видит слова на странице, но не всегда понимает их назначение в книге. Мелкий текст внизу может быть сноской или продолжением основного абзаца. Обведённая цифра может обозначать ссылку или пункт списка. Одно примечание бывает разбито на два блока или продолжается на следующей странице.
Достаточно ошибиться в одной связи, и в EPUB появятся странности: знак без примечания, две слипшиеся сноски, номер страницы внутри предложения или конец абзаца, присоединённый к колонтитулу следующей страницы. Сноски давно остаются одной из самых трудных задач PDF Craft.
Первая попытка: пусть LLM прочитает каждую страницу
Около года назад самым прямым решением казалось передать каждую страницу большой языковой модели. Она часто могла понять, что мелкий текст поясняет основной, распознать звёздочку или римскую цифру как знак сноски и по контексту определить, продолжается ли предложение после перелистывания.
На отдельной странице это выглядело многообещающе, но длинная книга означала сотни вызовов, ожиданий и возможных повторов. Для проверки переходов между страницами приходилось добавлять соседний текст, увеличивая ввод. Большинство страниц уже были верными: дорогая модель перечитывала их лишь для ответа «исправлять нечего». Пользователю было трудно понять, идёт ли обработка или застряла.
Сначала построить полный детерминированный процесс
В следующих версиях основная работа снова легла на OCR и определённые правила. Процесс отделяет основной текст от примечаний, собирает абзацы, разбивает сноски на отдельные записи и сопоставляет знаки в тексте с нужными примечаниями. Он быстр, стабилен, воспроизводим и хорошо работает на большинстве страниц.
Но оформление книг сильно различается. Сноски стоят внизу или между колонками, знаки бывают цифрами и символами, колонтитулы и номера страниц попадают в распознанный текст. Некоторые исключения требуют понимания смысла предложения. Одних правил не хватает для редких случаев, а LLM на каждой странице слишком медленна и дорога.
Поворот: JEV проверяет, а не переделывает
Существующий процесс не нужно было заменять. Ему требовалась быстрая проверка качества, способная выбрать сомнительные страницы. Я задаю JEV узкий вопрос: Можно ли принять анализ этой страницы без изменений? JEV не переписывает текст и не объясняет каждую сноску. Он возвращает вероятность, по которой страница либо идёт дальше, либо отправляется LLM на исправление.
Проверяется вся страница, а не только уже найденные сноски. Если алгоритм полностью пропустил примечание, проверка известных записей ничего не обнаружит. Оценка страницы всё ещё может заметить отсутствующую ссылку, неверную принадлежность, странный переход между страницами или номер страницы внутри абзаца. Лучше отправить на проверку несколько лишних страниц, чем пропустить ошибку в готовый EPUB: ложная тревога стоит дополнительного обращения к модели, пропуск портит результат. Порог ещё нужно настраивать на большем числе примеров.
flowchart TB
accTitle: От проверки страницы к ограниченному исправлению
accDescr: OCR и правила сначала обрабатывают страницу. JEV решает, можно ли принять её без изменений. Сомнительную страницу исправляет LLM, затем программа проверяет целостность. Неудачная попытка повторяется.
A[OCR и правила] --> B{JEV: страница надёжна?}
B -- Да --> F[Сборка глав и вывод]
B -- Нет --> C[LLM исправляет только эту страницу]
C --> D{Проверка целостности}
D -- Принято --> F
D -- Повторить --> C
LLM исправляет страницу в строгих границах
Для отмеченной страницы LLM получает текстовую структуру трёх последовательных страниц: предыдущей, текущей и следующей. Менять разрешено только среднюю. Соседние помогают понять предложения, которые переходят через границу. На этом этапе я не передаю изображения: OCR уже сохранил текст, координаты и расположение элементов. Требуется смысловое исправление, а не повторное распознавание.
Модель может заново пометить основной текст, сноски и номера страниц, поправить соединение абзацев и соответствие знаков примечаниям. Она не может свободно переписывать оригинал или менять структуру страницы. Затем программа проверяет порядок индексов сносок, соответствие ссылок и примечаний, согласованность соединений на обеих сторонах границы и возможность однозначно найти знак в указанном тексте. При ошибке модель получает конкретные замечания и должна вернуть полный результат снова. Сокращение числа повторов не оправдывает ослабления проверок.
Что показал образец из 26 страниц
В тестовом PDF на 26 страниц с большим количеством сносок JEV выбрал 6 страниц для LLM. Все шесть первых ответов прошли проверку целостности, а 22 уже верных соответствия между ссылками в тексте и примечаниями сохранились.
Исправления были небольшими, но важными: печатные номера страниц ошибочно считались основным текстом; один из них ложно связывал два абзаца; вводное предложение слилось со следующей цитатой с отступом. Модель разделила их по смыслу и отступу.
Это наблюдение по одному образцу, а не показатель общей точности или стоимости. Хорошее исправление сохраняет то, что уже верно, и меняет лишь проблемы, подтверждённые признаками ошибки.
Тратить дорогую проверку там, где она нужна
Правила выполняют большинство однозначных задач; JEV быстро выбирает подозрительные страницы; LLM разбирает редкие случаи, требующие понимания смысла; программные ограничения защищают итоговую структуру. Исправленные страницы возвращаются в тот же процесс сборки глав и вывода Markdown или EPUB.
Предстоит проверить больше языков, вариантов вёрстки и длинных книг, особенно частоту ошибок, которые JEV пропускает, и порог отправки в LLM. Но теперь ради нескольких ошибок на полях не нужно заставлять модель читать книгу от первой до последней страницы. Если вы преобразуете скан своей книги, начните с небольшого файла со сносками в PDF Craft и проверьте знаки, полный текст примечаний и абзацы на границе страниц.

