Analyse approfondie : estimation nutritionnelle
Le package @gram-lang/analyzer est capable de calculer automatiquement le profil en macro et micronutriments de n’importe quelle recette.
Néanmoins, les données nutritionnelles étant particulièrement sensibles (avec un impact direct sur les choix diététiques), Gram adopte une approche stricte et mathématiquement conservatrice pour ses estimations. Cette page détaille cette logique.
Le flux de calcul
Section intitulée « Le flux de calcul »- Standardisation des masses : Avant le moindre calcul nutritionnel, l’Analyseur doit convertir chaque ingrédient de la recette en une masse standard exprimée en grammes. (Voir Standardisation des masses).
- Recherche dans la Base de Données : L’Analyseur interroge votre base de données
ingredients.yamlpour le blocnutritionde chaque ingrédient. Les valeurs de la base de données doivent toujours représenter les nutriments pour 100 g de l’ingrédient cru. - Adaptation proportionnelle : L’Analyseur adapte les valeurs aux 100 g issues de la base de données pour correspondre à la masse réellement utilisée dans la recette.
- Agrégation : Les valeurs ajustées pour tous les ingrédients sont additionnées pour calculer la Nutrition Totale de la Recette.
- Bases de service v1.1.0 : La Nutrition Totale de la Recette est ensuite exprimée sur les bases qu’un cuisinier lit réellement. Si le frontmatter définit
portions: 4, elle est divisée par 4 pour donnerperPortion. Elle est aussi divisée par la masse dont elle est issue pour donnerper100g— qui ne dépend pas deportions, si bien qu’une recette sans portions déclarées obtient malgré tout une base standardisée.
Rapport transparent des données partielles
Section intitulée « Rapport transparent des données partielles »La règle d’or du moteur nutritionnel de Gram : ne jamais masquer l’estimation, mais ne jamais laisser l’utilisateur la prendre pour parole d’évangile.
Si vous préparez un repas contenant 10 ingrédients et que votre base de données n’en couvre que 9, afficher silencieusement la somme de ces 9 ingrédients pourrait laisser croire à un total exact, alors qu’il sous-estimerait la réalité calorique.
Plutôt que de purement et simplement cacher le total, Gram l’affiche en y adossant les indicateurs nécessaires pour juger de sa fiabilité :
- Le
total(ainsi queperPortion, siportionsest défini, etper100g) est toujours calculé et renvoyé à partir de toutes les données disponibles — il n’est jamais masqué. - Un ratio de
coverage(couverture) est toujours inclus (ex :0.9pour “90 % des ingrédients ont des données”), calculé comme la part des ingrédients ayant une masse qui possèdent un blocnutrition. - Une liste
warningssignale exactement quels ingrédients sont absents de la base de données, manquent de blocnutrition, ou ont une masse non résolvable — ainsi la lacune est attribuable, et n’est pas juste une mise en garde floue.
Le renderer HTML de référence reflète directement ce parti pris : il affiche systématiquement le panneau nutritionnel (dès lors qu’il y a des données ou un avertissement), flanqué d’un badge Couverture : X %. Le cuisinier accède ainsi instantanément à une valeur utile, tout en mesurant d’un coup d’œil la proportion réelle de la recette couverte par l’estimation (plutôt que de cacher totalement une estimation exacte à 90 %).
Ce que « pour 100 g » signifie ici v1.1.0
Section intitulée « Ce que « pour 100 g » signifie ici »Gram ne modélise aucune perte à la cuisson. Ni évaporation, ni réduction, ni perte au four — le champ yield de la base d’ingrédients concerne le parage (épluchures, tiges, os), pas ce qui se passe dans la casserole.
per100g signifie donc pour 100 g du mélange cru assemblé : la somme des masses des ingrédients ayant effectivement contribué des macros. Pour un ragoût qui réduit d’un tiers ou un pain qui perd 12 % de son eau à la cuisson, cela sous-estime le plat fini par rapport à l’étiquette d’un produit du commerce.
Plutôt que de masquer ce point, l’analyzer expose le dénominateur utilisé :
massStatus est le même signal à trois états que les métriques de masse, et il change la façon de lire le chiffre :
precise— toutes les masses étaient connues exactement.estimated— certaines proviennent d’une densité ou d’un poids unitaire, donc le dénominateur est approximatif. Les renderers l’affichent~830 g.incomplete— une partie de la masse n’a pas pu être résolue : le dénominateur est une borne inférieure, et la densité est donc surestimée, et non sous-estimée. Les renderers l’affichent>830 g.
Le dénominateur est la masse des ingrédients ayant contribué des macros, et non le totalMass de la recette. Les deux peuvent légitimement différer — un ingrédient dont le poids est connu mais sans données nutritionnelles a une masse sans calories — et diviser l’un par l’autre sous-estimerait silencieusement la densité dans ce cas précis.
Les renderers précisent duquel des deux il s’agit, car à couverture complète le dénominateur est la masse crue de la recette, alors qu’à couverture partielle il ne l’est pas :
coveragevaut 1 → « Sur 830 g d’ingrédients, avant cuisson »coverageest inférieur à 1 → « Sur les 830 g renseignés, avant cuisson »
La seconde formulation évite qu’un chiffre de 830 g se lise comme le poids d’une recette qui en pèse davantage.
D’où viennent les valeurs
Section intitulée « D’où viennent les valeurs »Gram ne fournit pas de base de référence nutrition/densité — ces valeurs sont propres à chaque produit, chaque région et chaque pays, donc seul vous pouvez réellement garantir ce que vous avez dans votre cuisine. gram db enrich peut proposer des valeurs via l’IA, mais chaque proposition passe par une revue interactive avant d’être écrite, et tout ce qui est accepté sans modification est tagué # [LLM] dans ingredients.yaml pour rester visiblement non vérifié.
Pour un retour d’expérience complet sur ce choix de conception et les raisons de l’abandon d’une base centrale comme le CIQUAL ou l’USDA, découvrez l’article de blog : Pourquoi Gram génère votre base d’ingrédients au lieu d’en intégrer une.
Gestion des modificateurs
Section intitulée « Gestion des modificateurs »Les modificateurs de syntaxe de Gram ont un impact sur les calculs nutritionnels de manières spécifiques :
- Ingrédients Optionnels (
?) : Les ingrédients marqués comme optionnels (ex :@?crème chantilly) sont exclus des totaux nutritionnels de base. L’Analyseur suppose le profil diététique le plus conservateur. - Alternatives (
|) : Lorsqu’une recette propose des alternatives (ex :@beurre{50 g} | @huile{40 g}), l’Analyseur ne calcule la nutrition que pour la première option (préférée). Il ne fait pas la moyenne entre elles. - Ingrédients Composites (
<@) : La nutrition d’un composite est calculée strictement à partir de ses enfants. Chacun est recherché indépendamment dans la base de données via son propre identifiant (ex :jus de citronetzeste de citronsont deux entrées distinctes avec des macros spécifiques). Il n’y a pas de système de repli (fallback) vers les macros du parent : si un enfant n’a pas de blocnutrition, il est traité comme n’importe quel ingrédient manquant, lève un avertissementMISSING_MACROSet ampute lacoverage, plutôt que d’être grossièrement estimé depuis son parent.