Коротко
Автор описывает ScanReader — конвейер, который извлекает сведения из сканов российских юридических документов с помощью VLM, а затем проверяет их детерминированными правилами. Его цель — не обещать безошибочность, а отсеивать сомнительные документы и направлять человеку только исключения до формирования реестров для 1С.
Контекст
Автор — разработчик ScanReader, открытого Python-проекта, созданного для внутреннего контура обработки конфиденциальных документов. Начальная задача возникла из-за расхождений и ошибок в уже использовавшемся распознавателе; решение должно было работать без передачи документов наружу и поддерживать конкретные российские юридические и бухгалтерские форматы. Проект сейчас используется в production и тестируется коллегами.
Главное
- Проект ScanReader опубликован как открытый Python-проект по лицензии MIT: github.com/Riper21/ScanReader.
- Поддерживаются девять категорий документов; типы реализованы изолированными плагинами, поэтому новое расширение добавляется без зашивания логики типа в ядро.
- Стек: Python 3.9+, Pydantic v2, Pillow/PyMuPDF, openpyxl и опциональный rapidocr; модели подключаются через OpenAI-совместимый API.
- Эвристики классификации по именам и якорям обработали 53,7% файлов с грязными названиями вроде Скан0001.pdf и IMG_20240115_143022.jpg; автор сообщает об одном misroute.
- Изображения ниже 1500 px апскейлятся в 2 раза Lanczos; обработка PDF ограничена 20 страницами, а пропуск более поздних страниц показывается в отчёте.
- Проверки контрольных разрядов учитывают специальные случаи: например, исторические номера СНИЛС до 1998 года и исключения для отдельных счетов ГРКЦ и казначейских БИК УФК.
- Арифметические и юридические проверки охватывают суммы, хронологию документов и лимиты удержаний: 50% и 70% по ст. 99 229-ФЗ, 20% по ст. 138 ТК РФ, а также дроби 1/4, 1/3, 1/2 и 2/3; отдельно учитывается исключение по 314-ФЗ для возмещения вреда здоровью.
- Кросс-модальный гейт сверяет поля с текстом документа, учитывая склонение русских фамилий и числовое представление сумм; десятикратное расхождение, например 507500 вместо 5 075,00, должно выявляться.
- Статусы включают zero_trust_verified, partially_verified, gate_not_executed, discrepancy_detected, heuristic_fallback и ocr_low_confidence; «100% подтверждено» система не должна заявлять.
- Ложные срабатывания на тестовом стенде выросли с 0% при чистом эталонном тексте до 89,1% при 10% ошибок; это означает, что ухудшение OCR повышает нагрузку на ручную проверку.
Как сделано
Пакетный процесс проходит шесть этапов: подготовка окружения, поиск файлов, классификация, извлечение данных, расчёт метрик и выпуск реестров с Excel. Классификатор сначала использует бесплатные эвристики по имени файла и текстовым якорям, а затем при необходимости обращается к VLM. Низкое разрешение апскейлится в 2 раза методом Lanczos; PDF ограничивается первыми 20 страницами. Извлечение организовано плагинами с промптом и Pydantic-схемой; постобработка исправляет типовые ошибки формата, а JSON модели безопасно разбирается с удалением лишних рассуждений. Поддерживается любая модель через OpenAI-совместимый API, в том числе корпоративный шлюз или локальные Ollama/vLLM; при разработке автор проверял проект с Ollama и Qwen2.5-VL.
Затем срабатывают четыре уровня контроля: контрольные суммы ИНН, СНИЛС, ОГРН/ОГРНИП, БИК и банковских счетов с учётом исключений; арифметика сумм, временная последовательность документов и юридические ограничения удержаний; сверка критичных полей с текстовым слоем, независимым OCR или транскрипцией той же модели (с пометкой, что последняя проверка не независима); и статус, который сообщает оператору, какие проверки прошли и что делать дальше. Выходы — JSON с аудитом (_Full), плоская запись для 1С (Flat), общий RegistryFull.json и Excel. CLI возвращает коды 0 для чистого результата, 3 для расхождения или невыполненного гейта, 4 для эвристического восстановления и 1 при сбое.
Результаты
Заявлена поддержка девяти типов документов, включая постановления ФССП, исполнительные документы, документы об удержаниях, УПД, договоры и акты. Эвристический первый этап классификации распознал 53,7% файлов с неинформативными именами; зафиксирован один misroute. На стенде из 23 эталонов измерялись ложные срабатывания кросс-модального гейта: 0% на чистом тексте, 21,5% при 1% ошибок, 38,5% при 2%, 73,5% при 5% и 89,1% при 10%. На каждом уровне было 460 проверок и 20 повторов. Автор подчёркивает, что шум вносили только в эталонный текст, то есть измерялся сценарий, когда OCR ошибается, а извлечение верно. В проекте указаны 667 автотестов и покрытие 73,5% при пороге 70%; 0.8.0 содержала 75 тестов. Система маркирует проблемы для ручной проверки, а автоимпорт предназначен только для чистых документов.
Ограничения
Измерения внутренние, а не сравнение с другими системами; выборка мала: 23 эталона, причём у шести из девяти типов был всего один документ. Результаты ложных срабатываний относятся к конкретному синтетическому сценарию и не доказывают точность на реальных потоках. При высоком уровне ошибок в тексте гейт часто отправляет корректные документы человеку. PDF длиннее 20 страниц обрезается: пример с 45 страницами потерял реквизиты с 31-й страницы, хотя ограничение отражается в отчёте. Низкое разрешение не гарантирует читаемость даже после апскейла. Статус zero_trust_verified означает только прохождение применимых проверок, а не абсолютную корректность; OCR/транскрипция той же VLM не является независимым подтверждением. Автор не обещает замену бухгалтера или работу на любом скане. Скорость обработки внутри периметра ниже привычной для подписных облачных сервисов; стоимости и количественной оценки производительности в статье нет.
Что взять себе
- Используйте VLM как инструмент извлечения предложений, а не как источник истины: реквизиты, суммы и правовые ограничения можно проверить отдельными алгоритмами.
- Разделяйте статусы «проверки пройдены» и «данные гарантированно верны»; не превращайте процентный показатель качества модели в обещание точности.
- Если сверка опирается на OCR, измеряйте, как ошибки OCR влияют на долю ложных тревог и объём ручной работы.
- Для конфиденциальных документов можно строить модельно-независимую архитектуру с локальным или внутренним OpenAI-совместимым API.
- Учитывайте ограничения входных файлов явно: лимит страниц и недостаточное разрешение должны приводить к видимому предупреждению, а не к молчаливому пропуску данных.
Читать оригинал, если…
Откройте оригинал, если нужны исходный код ScanReader, точные правила верификации, таблицы измерений, примеры интеграции с 1С или подробности регрессионных исправлений.