Задача
Косметический рынок устроен так, что покупатель не может проверить обещание. На упаковке написано «сужает поры», внутри может быть актив в нерабочей концентрации или вообще ничего по этой задаче. Состав по INCI напечатан мелким шрифтом на латыни и для обычного человека нечитаем.
Отсюда требования, каждое из которых меняет архитектуру:
- состав нужно получить без ручного ввода — иначе сервисом не будут пользоваться в магазине у полки; значит штрихкод, фотография упаковки и распознавание текста;
- компонент оценивается в позиции, а не сам по себе — вещество в начале списка и в конце это разные концентрации и разный эффект;
- оценка должна быть персональной — один и тот же состав хорош для жирной кожи и плох для сухой чувствительной;
- нужны взаимодействия — и внутри одного средства, и между средствами, которыми человек пользуется одновременно;
- за каждым утверждением должен стоять источник — иначе сервис ничем не отличается от блогерского мнения;
- каталог должен жить сам — бренды выпускают и переформулируют средства постоянно, вручную это не поддерживается.
Решение
Справочник компонентов — ядро, а не словарь. Карточка компонента содержит название по INCI, синонимы, бытовое название и класс; рабочую концентрацию и оптимум, отдельно для чувствительной кожи; условия устойчивости — кислотность, свет, температуру; совместимость с типами кожи. Главное в ней — две сети связей. Первая, «компонент — проблема»: для каждой проблемы указаны механизм действия, уровень доказательности и список источников. Вторая — взаимодействия с другими компонентами: синергия, конфликт или нейтральность, с пояснением почему. Уровень подтверждения разведён на клинические исследования, лабораторные работы и обзоры, отдельные наблюдения и данные производителя: сервис говорит «здесь эффект подтверждён» и «здесь данных недостаточно» вместо одинаково уверенного тона по всем пунктам.
Оценка — формула, а не коэффициент. Итог собирается из концентраций активов, оценённых по позиции в списке INCI, их синергии внутри состава, силы связи каждого актива с каждой проблемой, весов проблем из профиля пользователя и штрафов за нежелательные для него компоненты. Профиль строится из анкеты: тип кожи, чувствительность, беспокоящие проблемы, реакции в прошлом, возрастная группа, беременность и кормление, климат и сезон, назначения врача. Для беременных действует отдельный контур ограничений, который перекрывает обычную логику оценки.
Полка, а не одно средство. Пользователь ведёт список того, чем пользуется сейчас, с разбивкой на утро и вечер. Полка нужна, чтобы ловить конфликты между средствами: само по себе средство хорошее, но вместе с другим даёт раздражение — это видно только при учёте всего набора.
Сравнение всегда под задачу. У полки вопрос «что из этих двух» задают чаще, чем «что вообще есть». Одно и то же средство выигрывает по порам и проигрывает по увлажнению, поэтому пользователь выбирает проблему, и обе оценки пересчитываются под неё — с ключевыми активами и их концентрациями, рисками, ценой за миллилитр и текстовым выводом, который объясняет разницу словами, в том числе когда средства решают задачу по-разному.
Парсеры и их поломки. Каталог собирается по сайтам брендов и магазинов, для каждого бренда своё правило разбора. Источники разного качества: где-то состав опубликован текстом и забирается напрямую, где-то лежит картинкой и идёт в распознавание с заметно меньшей точностью, где-то его нет вовсе. Бренд меняет вёрстку — правило молча перестаёт находить состав, поэтому нужен мониторинг прогонов и явный статус «сломан» вместо тихой пустоты. Один и тот же артикул через год может иметь другой состав — фиксируется дата получения. Один ингредиент пишут по-разному — синонимы сводятся к канонической записи, иначе связи с проблемами не срабатывают и хороший состав получает заниженную оценку.
Замкнутый контур обучения. Всё, что разобрано неуверенно, попадает в кураторскую очередь к химику-технологу. Его правки и случаи, где модель разошлась с экспертом, идут обратно в обучающую выборку. Качество отслеживается отдельно: точность распознавания составов, совпадение оценки модели с экспертной, доля ошибок в концентрациях, объём ручных правок за период.
Стек. Ядро сервиса, каталог, профили и админка — Laravel и PHP, интерфейс сайта — Vue.js, в контуре проекта также Magento. Разбор составов, распознавание текста с упаковки и модель оценки — Python и машинное обучение. Мобильное приложение под iOS и Android даёт три пути к разбору: штрихкод, фотографию состава и ручной ввод текстом.
Результат
Покупатель получает у полки то, чего рынок ему не даёт, — проверяемый ответ: список по INCI в исходном порядке, оценка концентрации каждого компонента, функция простым языком, пометки «актив», «нейтральный», «спорный», общая оценка под его профиль, отдельная шкала по каждой проблеме, предупреждения о конфликте с полкой и о нежелательных для него компонентах — и количество работ за каждым ключевым утверждением.
Подбор идёт от проблемы, а не от рейтинга средств вообще: фильтры по проблеме, типу средства, цене и доказательности, автоматическое исключение нежелательных компонентов из профиля. Средства с ними не исчезают, а опускаются ниже и получают пометку — решение остаётся за человеком.
Химик-технолог получил машиночитаемую форму для своей экспертизы: знание о механизмах, концентрациях и взаимодействиях ложится в справочник без потерь и сразу работает в оценке. Контент-оператору досталась админка сбора данных: состояние каждого парсера, качество разбора, очередь на человека и метрики модели.