Multimodal AI: text, images and mixed inputs
When to use a VLM and when classic OCR, how to build structured extraction from images with per-field confidence, without mixing what was read with what was guessed.
Lesson content is currently available in Russian.
What you will learn
- →Выбирать пайплайн под задачу: VLM, OCR или их комбинация с cross-check.
- →Делать structured extraction из изображений с confidence и источником по каждому полю.
- →Проектировать uncertainty UX: пороги авто-принятия и очередь ручного review.
Модальности: что изображение может и не может
Vision-language модели (VLM) принимают изображения в том же контексте, что и текст, — картинка кодируется в токены и занимает место в окне. Практические следствия:
- Изображение стоит токенов, и цена зависит от разрешения: провайдеры режут картинку на тайлы, каждый тайл — сотни токенов. Режим low detail дешевле на порядок, но мелкий текст в нём нечитаем. Для документов почти всегда нужен high detail.
- Даунскейл убивает данные. Провайдер сжимает изображения до предельного размера; фото договора на 12 мегапикселей после сжатия теряет мелкий шрифт сносок. Правило: перед отправкой кадрируйте значимую область сами, вместо того чтобы отправлять целый разворот и надеяться.
- VLM видит «в целом», а не «по пикселям». Она отлично отвечает, что на изображении счёт-фактура, кто поставщик и какова структура таблицы. Но чтение длинных последовательностей символов — серийников, IBAN, мелких цифр — область, где она систематически ошибается, причём ошибается правдоподобно.
Ключевая ментальная модель: VLM — это модель рассуждения об изображении, а не измерительный прибор. Она интерполирует: размытую цифру «дочитает» до наиболее вероятной, отрезанную строку — до типичной. Для описания, классификации, понимания структуры это сила. Для точного извлечения критичных значений — риск, который закрывается архитектурой пайплайна, а не просьбой «читай внимательнее» в промпте.
OCR против VLM reasoning
Разделяйте два режима работы с изображением документа, потому что у них разные инструменты и разные гарантии:
- Буквальное чтение (сумма, ИНН, номер счёта, дата): нужна точность посимвольно. Здесь работает специализированный OCR (Tesseract, облачные document-API) — он честнее в своей неуверенности: нечитаемый символ даст мусор или низкий confidence score, но не «красивую» подмену. VLM в этой роли опасна именно правдоподобием ошибок: 8 превращается в 3, размытые копейки — в круглую сумму, и результат выглядит нормально.
- Понимание (что это за документ, где в нём таблица позиций, к чему относится эта сумма): здесь VLM вне конкуренции — классический OCR даёт плоский текст без семантики.
Сильнейший продовый паттерн — комбинация: OCR извлекает сырой текст с координатами и per-символьным confidence, VLM получает и изображение, и OCR-текст, и раскладывает данные по смысловой структуре. Расхождение между OCR и VLM по одному полю — это сигнал для review, а совпадение из двух независимых источников — сильное свидетельство корректности.
И самый дешёвый детектор ошибок — арифметический cross-check: в финансовых документах числа связаны (сумма позиций = итог, цена × количество = стоимость строки, итог с НДС сходится со ставкой). Проверка — три строки кода, а ловит она значительную долю ошибок чтения. Не сошлось — поле помечается и уходит на review, независимо от того, насколько уверенно его прочитали. Документ, в котором цифры не бьются, не должен проходить автоматом никогда.
Structured extraction с confidence по полям
Extraction из изображения — это structured output из урока 2 плюс два обязательных дополнения: confidence и источник по каждому полю, а не по документу в целом. Усреднённый confidence бесполезен: «0.9 по документу» не говорит, что именно сумма прочитана с 0.4.
{
"vendor": { "value": "ООО Ромашка", "confidence": 0.98, "source": "vlm" },
"total": { "value": 12500.00, "confidence": 0.95, "source": "ocr+vlm" },
"date": { "value": "2026-03-14", "confidence": 0.71, "source": "vlm" },
"iban": { "value": null, "confidence": 0.0, "source": "none" },
"checks": { "lineItemsSumMatchesTotal": true }
}
Что здесь важно:
- source различает происхождение: ocr (буквально прочитано), vlm (понято моделью), ocr+vlm (два источника сошлись — максимальное доверие), inferred (выведено, а не прочитано: «валюта — рубли, потому что ИНН российский»). Inferred-поля — отдельный класс: они могут быть верными, но обязаны быть помечены.
- null с confidence 0 — честный ответ «в документе этого нет или нечитаемо». Тот же принцип nullable, что и в текстовом extraction: пропуск не заполняется правдоподобием.
- Блок checks — результаты cross-валидаций, вычисленных кодом, не моделью.
В промпте требуйте различать «прочитал» и «предположил» явно, и дайте few-shot пример с нечитаемым полем → null. Без такого примера модель будет стабильно «дочитывать» всё до конца — она обучена быть полезной, а не осторожной.
Uncertainty UX и петля human review
Per-field confidence нужен не для красоты — он приводит в действие маршрутизацию:
- Выше верхнего порога (например, 0.9 при сошедшихся cross-check): авто-принятие без человека.
- Средняя зона: документ проходит, но неуверенные поля подсвечены в UI, и пользователь подтверждает именно их — не перепечатывает весь документ.
- Ниже нижнего порога, или провален cross-check, или критичное поле null: очередь ручного review целиком.
Пороги — не константы из головы: они подбираются по размеченной выборке под целевую цену ошибки. Для оплаты счёта ложное авто-принятие стоит дорого — порог высокий, пусть даже 40% документов идёт на review. Для тегирования фотографий в архиве — наоборот. Это продуктовое решение с явной ценой в обе стороны: точность против доли ручного труда.
В интерфейсе review показывайте не голый JSON, а изображение рядом с извлечёнными полями, в идеале — с подсветкой области, откуда взято значение (координаты даёт OCR). Оператор проверяет глазами за секунды то, что без подсветки искал бы минуту. Поля с source: inferred помечаются отдельно — их проверка требует другого действия (подумать), чем сверка цифр (посмотреть).
И замкните петлю: каждое ручное исправление — это бесплатный размеченный кейс. Пары «что извлекла система → что поставил человек» стекают в golden set мультимодального пайплайна; рост доли исправлений по конкретному полю — сигнал деградации промпта, смены формата входящих документов или проблемы источника изображений (новый сканер, новый шаблон поставщика). Команды, выбрасывающие эти данные, платят за разметку дважды.
Practice
Receipt parser с review-очередью
Соберите парсер чека или счёта: вход — изображение, выход — JSON с value/confidence/source по каждому полю, арифметический cross-check суммы позиций против итога, маршрутизация по порогам (авто / подтверждение полей / полный review). Прогоните минимум 10 реальных чеков, включая один размытый и один с отрезанным краем.
Deliverable
Проверяемый JSON с per-field confidence и source, работающий cross-check, демонстрация трёх маршрутов на разных чеках и список полей, ушедших на review, с причинами.
Checkpoint
Какие поля в вашем ответе были прочитаны из картинки, какие интерпретированы, и как это видит пользователь?
- ✓ Факты (ocr/vlm-прочитанное) и интерпретации (inferred) разделены на уровне схемы, а не на словах.
- ✓ Есть per-field confidence, арифметический cross-check и явный null для нечитаемого.
- ✓ Пользователь видит, какие поля требуют его подтверждения, и ручные исправления собираются в golden set.
Check yourself
Sources