营养成分表计算器(nutrition-facts-calculator)
Overview
将一张预包装食品的营养标签(营养成分表 + 配料表)转化为可执行的饮食判断:先按国标 NRV 基准量化"每 100g 占一天额度多少",再读配料表识别糖的别名、风险油脂与添加剂,最后结合人群给出量化食用建议。所有确定性计算交由 scripts/analyze_nutrition.py,避免每轮重写同段代码;标准值单一数据源为 references/nrv_standards.json,用户向速查以 references/食品标签常见指标集合.html 呈现。
> 合规红线(每次输出都必须遵守):本技能输出为食品标签营养科普,不构成医疗诊断或饮食处方。报告必须包含免责声明段(见步骤 6 模板),涉及疾病、孕产、婴幼儿的场景须提示"请咨询医生或注册营养师"。
When to Use
- 用户上传食品包装图片 / 营养成分表截图 / 配料表截图(环境支持 Read 图片时直接解析,不支持时走降级路径,见步骤 1)。
- 用户粘贴文字版营养成分表或配料表。
- 用户问"如何看懂配料表/营养成分表""这个零食健不健康""钠/糖/脂肪是不是超标""NRV% 怎么看""一天能吃多少"。
- 用户要求对某个食品做量化营养分析与食用建议。
Workflow
按顺序执行以下步骤:
1. 输入识别(含降级路径)
判断输入形态:
- 图片:先用 Read 读取图片。若 Read 报错或不支持图片(部分模型/环境会失败),立即降级:告知用户"当前环境无法直接读图,请把营养成分表和配料表用文字打出来(照抄包装上的'项目/每100g/NRV%'三列和配料清单即可)",不要中断或凭空编造数值。
- 文字:直接解析用户粘贴的表格或文本。
解析时记录:
- 数据基准:数值是"每 100g"还是"每份"(饮料、进口包装常见"每份")。每份基准需记录每份克数(serving_size_g),计算时用 --basis per_serving --serving-size-g N。
- 净含量(如 320g / 30g 小包),供步骤 5 换算。
- 拍照常只拍到局部,须提示用户补全前段配料。
2. 解析营养成分表(定量)
将提取到的项目整理为结构化数据,字段含 name / value / unit。指标名不必强行纠正为标准名——脚本已内置别名归一(热量→能量、纳→钠、碳水→碳水化合物等),单位也不必预换算(kcal/大卡、g/mg 均自动转换并输出 unit_note)。交给 scripts/analyze_nutrition.py 计算(见步骤 4 用法)。
3. 解析配料表(定性)
按以下规则逐项判断,结论用于报告「配料表解读」段:
- 排序:配料按添加量从多到少排,前三位 ≈ 主料。
- 添加糖别名:白砂糖、果葡糖浆、麦芽糖浆、玉米糖浆、葡萄糖浆、蜂蜜、浓缩果汁、乳糖、麦芽糖。出现越多、越靠前越差;"无蔗糖"≠无糖。
- 风险油脂:含"氢化 / 部分氢化 / 起酥油 / 植脂末 / 代可可脂 / 人造奶油"→ 可能含反式脂肪,警惕。
- 添加剂:防腐剂、色素、增稠剂、甜味剂;种类越多 = 加工度越高,儿童食品尤其要数。
- 关键澄清:营养成分表"碳水"≠"糖";"0 反式脂肪"仍可能因国标允许 ≤0.3g/100g 标 0 而含微量。
4. 运行计算脚本(确定性)
用 scripts/analyze_nutrition.py 计算 NRV% 与灯色,避免手算误差:
python analyze_nutrition.py --input data.json [--serving 30] [--output result.json]
# 每份基准(饮料/进口包装):
python analyze_nutrition.py --input data.json --basis per_serving --serving-size-g 250
data.json 结构:
{
"items": [
{"name": "能量", "value": 2011, "unit": "kJ"},
{"name": "蛋白质", "value": 10.3, "unit": "g"},
{"name": "脂肪", "value": 19.8, "unit": "g"},
{"name": "饱和脂肪", "value": 0, "unit": "g"},
{"name": "碳水化合物", "value": 66.4, "unit": "g"},
{"name": "糖", "value": 0, "unit": "g"},
{"name": "钠", "value": 502, "unit": "mg"}
],
"serving_g": 30
}
执行注意:
- 临时 data.json 写到系统临时目录(如 $TMP/%TEMP%),不要写在技能目录或用户工作目录,用完即删。
- 脚本自动处理单位换算与别名;结果中出现 unit_note 时须在报告中如实呈现(如"kcal 已换算为 kJ")。
- 标准值与灯色阈值以 references/nrv_standards.json 为单一数据源(脚本读取失败会回退内置值并继续可用)。
脚本输出每项的 nrv_pct、light、direction,以及按 serving_g 换算后的实际摄入量与占日上限比例。
5. 量化分析
结合脚本结果,对每一项给灯色与一句判断:
- limit 类(能量、脂肪、饱和脂肪、糖、钠、反式脂肪):NRV% ≥ 30 → 红灯(单包已占一天额度 1/3 以上);5–30 → 黄灯;< 5 → 绿灯(低,好)。
- encourage 类(蛋白质、膳食纤维、钙、铁):NRV% ≥ 15 → 绿灯(贡献充足);5–15 → 黄灯;含量为 0 → 标"—"(该品类通常不含此成分,如饮料的蛋白质,不是健康风险,勿判红灯)。
- 按 serving_g 换算实际吃下的脂肪/钠/热量占日上限比例,写进报告。
- 旧版标准提示:当前市售包装多按 GB 28050-2011(1+4)标注,若无"糖/饱和脂肪"列,须注明"该包装或基于旧版标准,糖/饱和脂肪未强制标出,不代表含量为 0"。
6. 分人群建议(固定 HTML 报告)
报告输出到当前工作目录(用户的 workspace),文件名"品名+营养成分分析报告.html"。禁止写死任何绝对路径;用户环境的工作目录即输出位置。
报告结构(与 references/report-template.md 一致):
1. 核心结论一句话;
2. 营养成分表量化(每 100g + 灯色 + 按食用量换算);
3. 配料表解读;
4. 分人群食用建议(普通成人 / 减脂控重 / 控糖 / 高血压限盐 / 儿童孕妇)——须基于本品的真实 NRV 占比给区间,不套与数据无关的固定话术;
5. 关键澄清与标准来源;
6. 免责声明(必含):"本报告仅基于食品标签做营养科普,不构成医疗诊断或饮食处方;婴幼儿、孕产妇及患有疾病者请咨询医生或注册营养师。"
报告内必须保留三条读表原则:
1. 看 NRV% 找红灯(单指标 > 30% 高含量、< 5% 低含量)。
2. 第 2 列是"每 100g"非"每份",按实际量换算。
3. NRV% 是标准人(2000 kcal)基准,非个人额度,仅作相对高低判断。
Resources
references/nrv_standards.json
单一数据源:NRV 基准(GB 28050-2025 附录 A)、方向、别名映射、灯色阈值。脚本运行时读取;更新国标/指南时只改此文件。
references/label-standards.md
纯文本速查(文档性质):NRV 基准、灯色阈值、健康每日推荐值、配料表定性规则、来源清单。步骤 3–5 的判断依据。
references/食品标签常见指标集合.html
用户向速查(与 .md 互补):日常最常见 11 项指标的强制/可选属性、NRV 基准、健康关注点,含"已移除不常见指标"清单。可直接在报告中引用或展示给用户。
references/report-template.md
固定 HTML 报告的结构模板与免责声明原文,保证不同会话生成报告样式一致。
scripts/analyze_nutrition.py
确定性计算引擎 v2.0:NRV% = 含量 ÷ NRV × 100%,灯色判定,按食用量换算;内置单位换算、别名归一、每份基准。仅依赖 Python 标准库(3.8+),无需 pip 安装。所有数值计算经此脚本,保证可复现。
scripts/test_analyze.py
自动化测试(14 项断言):v1 兼容、单位换算、别名、每份基准、0 值判定、错误处理。改动脚本后必须跑通再交付。
Notes
- 合规:输出为营养科普,非医疗建议;报告必含免责声明;不对用户做疾病诊断。
- 隐私:报告只呈现食品数据,不写入用户姓名等个人身份信息。
- 标准值更新:GB 28050-2025 已发布(2027-03-16 实施),市售包装多仍按 2011 版;糖、饱和脂肪为 2025 版新增强制项。更新时只改
nrv_standards.json,并同步核对label-standards.md的文档表述。 - 两类来源强制力不同:GB 28050 管"标签怎么标"(强制国标);膳食指南 / DRIs 管"该吃多少"(权威推荐,无法律强制力)。
- 适用范围:基于中国大陆标准体系;海外包装(英文 Nutrition Facts)数据结构不同,处理时须手动映射到本技能指标名后计算,并注明标准差异。