健身營養
健身房訓練計劃器和營養追蹤器。通過 wger 按肌肉、器械或類別搜索 690+ 種練習。通過 USDA FoodData Central 查詢 380,000+ 種食物的宏量營養素和卡路里。計算 BMI、TDEE、單次最大重量(1RM)、宏量營養素分配比例和體脂率——純 Python 實現,無需 pip 安裝。專為追求增肌、減重或只是希望吃得更健康的人士打造。
技能元數據
| 來源 | 可選 — 使用 hermes skills install official/health/fitness-nutrition 安裝 |
| 路徑 | optional-skills/health/fitness-nutrition |
| 版本 | 1.0.0 |
| 許可證 | MIT |
| 標籤 | health, fitness, nutrition, gym, workout, diet, exercise |
參考:完整 SKILL.md
以下是 Hermes 在觸發此技能時加載的完整技能定義。這是技能激活時代理看到的指令。
健身與營養
專家級健身教練和運動營養師技能。兩個數據源加上離線計算器——將健身人士所需的一切整合於一處。
數據源(全部免費,無 pip 依賴):
- wger (https://wger.de/api/v2/) — 開放練習數據庫,包含 690+ 種練習,涵蓋肌肉、器械和圖片。公共端點無需身份驗證。
- USDA FoodData Central (https://api.nal.usda.gov/fdc/v1/) — 美國政府營養數據庫,包含 380,000+ 種食物。
DEMO_KEY可立即使用;免費註冊可獲得更高限額。
離線計算器(純 Python 標準庫):
- BMI、TDEE(Mifflin-St Jeor 公式)、單次最大重量(Epley/Brzycki/Lombardi 公式)、宏量營養素分配比例、體脂率百分比(美國海軍方法)
何時使用
當用戶詢問以下內容時觸發此技能:
- 練習、訓練、健身房常規、肌群、訓練分化
- 食物宏量營養素、卡路里、蛋白質含量、膳食計劃、卡路里計數
- 身體成分:BMI、體脂率、TDEE、熱量盈餘/赤字
- 單次最大重量估算、訓練百分比、漸進超負荷
- 用於減脂、增肌或維持的宏量營養素比例
流程
練習查詢(wger API)
所有 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 — 獲取並展示結果:
# Search exercises by name
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} | Category: {d.get('category','N/A')}\")
"
# Get full details for a specific exercise
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\"Exercise : {t.get('name','N/A')}\")
print(f\"Category : {data.get('category',{}).get('name','N/A')}\")
print(f\"Primary : {', '.join(m.get('name_en','') for m in data.get('muscles',[])) or 'N/A'}\")
print(f\"Secondary : {', '.join(m.get('name_en','') for m in data.get('muscles_secondary',[])) or 'none'}\")
print(f\"Equipment : {', '.join(e.get('name','') for e in data.get('equipment',[])) or 'bodyweight'}\")
print(f\"How to : {desc[:500]}\")
imgs=data.get('images',[])
if imgs: print(f\"Image : {imgs[0].get('image','')}\")
"
# List exercises filtering by muscle, category, or equipment
# Combine filters as needed: ?muscles=4&equipment=1&language=2&status=2
FILTER="$1" # e.g. "muscles=4" or "category=11" or "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'Found {data.get(\"count\",0)} exercises.')
for ex in data.get('results',[]):
print(f\" ID {ex['id']:>4} | muscles: {ex.get('muscles',[])} | equipment: {ex.get('equipment',[])}\")
"
營養查詢(USDA FoodData Central)
如果設置了 USDA_API_KEY 環境變量則使用它,否則回退到 DEMO_KEY。
DEMO_KEY = 30 次請求/小時。免費註冊密鑰 = 1,000 次請求/小時。
# Search foods by name
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('No foods found.'); 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\" Per 100g: {cal} kcal | {prot}g protein | {fat}g fat | {carb}g carbs\")
print(f\" FDC ID: {f.get('fdcId','N/A')}\")
print()
"
# Detailed nutrient profile by 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\"Food: {d.get('description','N/A')}\")
print(f\"{'Nutrient':<40} {'Amount':>8} {'Unit'}\")
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 <weight_kg> <height_cm>python3 scripts/body_calc.py tdee <weight_kg> <height_cm> <age> <M|F> <activity 1-5>python3 scripts/body_calc.py 1rm <weight> <reps>python3 scripts/body_calc.py macros <tdee_kcal> <cut|maintain|bulk>python3 scripts/body_calc.py bodyfat <M|F> <neck_cm> <waist_cm> [hip_cm] <height_cm>
請參閱 references/FORMULAS.md 瞭解每個公式背後的科學原理。
常見陷阱
- wger 運動端點默認返回所有語言——始終添加
language=2以獲取英語內容 - wger 包含未驗證的用戶提交內容——添加
status=2以僅獲取已審核的運動項目 - USDA
DEMO_KEY的限制為每小時 30 次請求——在批量請求之間添加sleep 2,或申請免費密鑰 - USDA 數據基於每 100 克——提醒用戶根據實際份量進行換算
- BMI 無法區分肌肉和脂肪——肌肉發達的人的高 BMI 不一定表示不健康
- 體脂公式僅為估算值(誤差 ±3-5%)——如需精確結果,建議進行 DEXA 掃描
- 1RM 公式在超過 10 次重複時準確性下降——使用 3-5 次的組數以獲得最佳估算
- wger 的
exercise/search端點使用term而非query作為參數名
驗證
運行運動搜索後:確認結果包含運動名稱、肌群和器械。 查詢營養信息後:確認返回每 100 克的宏量營養素,包括熱量(kcal)、蛋白質、脂肪和碳水化合物。 運行計算器後:對輸出進行合理性檢查(例如,大多數成年人的 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} |
| BMI / TDEE / 1RM / 宏量營養素 | 離線 | python3 scripts/body_calc.py |