Я делаю сканер состава продуктов: наводишь камеру на штрихкод, получаешь светофор и короткую фразу, почему так. Про то, как считается балл, писал раньше. Сегодня про метрику, которую я долго не хотел смотреть в глаза.
Каждое утро мне падает сводка. Вот сегодняшняя: сканов за сутки 27, вердикты — зелёных 5, жёлтых 9, красных 3, нет данных 10.
Десять из двадцати семи. Тридцать семь процентов сканирований заканчиваются тем, что человек навёл камеру и не получил ничего. Не “продукт плохой”, не “продукт нормальный” — пустота. Для продукта, вся ценность которого в ответе за секунду, это худший из возможных исходов. Красный вердикт хотя бы полезен. “Нет данных” — это просто потраченное время пользователя.
Откуда берётся дыра. В базе 112 тысяч карточек. Звучит солидно, пока не посчитаешь, сколько на самом деле SKU в рознице. У одной крупной сети ассортимент — десятки тысяч позиций, и большая часть из них — собственные торговые марки, которых нет ни в одном открытом источнике. Плюс регионалка, плюс сезонка, плюс ротация: поменяли рецептуру — сменился штрихкод. То есть 112 тысяч — это не “почти всё”, а тонкий слой поверх очень длинного хвоста.
Что сделали: OCR как запасной путь. Логика простая: если штрихкод не нашёлся, предлагаем сфотографировать состав. Распознаём текст, парсим ингредиенты, считаем тот же светофор и, если всё сошлось, записываем товар в базу. Следующий человек с этим же продуктом получит мгновенный ответ.
Идея красивая. Реальность: всего OCR-вкладов 474, одобрено автоматически 256, отклонено 184, ушло на ручную модерацию 34. Тридцать девять процентов отсекается. Почему отсекается. Топ причин за неделю выглядит скучно, но объясняет всё.
barcode_known — товар уже есть в базе, человек сфотографировал состав того, что и так распознаётся. Это не ошибка пользователя, это наш недосмотр в интерфейсе. no_sostav_word — на фото не нашлось слова “состав”. Чаще всего это значит, что сняли лицевую сторону упаковки или такой угол, где распознался один БЖУ.
Соблазн понятный: снизить планку, принимать всё подряд, и дыра закроется сама. Проблема в том, что база с мусором хуже пустой базы. Покажу один раз состав от другого товара — человек больше не вернётся, и правильно сделает. Поэтому модерация автоматическая и злая: не нашли ключевые маркеры состава — отклоняем. Робот ходит раз в час, очередь обычно пустая.
Что с этим делать дальше. Есть три направления, и все три недоделаны.
Первое — не показывать “нет данных” как тупик. Сейчас это конец пути, а должно быть началом: сразу предлагать фото состава, одним касанием, без выхода в меню. Судя по barcode_known, человек и так пытается что-то сфотографировать, только не то и не там.
Второе — снижать порог входа в OCR: подсказывать, где искать состав на упаковке, ловить угол, подсвечивать рамкой. Скучная работа, но именно она превращает 39% отказов во что-то приличное.
Третье — источники данных. Мы подавались в реестр партнёров Честного знака ради доступа к Национальному каталогу. Отказали: “компания имеет крайне низкие финансовые показатели”. Формально не поспоришь, мы небольшая ИТ-компания без внешних денег. Только получается замкнутый круг: чтобы данные были хорошие, нужен доступ; чтобы был доступ — нужны обороты; чтобы были обороты — нужны хорошие данные.
Зачем я это пишу. Мне кажется, “нет данных” — это метрика, которую в подобных продуктах прячут по умолчанию. Показывают охват базы (“112 тысяч товаров!”), а не долю неудачных сканов. Между тем именно вторая цифра говорит, работает продукт или нет. Если вы делали что-то похожее — распознавание текста с упаковок, пополнение базы силами пользователей, автомодерацию таких вкладов — расскажите, где у вас проходит граница между “принять с риском” и “отклонить и потерять данные”. У меня она сейчас проведена интуитивно, и я не уверен, что правильно.
Кто захочет посмотреть, как это выглядит: справочник добавок открыт без регистрации. Само приложение бесплатно в RuStore.
