Фитнес-нутрициология
Планировщик тренировок в зале и трекер питания. Ищите 690+ упражнений по мышцам, оборудованию или категориям через wger. Узнавайте макронутриенты и калорийность 380 000+ продуктов через USDA FoodData Central. Рассчитывайте ИМТ, TDEE, повторный максимум, распределение макронутриентов и процент жира — чистый Python, без pip-установок. Создано для тех, кто стремится к набору массы, снижению веса или просто хочет питаться лучше.
Метаданные навыка
| Источник | Опционально — установка через vibeos skills install official/health/fitness-nutrition |
| Путь | optional-skills/health/fitness-nutrition |
| Версия | 1.0.0 |
| Лицензия | MIT |
| Платформы | linux, macos, windows |
| Теги | health, fitness, nutrition, gym, workout, diet, exercise |
Справочник: полный SKILL.md
Ниже приведено полное описание навыка, которое VibeOS загружает при его активации. Агент видит эти инструкции, когда навык активен.
Фитнес и нутрициология
Экспертный навык фитнес-тренера и спортивного нутрициолога. Два источника данных плюс офлайн-калькуляторы — всё, что нужно посетителю зала, в одном месте.
Источники данных (все бесплатные, без pip-зависимостей):
- wger (https://wger.de/api/v2/) — открытая база упражнений, 690+ упражнений с мышцами, оборудованием, изображениями. Публичные эндпоинты не требуют аутентификации.
- USDA FoodData Central (https://api.nal.usda.gov/fdc/v1/) — государственная база данных о питании США, 380 000+ продуктов.
DEMO_KEYработает сразу; бесплатная регистрация для более высоких лимитов.
Офлайн-калькуляторы (чистый Python из стандартной библиотеки):
- ИМТ, TDEE (Mifflin-St Jeor), повторный максимум (Epley/Brzycki/Lombardi), распределение макронутриентов, процент жира (метод ВМС США)
Когда использовать
Активируйте этот навык, когда пользователь спрашивает о:
- Упражнениях, тренировках, программах для зала, мышечных группах, сплитах
- Макронутриентах продуктов, калориях, содержании белка, планировании питания, подсчёте калорий
- Композиции тела: ИМТ, процент жира, TDEE, профицит/дефицит калорий
- Оценке повторного максимума, тренировочных процентах, прогрессивной перегрузке
- Соотношении макронутриентов для сушки, набора массы или поддержания
Процедура
Поиск упражнений (API wger)
Все публичные эндпоинты wger возвращают JSON и не требуют аутентификации. Всегда добавляйте format=json и language=2 (английский) к запросам упражнений.
Шаг 1 — Определите, что нужно пользователю:
- По мышце → используйте
/api/v2/exercise/?muscles={id}&language=2&status=2&format=json - По категории → используйте
/api/v2/exercise/?category={id}&language=2&status=2&format=json - По оборудованию → используйте
/api/v2/exercise/?equipment={id}&language=2&status=2&format=json - По названию → используйте
/api/v2/exercise/search/?term={query}&language=english&format=json - Полные детали → используйте
/api/v2/exerciseinfo/{exercise_id}/?format=json
Шаг 2 — Справочные ID (чтобы не делать лишних API-запросов):
Категории упражнений:
| ID | Категория |
|---|---|
| 8 | Руки |
| 9 | Ноги |
| 10 | Пресс |
| 11 | Грудь |
| 12 | Спина |
| 13 | Плечи |
| 14 | Икры |
| 15 | Кардио |
Мышцы:
| ID | Мышца | ID | Мышца |
|---|---|---|---|
| 1 | Двуглавая плеча | 2 | Передняя дельтовидная |
| 3 | Передняя зубчатая | 4 | Большая грудная |
| 5 | Наружная косая | 6 | Икроножная |
| 7 | Прямая живота | 8 | Большая ягодичная |
| 9 | Трапециевидная | 10 | Четырёхглавая бедра |
| 11 | Двуглавая бедра | 12 | Широчайшая спины |
| 13 | Плечевая | 14 | Трёхглавая плеча |
| 15 | Камбаловидная |
Оборудование:
| ID | Оборудование |
|---|---|
| 1 | Штанга |
| 3 | Гантель |
| 4 | Гимнастический коврик |
| 5 | Фитбол |
| 6 | Турник |
| 7 | нет (с весом тела) |
| 8 | Скамья |
| 9 | Наклонная скамья |
| 10 | Гиря |
Шаг 3 — Получите и представьте результаты:
# Поиск упражнений по названию
QUERY="$1"
ENCODED=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))" "$QUERY")
curl -s "https://wger.de/api/v2/exercise/search/?term=${ENCODED}&language=english&format=json" \
| python3 -c "
import json,sys
data=json.load(sys.stdin)
for s in data.get('suggestions',[])[:10]:
d=s.get('data',{})
print(f\" ID {d.get('id','?'):>4} | {d.get('name','N/A'):<35} | Категория: {d.get('category','N/A')}\")
"
# Получить полную информацию о конкретном упражнении
EXERCISE_ID="$1"
curl -s "https://wger.de/api/v2/exerciseinfo/${EXERCISE_ID}/?format=json" \
| python3 -c "
import json,sys,html,re
data=json.load(sys.stdin)
trans=[t for t in data.get('translations',[]) if t.get('language')==2]
t=trans[0] if trans else data.get('translations',[{}])[0]
desc=re.sub('<[^>]+>','',html.unescape(t.get('description','N/A')))
print(f\"Упражнение: {t.get('name','N/A')}\")
print(f\"Категория : {data.get('category',{}).get('name','N/A')}\")
print(f\"Основные : {', '.join(m.get('name_en','') for m in data.get('muscles',[])) or 'N/A'}\")
print(f\"Вторичные : {', '.join(m.get('name_en','') for m in data.get('muscles_secondary',[])) or 'нет'}\")
print(f\"Оборуд. : {', '.join(e.get('name','') for e in data.get('equipment',[])) or 'вес тела'}\")
print(f\"Как делать: {desc[:500]}\")
imgs=data.get('images',[])
if imgs: print(f\"Изображение: {imgs[0].get('image','')}\")
"
# Список упражнений с фильтрацией по мышце, категории или оборудованию
# Комбинируйте фильтры по необходимости: ?muscles=4&equipment=1&language=2&status=2
FILTER="$1" # например "muscles=4" или "category=11" или "equipment=3"
curl -s "https://wger.de/api/v2/exercise/?${FILTER}&language=2&status=2&limit=20&format=json" \
| python3 -c "
import json,sys
data=json.load(sys.stdin)
print(f'Найдено {data.get(\"count\",0)} упражнений.')
for ex in data.get('results',[]):
print(f\" ID {ex['id']:>4} | мышцы: {ex.get('muscles',[])} | оборудование: {ex.get('equipment',[])}\")
"
Поиск продуктов питания (USDA FoodData Central)
Использует переменную окружения USDA_API_KEY, если она задана, иначе использует DEMO_KEY.
DEMO_KEY = 30 запросов/час. Бесплатный ключ = 1 000 запросов/час.
# Поиск продуктов по названию
FOOD="$1"
API_KEY="${USDA_API_KEY:-DEMO_KEY}"
ENCODED=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))" "$FOOD")
curl -s "https://api.nal.usda.gov/fdc/v1/foods/search?api_key=${API_KEY}&query=${ENCODED}&pageSize=5&dataType=Foundation,SR%20Legacy" \
| python3 -c "
import json,sys
data=json.load(sys.stdin)
foods=data.get('foods',[])
if not foods: print('Продукты не найдены.'); sys.exit()
for f in foods:
n={x['nutrientName']:x.get('value','?') for x in f.get('foodNutrients',[])}
cal=n.get('Energy','?'); prot=n.get('Protein','?')
fat=n.get('Total lipid (fat)','?'); carb=n.get('Carbohydrate, by difference','?')
print(f\"{f.get('description','N/A')}\")
print(f\" На 100г: {cal} ккал | {prot}г белка | {fat}г жира | {carb}г углеводов\")
print(f\" FDC ID: {f.get('fdcId','N/A')}\")
print()
"
# Детальный профиль питательных веществ по FDC ID
FDC_ID="$1"
API_KEY="${USDA_API_KEY:-DEMO_KEY}"
curl -s "https://api.nal.usda.gov/fdc/v1/food/${FDC_ID}?api_key=${API_KEY}" \
| python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f\"Продукт: {d.get('description','N/A')}\")
print(f\"{'Питательное вещество':<40} {'Количество':>8} {'Ед.'}\")
print('-'*56)
for x in sorted(d.get('foodNutrients',[]),key=lambda x:x.get('nutrient',{}).get('rank',9999)):
nut=x.get('nutrient',{}); amt=x.get('amount',0)
if amt and float(amt)>0:
print(f\" {nut.get('name',''):<38} {amt:>8} {nut.get('unitName','')}\")
"
Офлайн-калькуляторы
Используйте вспомогательные скрипты в scripts/ для пакетных операций или запускайте встроенные команды для одиночных расчётов:
python3 scripts/body_calc.py bmi <вес_кг> <рост_см>python3 scripts/body_calc.py tdee <вес_кг> <рост_см> <возраст> <M|F> <активность 1-5>python3 scripts/body_calc.py 1rm <вес> <повторения>python3 scripts/body_calc.py macros <tdee_ккал> <cut|maintain|bulk>python3 scripts/body_calc.py bodyfat <M|F> <шея_см> <талия_см> [бедра_см] <рост_см>
Смотрите references/FORMULAS.md для научного обоснования каждой формулы.
Подводные камни
- Эндпоинт упражнений wger возвращает все языки по умолчанию — всегда добавляйте
language=2для английского - wger включает непроверенные пользовательские материалы — добавляйте
status=2, чтобы получать только одобренные упражнения DEMO_KEYUSDA имеет 30 запросов/час — добавляйтеsleep 2между пакетными запросами или получите бесплатный ключ- Данные USDA даны на 100г — напоминайте пользователям масштабировать под их фактический размер порции
- ИМТ не различает мышцы и жир — высокий ИМТ у мускулистых людей не обязательно нездоров
- Формулы процента жира являются приблизительными (±3-5%) — рекомендуйте DEXA-сканирование для точности
- Формулы ПМ теряют точность при более чем 10 повторениях — используйте подходы по 3-5 повторений для лучших оценок
- Эндпоинт
exercise/searchwger используетterm, а неqueryв качестве имени параметра
Проверка
После поиска упражнений: убедитесь, что результаты включают названия упражнений, мышечные группы и оборудование. После поиска продуктов: убедитесь, что возвращены макронутриенты на 100г с ккал, белками, жирами, углеводами. После калькуляторов: проверьте результаты на правдоподобие (например, TDEE должен быть 1500-3500 для большинства взрослых).
Быстрая справка
| Задача | Источник | Эндпоинт |
|---|---|---|
| Поиск упражнений по названию | wger | GET /api/v2/exercise/search/?term=&language=english |
| Детали упражнения | wger | GET /api/v2/exerciseinfo/{id}/ |
| Фильтр по мышце | wger | GET /api/v2/exercise/?muscles={id}&language=2&status=2 |
| Фильтр по оборудованию | wger | GET /api/v2/exercise/?equipment={id}&language=2&status=2 |
| Список категорий | wger | GET /api/v2/exercisecategory/ |
| Список мышц | wger | GET /api/v2/muscle/ |
| Поиск продуктов | USDA | GET /fdc/v1/foods/search?query=&dataType=Foundation,SR Legacy |
| Детали продукта | USDA | GET /fdc/v1/food/{fdcId} |
| ИМТ / TDEE / ПМ / макронутриенты | офлайн | python3 scripts/body_calc.py |