Yesterday

🥤 Как я считаю калории по фотографии

Одна из очередных автоматизаций, которую я наваибкодил, — подсчет калорий еды по фотке и сохранение в FatSecret. Хотелось простого сценария: закинул фотку в бота, он сам нашел продукты и добавил их в приложение. Задача была не сделать идеальный инструмент для точного учета калорий или макронутриентов, это невозможно, а собрать рабочую и практичную штуку. Пост не про то зачем и почему это нужно, а про реализацию.

Подпишешься на мой Телеграм канал?

⚠️ Сразу дисклеймер: даже современные AI-технологии пока не умеют точно определять питание. Нужно знать исходные продукты и способ приготовления. Если фоткать ингредиенты или упаковки с указанными макронутриентами, точность выше, но это не решает проблему полностью. И это логично. Даже человеку сложно оценить блюдо без контекста — не зная, как и из чего оно приготовлено. Возможно, в узкоспециализированных моделях качество лучше, но фундаментальная проблема никуда не исчезает.

Простой пример: творог с ягодами и орехами. AI спокойно определит ягоды и орехи. А вот жирность творога — нет. Ее невозможно понять по фотографии. И человек тоже не угадает. Без цифр на упаковке это просто гадание.

💸 Почему не использовать готовые инструменты? Они работают примерно так же, пытаются угодить всем с разными целями и, главное, стоят денег. Мои расходы на API LLM в разы ниже.

Само по себе отправить фотку в LLM с нужным промптом и получить калорийность — не проблема. Поправить цифры вручную — тоже. Самое сложное оказалось связать все это с FatSecret. У них есть API, но с ограничениями. Именно с ними я и воевал большую часть времени.

📷 На входе у меня фото или голосовое с описанием еды и граммовки. Vision от OpenAI обрабатывает изображение и возвращает не только калории и нутриенты, но и возможные названия продуктов для поиска в базе FatSecret с разной степенью уверенности. Дальше начинается магия костылей, потому что поиск в FatSecret очень специфичный. Промпт можно поглядеть здесь.

🔎 Код дергает API, получает кандидатов, сравнивает их по весам с тем, что предложил LLM, и выбирает одного основного + три дополнительных. Потом я могу голосом или текстом поправить граммовку, заменить продукт кнопкой, удалить его или сразу подтвердить. Распознавание иногда занимает до пары минут — поиск в FatSecret быстрый, но найти нужные варианты сложно. В итоге код находит в API приложения кандидатов, сравнивает их по весам отклонений с отправными значениями, которые задал LLM, и выбирает основного кандидата и трёх дополнительных. Выглядит это так.

После подтверждения бот сохраняет прием пищи в мой аккаунт, привязывая его ко времени: утром завтрак, днем обед и так далее. Все как в обычном трекере, только без ручного поиска каждого продукта.

🌍 Главная боль API FatSecret — в бесплатном тарифе поиск идет только по американской базе. Я не в Америке, не знаю как читать реп, поэтому пришлось занижать веса брендов в выдаче. На то, чтобы понять, что API просто игнорирует переданный регион поиска, ушло полдня 🙃

📦 Отдельно работает процесс для штрих-кодов. Он ищет продукты в OpenFoodFacts и добавляет дополнительный контекст. Если бы я вел свою базу питания, а не использовал FatSecret, все было бы проще. Но делать свой интерфейс не хотелось, когда уже есть нормальное приложение.

Если развивать идею дальше, логично дать LLM больше контекста: образ жизни, привычные продукты, частые блюда. Получился бы персональный nutrition assistant. Но я и не делал бота ради детального анализа белков и жиров. Мне важен контроль калорий внутри моей системы питания. Бот просто убирает лишнее трение и напоминает, сколько уже съедено и сколько еще остается. И этого достаточно.

Подпишешься на мой Телеграм канал?