Skip to content

Latest commit

 

History

History
179 lines (155 loc) · 25.4 KB

AGENTS.md

File metadata and controls

179 lines (155 loc) · 25.4 KB

🤖 AGENTS.md: Инструкции и Правила для AI-Ассистентов бота «Пищеблок» 🥑

Назначение файла: Главное руководство, свод архитектурных правил, инвариантов и протоколов разработки для любых AI-ассистентов и агентов, работающих с проектом «Пищеблок». Базовый стек: Python 3.10+, Aiogram 3.22 (FSM, Routers, MemoryStorage), aiosqlite (SQLite 3), DeepSeek Flash (deepseek-flash, OpenAI API compatible, Vision-мультимодальность), faster-whisper (автономное распознавание речи на CPU), python-dotenv, Pydantic v2, pytest (формализованные сьюты в tests/). Проект версионируется в GIT (эпоха этапа 0+): секреты и БД исключены через .gitignore, окончания строк нормализованы через .gitattributes. Операционная система сервера/разработки: Windows 10/11 x64.


1. Архитектурный ландшафт и модульная структура

Проект представляет собой специализированного Telegram-бота: персонального дипломированного диетолога-нутрициолога и заботливого семейного шеф-повара.

                               ┌─────────────────────────────────────────┐
                               │       Telegram Client (User / Wife)     │
                               └────────────────────┬────────────────────┘
                                                    │ Updates (Messages / Callbacks / Photos / Voice)
                                                    ▼
                               ┌─────────────────────────────────────────┐
                               │      Aiogram 3 Dispatcher (main.py)     │
                               │      MemoryStorage & Bot Commands Menu  │
                               └────────────────────┬────────────────────┘
                                                    │
       ┌───────────────────┬────────────────────────┼────────────────────────┬───────────────────┐
       ▼                   ▼                        ▼                        ▼                   ▼
┌──────────────┐    ┌──────────────┐         ┌──────────────┐         ┌──────────────┐    ┌──────────────┐
│  profile.py  │    │food_diary.py │         │vision_voice  │         │ sos_sweet.py │    │menu_planner  │
│  Анкета &    │    │Дневник &     │         │Vision Фото & │         │Экспресс-     │    │Меню на день/ │
│  Быстрый ред │    │Прогресс-бары │         │Whisper Голос │         │десерты & срыв│    │неделю & чеки │
└──────────────┘    └──────────────┘         └──────────────┘         └──────────────┘    └──────────────┘
       │                   │                        │                        │                   │
       └───────────────────┼────────────────────────┴────────────────────────┼───────────────────┘
                           │                                                 │
                           ▼                                                 ▼
       ┌─────────────────────────────────────────┐         ┌─────────────────────────────────────────┐
       │         Core Data & Logic               │         │        AI Intelligence Engine           │
       │  - database.py (aiosqlite SQLite)       │         │  - llm_service.py (DeepSeek Flash)      │
       │  - nutrition.py (Mifflin-St Jeor, BMR)  │         │    • Text: меню, рецепты, КБЖУ, SOS     │
       │  - keyboards.py (Reply & Inline Markup) │         │    • Vision: мультимодальный разбор фото│
       │  - states.py (Aiogram FSM States)       │         │  - faster-whisper (локальный Voice)     │
       └─────────────────────────────────────────┘         └─────────────────────────────────────────┘

Структура каталогов и назначение файлов:

  • main.py — Главная точка входа. Настройка логирования, UTF-8 консоли Windows, предполётная проверка конфигурации run_preflight() (validate_config(), флаг --check — сухой прогон без запуска бота), инициализация SQLite БД, регистрация системных команд бота (BotCommand) и подключение роутеров.
  • config.py — Загрузка переменных окружения из .env (токен бота, провайдер LLM_PROVIDER deepseek/gemini, ключ и модель LLM, базовый URL API, прокси, LLM_TIMEOUT, WHISPER_MODEL, DB_PATH) + validate_config() с человеческими сообщениями об ошибках. Шаблон — .env.example.
  • database.py — Асинхронный слой работы с БД SQLite через aiosqlite:
    • Таблица users: профиль, антропометрия, цели, любимые продукты, стоп-листы, привычки готовки, нормы КБЖУ.
    • Таблица daily_food_logs: дневник питания (записи приемов пищи за день с КБЖУ и временем).
    • Таблица weight_history: еженедельный трекер динамики изменения веса.
    • Таблица favorites: избранные рационы, рецепты и расчеты КБЖУ.
    • Таблица chat_messages: контекст диалога свободного общения с нутрициологом.
  • nutrition.py — Математический аппарат доказательной диетологии:
    • Формула Миффлина — Сан Жеора для расчета BMR и суточных энергозатрат (TDEE).
    • Расчет индивидуального коридора калорий и БЖУ (белки, жиры, углеводы) под цели (снижение веса, поддержание, набор).
    • Наглядное форматирование карточек с визуальными прогресс-барами ([🟩🟩🟩🟩⬜⬜⬜⬜] 50%).
  • keyboards.py — Фабрики клавиатур Telegram:
    • Постоянная нижняя ReplyKeyboardMarkup (get_main_keyboard).
    • Инлайн-клавиатуры модульного редактирования профиля (get_profile_actions_keyboard).
    • Инлайн-кнопки мгновенной записи в Дневник в 1 клик для фото (get_vision_log_keyboard) и текста (get_meal_type_log_keyboard).
  • states.py — Конечные автоматы Aiogram (StatesGroup): анкета ProfileForm, быстрое редактирование QuickEditForm, расчет КБЖУ KbzhuForm, холодильник FridgeForm.
  • llm_service.py — Единый AI-клиент на базе модели deepseek-flash:
    • Системный промпт нутрициолога с учетом кухонных весов, граммовок, режима и любимых продуктов.
    • Мультимодальный анализ фото тарелок analyze_food_photo через image_url (Base64).
    • Психологическая и нутрициологическая помощь generate_sweet_sos.
    • Генерация меню на день/неделю, рецептов из холодильника, расчетов КБЖУ.
  • handlers/ — Модульные обработчики событий Telegram:
    • profile.py: Первичный онбординг (анкета) и модульное точечное редактирование параметров.
    • food_diary.py: Просмотр дневника за день, прогресс-бары, умный совет на остаток нормы, удаление записей.
    • kbzhu_calc.py: Текстовый расчет КБЖУ любого блюда с кнопками быстрой записи в дневник.
    • vision_voice.py: Обработка фото тарелок (F.photo) через DeepSeek Flash Vision и голосовых заметок (F.voice) через Whisper.
    • sos_sweet.py: Экстренная помощь при тяге к сладкому / срыве.
    • menu_planner.py: Меню на день и на неделю с группировкой готовки на 2-3 дня и списками покупок.
    • fridge_chef.py: Подбор блюд из остатков продуктов в холодильнике.
    • favorites.py: Просмотр и удаление сохраненных материалов.
    • common.py: Команды /start, /reset и свободный диалог с нутрициологом (Fallback-роутер).
  • ЗАПУСК_БОТА.cmd — Лаунчер запуска бота для Windows (кодировка UTF-8 через chcp 65001, авто-venv, авто-установка зависимостей с маркером .deps_ok, предполётный main.py --check). Файл-спутник Запустить_Бота.lnk и .bat-версии удалены (Правило 8).
  • scripts/unix/run.sh — Лаунчер для Linux/macOS (venv + зависимости + preflight). Окончания строк LF (гарантируются .gitattributes).
  • .env.example — Шаблон переменных окружения с комментариями-инструкциями. .env с реальными ключами никогда не коммитится (.gitignore).
  • test_bot_core.py — Интеграционный набор (10 сьютов, запускается напрямую, работает в тестовой БД tests/_test_bot_core.db — боевая БД не затрагивается).
  • test_local_dataset.py — Оффлайн-проверки: дата-сет запросов, фикстуры LLM, локальный Whisper (0 токенов).
  • tests/ — Формализованные pytest-сьюты (conftest.py перенаправляет DB_PATH в tests/_test_nutrition_chef.db и выставляет ключи-заглушки до импорта config — герметичность к живому endpoint): test_config.py (validate_config), test_nutrition.py (BMR/цели/прогресс-бары), test_database.py (профиль, дневник, вес, избранное, чат), test_llm_service.py (промпты, гендерный контекст, парсеры, Vision-деградация, мок-клиент LLM), test_keyboards.py, test_menu_planner.py.
  • .github/workflows/ci.yml — CI: матрица ubuntu/windows, pytest + смоук main.py --check на заглушках (без сети и реальных токенов).
  • README.md — Простая версия для базового пользователя (дефолтная страница репозитория). README_ADVANCED.md — Техническая документация для экспертов (архитектура, все env-ручки, тесты, CI, эксплуатация). ИНСТРУКЦИЯ_ПОЛЬЗОВАТЕЛЯ.md — Пошаговый гайд уровня «куда нажать» для не-программиста.

2. Железные инженерные инварианты (Core Invariants)

При внесении любых изменений в проект любой AI-агент ОБЯЗАН СТРОЖАЙШЕ СОБЛЮДАТЬ следующие правила:

🔴 Правило 0: Обязательное составление и утверждение плана до внесения изменений (Plan-First & User Approval Gate)

  • Строго запрещено вносить ЛЮБЫЕ изменения в код, конфигурацию, схему БД или зависимости без предварительного составления детального плана и получения явного утверждения от пользователя.
  • Протокол действий агента:
    1. Тщательно проанализировать задачу, открытые файлы и архитектурные инварианты.
    2. Сформировать пошаговый план реализации с перечнем затрагиваемых модулей, файлов и сценариев проверки.
    3. Запросить у пользователя подтверждение плана.
    4. Приступать к редактированию файлов только после получения явного одобрения от пользователя.

🔴 Правило 1: Нулевая терпимость к «тихим сбоям» (Zero Silent Failures)

  • Категорически запрещен паттерн except: pass.
  • Любые перехваченные исключения обязаны логироваться через logger.error(..., exc_info=True) или возвращать пользователю понятное, вежливое объяснение ошибки вместо бесконечного ожидания или падения процесса бота.

🔴 Правило 2: Единый AI-движок DeepSeek Flash (deepseek-flash)

  • Проект стандартизирован на использование единой мультимодальной модели deepseek-flash (OpenAI-совместимый API).
  • Запрещено внедрять гибридные схемы (Hybrid AI) с привлечением сторонних облачных нейросетей (Google Gemini и др.) для разделения текста и картинок. Модель deepseek-flash выполняет как текстовые задачи (меню, рецепты, КБЖУ, чат), так и нативный визуальный анализ фото блюд (Vision) через Base64 image_url.
  • Модель deepseek-flash является reasoning-моделью (reasoning_tokens расходуют лимит completion tokens). Поэтому при вызовах client.chat.completions.create параметр max_tokens должен быть либо опущен, либо установлен с запасом (не менее 1500–2500 токенов), чтобы ответ не обрезался до пустой строки.

🔴 Правило 3: Автономность голосового ввода (Локальный Whisper)

  • Распознавание голосовых сообщений Telegram (F.voice) выполняется локально и автономно через библиотеку faster-whisper (модель tiny на CPU/int8) прямо на машине пользователя.
  • Аудиофайлы никогда не отправляются во внешние облачные API распознавания речи. После локальной транскрибации текст передается в deepseek-flash как обычное текстовое описание еды.

🔴 Правило 4: Неприкосновенность данных профиля подопечной

  • Запрещено заставлять пользователя перезаполнять профиль с нуля при изменении отдельных параметров.
  • В меню 👤 Мой профиль и КБЖУ реализованы модульные кнопки быстрого редактирования: 🎯 Изменить цель, ⚖️ Обновить вес, ❤️ Любимые продукты, 🥘 Режим и готовка, 🚫 Стоп-лист, ⚠️ Аллергии, 🍽️ Число персон.
  • При обновлении веса или цели формула Миффлина — Сан Жеора пересчитывает калории и БЖУ, а все остальные поля (аллергии, стоп-лист, любимые продукты) обязаны оставаться нетронутыми.

🔴 Правило 5: Обязательные граммовки для кухонных весов (Kitchen Scale Fidelity)

  • Главная боль подопечной при ведении дневника — непонимание, сколько именно грамм положить себе в тарелку.
  • Инвариант: Во всех рационах на день/неделю, рецептах из холодильника и отчетах КБЖУ бот ОБЯЗАН указывать:
    1. Рекомендуемый вес готовой порции в граммах (⚖️ Вес порции: ХХХ г).
    2. КБЖУ этой конкретной порции (~ХХХ ккал / Б: ХХ г / Ж: ХХ г / У: ХХ г).
    3. Справочно: КБЖУ на 100 г блюда.

🔴 Правило 6: Уважение к любимым вкусностям и стоп-листам

  • Поле favorite_foods (радости) обязательно учитывается в промптах llm_service.py. Шеф-повар регулярно и гармонично включает любимые продукты (шоколад, ягоды, сыр, манго и т.д.) в меню, перекусы и экспресс-десерты, обеспечивая психологический комфорт без срывов.
  • Поля allergies и disliked_foods (стоп-лист) имеют наивысший приоритет запрета: продукты из этих списков ни при каких обстоятельствах не должны попадать в предложенные блюда.

🔴 Правило 7: Дневник питания, прогресс-бары и динамика веса

  • В Дневнике питания (daily_food_logs) отображается точный подсчет съеденных калорий и БЖУ за текущие сутки с визуальными прогресс-барами и расчетом остатка до индивидуальной нормы.
  • Записи в дневник добавляются в 1 клик как по кнопкам после расчета КБЖУ текста, так и по кнопкам под карточкой распознанного фото блюда.
  • Каждое обновление веса фиксируется в таблице weight_history, и бот наглядно сообщает пользователю динамику отвеса с момента первого взвешивания (📉 Динамика веса: -Х.Х кг).
  • Трекер воды исключен из проекта по решению пользователя.

🔴 Правило 8: Обязательные DOS CRLF окончания (\r\n) для файлов .bat и .cmd

  • Строжайше запрещено сохранять файлы .bat и .cmd с Unix-окончаниями \n (LF)!
  • Командный интерпретатор Windows cmd.exe считывает скрипты построчно прямо с диска, рассчитывая смещения по стандарту DOS (\r\n, 2 байта). Unix-окончания \n при наличии кириллицы (UTF-8) приводят к накоплению ошибки смещения каретки (Byte Offset Drift), порождая критические ошибки парсера вида 'e" set "PY_CMD' is not recognized.
  • Запрещено использовать типографские Unicode-тире — (U+2014) в командах батников до chcp 65001. Всегда использовать стандартный ASCII дефис -.

🔴 Правило 9: Безопасность Markdown и ограничений Telegram

  • Лимит длины одного текстового сообщения в Telegram составляет 4096 символов.
  • Все длинные ответы LLM (меню на неделю, разборы рационов) обязаны разбиваться на чанки до 4000 символов перед отправкой.
  • При отправке сообщений с parse_mode="Markdown" блок try...except обязан перехватывать ошибки парсинга Telegram API (TelegramBadRequest) и отправлять сообщение повторно с parse_mode=None (Fallback Graceful Degradation), чтобы пользователь никогда не оставался без ответа.

🔴 Правило 10: Чистота тестовой базы данных и гигиена тестов

  • Любые тесты, создающие тестовые записи в БД (users, daily_food_logs, weight_history, favorites), обязаны удалять свои временные данные после завершения тестирования.
  • Основная боевая БД nutrition_chef.db не должна засоряться тестовыми пользователями и фиктивными записями.

3. Регламент тестирования и верификации

Перед сдачей любой доработки агенты обязаны выполнить следующие проверки:

  1. Синтаксис и чистота импортов:
    py -c "import main; print('OK')"
  2. Предполётная проверка конфигурации:
    py main.py --check
    При живом .env вывод должен быть «OK: конфигурация в порядке».
  3. Автономное оффлайн-тестирование (Дата-сет, Whisper, База данных, 0 руб/0 токенов):
    py test_local_dataset.py
    Все 5 оффлайн-тестов обязаны завершаться успешно.
  4. Прогон формализованных pytest-сьютов (герметично к сети и ключам):
    py -m pytest tests -q
    Все тесты обязаны проходить; новые доработки сопровождаются новыми тестами в tests/.
  5. Прогон единого интеграционного тестового набора:
    py test_bot_core.py
    Все 10 тестовых сьютов (Инициализация БД, Профиль, Точечное редактирование, Промпты LLM, Дневник питания, Избранное, Клавиатуры SOS/Vision, Трекер веса, Гендерная адаптация, Интерактивный список покупок и замена блюд) обязаны завершаться со статусом 100% УСПЕШНО.
  6. CI: при пуше в Gite/GitHub джоб .github/workflows/ci.yml повторяет пункты 4 и 2 на матрице ubuntu/windows с ключами-заглушками. Локально достаточно пунктов 1-5.