Can AI fill in a food's missing micronutrients?
We deleted the micronutrients from 250 lab-tested foods and asked a model to put them back.
Food databases are rich in calories and thin in micronutrients. A branded yoghurt will list energy, protein, carbs and fat, and say nothing at all about magnesium, folate or zinc. So a day that looks complete in a tracker is usually a day with holes in it. An AI model can guess what belongs in those holes. The question is whether the guess is worth showing.
We had an unusually good way to check. Pensum ships a catalogue of 16,358 foods from three national food composition databases, and 11,504 of those rows carry all twelve micronutrients we track, measured in a lab. Delete the micronutrients from a row and what is left, a name and its macros, is exactly what our estimator receives in the app. The measured values stay behind as an answer key. That gives us a benchmark with real ground truth and no annotation work.
How we measured it
- Real ground truth. 250 foods drawn from the German (BLS), US (USDA) and Swiss (FSVO) databases, balanced across all three. Every one has all twelve micronutrients measured.
- The real engine. We replay the exact system prompt and the exact strict JSON schema the shipping app sends, so this measures the product, not a lookalike.
- Two difficulty tiers. Single-ingredient foods (Parsnips, raw) against multi-ingredient dishes (Ham pie with shortcrust pastry, baked). The split was made by a different AI model than the one under test, so the system being measured does not get to decide which cases count as hard. Foods it could not confidently place were discarded rather than forced into a bucket.
- Two provenance conditions. Once with the catalogue's real macros as the anchor, and once where the model first invents the macros from the name and then estimates micronutrients off its own guess. The second is what an AI-generated diary entry actually looks like end to end.
- A floor to beat. Every result is compared against a deliberately stupid baseline: ignore the food entirely and predict the catalogue-wide median for that nutrient. If the model cannot beat a constant, the feature is theatre.
We report the median error rather than the mean. When a true value sits near zero a single ratio can run to thousands of percent, and a mean quietly becomes a report on that one row.
Finding 1: it clears the dumb baseline by about three times
| Condition | Food type | Median error | Within 2x |
|---|---|---|---|
| AI estimate, real macros | Single ingredient | 25% | 78% |
| AI estimate, real macros | Mixed dish | 33% | 76% |
| Predict the catalogue median | Single ingredient | 76% | 42% |
| Predict the catalogue median | Mixed dish | 69% | 46% |
Shipped model, 125 foods per tier, twelve nutrients each.
So the model is genuinely reading the food, not regurgitating an average. That is the minimum bar, and it clears it comfortably. It is not the same as being accurate.
Finding 2: minerals are solid, vitamins are not
The single number hides the most important result. Split by nutrient and the twelve fall into two clearly different groups.
| Nutrient | Median error | Bias | Within 2x |
|---|---|---|---|
| Magnesium | 15% | 0% | 94% |
| Potassium | 15% | -5% | 92% |
| Zinc | 20% | 0% | 95% |
| Sodium | 26% | 3% | 83% |
| Calcium | 27% | 0% | 83% |
| Iron | 29% | 5% | 86% |
| Folate | 33% | -7% | 74% |
| Vitamin B12 | 41% | 2% | 70% |
| Vitamin E | 45% | -14% | 67% |
| Vitamin A | 59% | -39% | 51% |
| Vitamin D | 60% | -44% | 54% |
| Vitamin C | 73% | -51% | 44% |
Magnesium, potassium and zinc land within 15 to 20% and are almost never wildly off. Vitamin C is wrong by 73% at the median and lands outside a factor of two more than half the time. Treating "micronutrients" as one feature with one accuracy would be misleading: the same model is useful on minerals and unreliable on vitamins.
There is a reason for the split. Mineral content is largely a property of the raw material and moves within a fairly narrow band. Vitamin content swings enormously with variety, freshness, storage, cooking and fortification, and no amount of reasoning about a name recovers information that the name does not carry.
Finding 3: the vitamin errors run one way, and it is downward
Look at the bias column. The minerals sit at or near zero, which is what an unbiased estimator looks like. The vitamins are all negative, and heavily so: vitamin C at -51%, vitamin D at -44%, vitamin A at -39%. The model does not scatter around the truth on vitamins. It systematically guesses low.
The failure cases show why. The model refuses to believe extreme foods:
| Food | Nutrient | Lab | Estimate |
|---|---|---|---|
| Rose hip, raw | Vitamin C | 1045 mg | 426 mg |
| Boiling fowl giblets, boiled | Vitamin A | 3938 µg | 1200 µg |
| Oyster, canned | Zinc | 91 mg | 40 mg |
Per 100 g. These are real rows from the benchmark, not constructed examples.
Rose hips really do carry more vitamin C than almost any other food, and liver really is an extraordinary source of vitamin A. The model knows these are high and still lands well short, because a plausible-sounding number is closer to the middle of the distribution than the truth is. Vitamins have far more of these extreme foods than minerals do, which is exactly why the vitamin bias is negative and the mineral bias is not.
Finding 4: mixed dishes are harder, and they fail in the opposite direction
A dish is the case this feature will actually meet in a diary, and it is measurably worse: 33% median error against 25% for single ingredients, and the typical error in daily terms roughly doubles. That is the expected direction. The interesting part is that dishes break differently.
With a single ingredient the model shrinks toward the average. With a dish it does the opposite: it anchors on the ingredient in the name and forgets that the dish is mostly other things. Canned chicken liver pate is measured at 217 µg of vitamin A per 100 g. The model answered 5500, roughly 25 times too high, because it estimated liver rather than pate. The pastry, fat and filler that make up most of the product never entered the guess.
This is the same failure that makes an AI-generated "Burrito" entry hard to trust. The name names an ingredient. The plate is a ratio, and the ratio is what nobody wrote down.
Finding 5: an AI-generated entry barely makes it worse
We expected the fully-AI path to compound badly: if the model invents the macros and then estimates micronutrients from its own invented macros, two layers of guess sit on top of each other. It costs less than we assumed.
| Food type | Real macros | AI-invented macros |
|---|---|---|
| Single ingredient | 25% | 26% |
| Mixed dish | 33% | 37% |
One to four points. The reason is a little deflating: the macros were never carrying much of the estimate. The model is mostly recalling what it knows about the food from its name, and the macro anchor is a sanity check rather than a source of information. Useful to know, because it means the estimate on a photo-logged meal is not meaningfully worse than the estimate on a database food.
Finding 6: the more expensive model was worse
We ran the whole benchmark a second time against a larger frontier model, expecting to find a quality ceiling we were leaving on the table. It lost on every cell.
| Model | Single ingredient | Mixed dish |
|---|---|---|
| Shipped model (a fast, cheap tier) | 25% | 33% |
| Large frontier model | 28% | 42% |
This matches what we found benchmarking the photo feature: on food composition, model size is not the bottleneck. The bottleneck is that the information is not in the name. We are keeping the cheaper model, which also keeps this feature cheap to run.
What the error looks like on the daily bar
Percentages are unintuitive here, because being 300% wrong about the vitamin D in lettuce moves nothing. So we also scored every estimate in percentage points of the EU daily reference value, which is what actually moves on screen.
The typical estimate is off by under one point of the daily bar for a single food, and under two for a dish. That is small. But the tail is not: one estimate in ten is off by roughly ten points or more, and the worst cases in this run were off by hundreds. A micronutrient row that looks 40% covered could be 30% or 55%, and occasionally it could be badly wrong in either direction.
What this changed in the app
Two things, both of them about not overstating what we know.
- Estimated values are drawn in a different colour. On every micronutrient bar, the share of the value that came from an AI estimate is painted in the same orange used to flag estimated data everywhere else in Pensum, and the measured share stays green. You can see at a glance how much of that bar is real. Given Finding 2, this matters most on the vitamins, which is where the orange tends to appear.
- Estimates never overwrite measured data. The estimator only fills gaps. A known value, including a known zero, always wins, and the estimate is stored as a separate overlay rather than written into the food. Removing it restores the original row exactly, and estimated values never leave the app in an export or a database contribution.
We are not gating the vitamins behind a warning or hiding them. A 60%-error estimate of your vitamin A is still more informative than a blank, as long as it is labelled as an estimate and you can tell which is which.
Caveats
- The answer key is not perfect either. National databases record a zero where a nutrient was genuinely absent and, sometimes, where it simply was not measured. A few of the model's largest apparent errors are on fortified products where the database says zero and the model assumed fortification. We have not tried to correct those, so a small part of the measured error is probably ours.
- Per 100 g, not per portion. Real diary error also depends on the portion size, which this benchmark does not test.
- English names only, since that is what all three databases share.
- The difficulty split is itself an AI judgement. It is a different model than the one under test, and ambiguous foods were dropped, but it is not a human annotation.
- 250 foods, one run. Directions are stable, individual figures will move.
The short version: this is a useful feature on minerals, a rough one on vitamins, and it guesses low on exactly the foods people take supplements for. That is why the estimated part of every bar is a different colour.
This is one of three pages where we show the arithmetic instead of describing it. The others cover how Pensum measures your energy expenditure and whether AI can estimate food weight from a photo.
Pensum is a fast, private macro tracker built on national food databases (USDA plus German and Swiss sources). Download Pensum for Android, or go back to the homepage.