Short answer: if you put a GenAI assistant on top of winery data without a governed metric layer, it will answer “what is the potential alcohol on the Shiraz lots?” with whichever of your three hidden conversion factors it happens to find. At 24 Brix those factors disagree by 1.7 points of alcohol, which is wider than a label tolerance. The model is not the problem. The undefined metric is. Define potential alcohol once, with its parameters in the open, build the pipeline so every reading carries its instrument, point the assistant at the semantic layer instead of raw tables, and test it with twenty questions the cellar actually asks.
A winemaker types into the new data assistant: “What’s the potential alcohol on the Shiraz lots?” It answers in two seconds, with a tidy table. The assistant is right, in the sense that the number exists somewhere. It is also wrong, because the lab’s workbook would have said something else, and the label artwork file something else again.
Nobody in that building made a mistake. Somebody typed a conversion factor into a cell years ago, the cell got copied into the next vintage’s workbook, and now three versions of the same metric live in three files. A person knows which file to trust. A text-to-SQL agent does not. This is the first post in The Cellar Ledger, a series on the data engineering and GenAI work that sits under a winery’s numbers, and it starts with the number everyone uses and nobody has defined.
Why GenAI makes an old problem louder
Every chat-with-your-data product on the market in 2026 works roughly the same way. You ask a question in English. The assistant reads some description of your data, writes a query, runs it and summarises the result. Power BI Copilot, Databricks AI/BI Genie and Snowflake Cortex Analyst all follow this pattern, and all three read a semantic model or a set of curated instructions first if you give them one.
If you do not give them one, they read the tables. And a table column called pot_alc tells the model nothing about which factor produced it.
Two things then go wrong at once:
- The answer is unstable. Rephrase the question slightly and the agent may join a different table, pick a different column and return a different number, with the same confident tone.
- The answer looks authoritative. A spreadsheet with a wrong number looks like a spreadsheet. A chatbot with a wrong number looks like the system. People check spreadsheets. They mostly do not check the chatbot.
The old problem was three people working from three wines. The new problem is that the assistant sends each person whichever of the three wines the prompt happened to reach.
The metric underneath: what the conversion really is
To define potential alcohol once, you have to know what the rules of thumb are hiding. Brix times 0.55, 0.59 or 0.62 is a shortcut for a four-step calculation, and each step is a parameter someone should own.
1. Brix to density. Degrees Brix is grams of sucrose per 100 grams of solution, weight for weight. A standard polynomial for sucrose solutions gives a specific gravity of about 1.101 at 24 Brix.
2. Dissolved solids per litre. Brix times SG times 10. For our must, about 264 g/L.
3. Subtract what is not sugar. Grape must is glucose and fructose plus acids, minerals and phenolics. The non-sugar solids are typically somewhere around 20 to 30 g/L in ripe fruit. Take 25 and you have about 239 g/L of fermentable sugar.
4. Sugar to alcohol. In theory, one glucose molecule gives two of ethanol and two of CO2, so about 15.4 g/L of sugar makes 1% alcohol by volume. Real yeast builds cells, makes glycerol and loses some ethanol with the gas, so working figures sit higher. The EU uses 16.83 g/L per 1% vol. 239 divided by 16.83 is 14.2%.
Written as a function, the whole thing is short:
def potential_alcohol(brix, non_sugar_gl=25.0, yield_gl_per_pct=16.83):
sg = 1 + brix / (258.6 - (brix / 258.2) * 227.1)
sugar_gl = brix * sg * 10 - non_sugar_gl
return sugar_gl / yield_gl_per_pct
The point is not the code. It is that non_sugar_gl and yield_gl_per_pct are now named, visible and owned. The shortcut factors hide both, which is why they disagree.
It matters because tolerances are measured in single points. In the US, a wine at or under 14% may be labelled within 1.5 points of the truth, and above 14% within 1 point, and the label may not cross the 14% line because the excise rate changes there. A 1.7 point spread across the building is bigger than the tolerance it has to stay inside.
The data engineering fix: instrument-aware layers
Defining the metric is half of it. The other half is making sure the inputs mean what the metric assumes. This is where a lot of winery data breaks before any AI gets near it.
A refractometer is fine in the vineyard. Once fermentation starts, alcohol raises the refractive index, so a refractometer overstates the remaining sugar, more so as the wine gets drier. A hydrometer measures density, and ethanol is lighter than water, so a dry red reads about minus 1 to minus 2 Brix. Both are correct readings of what the instrument measures. Both become wrong the moment a pipeline stores them in one column called brix.
A simple medallion layout handles this without heroics:
- Bronze keeps every reading exactly as taken: value, unit, instrument, who, when, which tank. Nothing is converted and nothing is thrown away.
- Silver adds context the pipeline can derive: the fermentation phase (pre-inoculation, active, dry) from the tank’s own events, and a flag on any refractometer reading taken after inoculation. Hydrometer readings mid-ferment are renamed to what they are, density, and allowed to go negative.
- Gold and the semantic layer hold the governed metrics.
potential_alcoholonly reads pre-inoculation sugar readings. Once a finished lot has a measured alcohol from the lab, a separatealcohol_measuredtakes over and the prediction retires for that lot.
Put a data contract on the bronze table that rejects a reading with no instrument. It is one line of validation, and it is the line that stops the next vintage’s ambiguity at the door instead of in a board report.
Pointing the assistant at the right layer
With the metric defined, the GenAI part becomes much less exciting, which is what you want. Three settings do most of the work:
- Restrict the assistant to the semantic model. Do not give it the raw tables at all. If it can only see
potential_alcoholas a measure, it cannot invent a fourth version. - Write the instructions like a cellar manual. Most of these tools accept plain-text instructions. Use them for the domain facts the model cannot guess: “Brix after inoculation is density, not sugar”, “alcohol on a finished lot comes from
alcohol_measured”, “volumes are in litres at 20 degrees C”. - Make it cite the method. Ask for the metric name and its parameters under every answer. A winemaker who sees “potential alcohol, EU yield 16.83 g/L, non-sugar 25 g/L” can argue with the assumption instead of with the number.
A twenty-question eval set
The last step is the one teams skip. Before anyone relies on the assistant, write down twenty or so questions the cellar actually asks, with answers someone has checked by hand. “Potential alcohol on lot 24-SH-03.” “Which tanks are still above 5 Brix?” “Measured alcohol on last year’s Viognier.” Run the set every time the model, the prompt or the semantic model changes, and score exact numeric matches.
It is a small file. It is also the only honest answer to “can we trust the chatbot?” You do not trust it. You test it, the same way the lab tests a new instrument against a reference before it goes into use.
Here is the bonus. Every finished lot gives you a pair: starting sugar and measured alcohol. A few vintages of those pairs, by variety, let you fit your own yield figure to your fruit, your yeast and your cellar. That is the first genuinely useful model in the building, and it only exists because the pipeline kept both numbers.
Where this breaks
The non-sugar estimate is still a guess. It moves with variety, ripeness, rot and press fraction. A stated default is better than a hidden one, but measure it on a few musts each year and treat it as provisional.
A semantic layer does not fix bad sampling. Juice from the sunny end of one row does not describe a block. No metric definition corrects the bucket.
Instructions drift. The plain-text guidance you give the assistant is configuration. Version it, review changes, and re-run the eval set when it changes, or it quietly becomes the fourth spreadsheet.
Rules vary by market. The US tolerance figures above are the ones I know best. Check the market you sell into before you build a labelling check on them.
The bottom line
The chatbot gave three answers because the winery had three answers. GenAI did not create that problem. It just stopped hiding it. Define the metric once with its parameters in the open, keep every reading with its instrument, let the assistant see only the governed layer, and hold it to a small set of checked questions. Then the two-second answer is worth having.
For the wider argument about why winery dashboards lose the cellar’s trust, see Why Power BI Dashboards Die in Wineries. What a model can do with a clean fermentation curve is in AI for Wine Fermentation Control. Next in this series: event-sourcing the cellar, the data model that makes volumes add up. The full list is on the Cellar Ledger series page.
Frequently asked questions
Why does a chat-with-your-data assistant give different answers to the same question? Usually because the metric is not defined anywhere the assistant can see. A text-to-SQL agent writes a query against whatever columns look plausible. If potential alcohol is calculated in three workbooks with three different factors, the agent picks one, and a slightly different prompt picks another. The fix is to define the metric once in a governed semantic layer and point the assistant at that, not at raw tables.
What should a winery put in its semantic layer first? The numbers people argue about: potential alcohol, residual sugar, volume on hand, loss, and yield per tonne. Each gets one definition, stated parameters such as the sugar-to-alcohol yield figure, and a named owner. Those are also the questions a GenAI assistant will be asked most, so they are where a wrong answer does the most damage.
How do you test a GenAI data assistant before the winemaker uses it? Write twenty or so real questions the cellar asks, with answers a person has checked by hand, and run them every time the model, prompt or semantic model changes. Score exact match on the numbers. It is a small evaluation set, and it catches most regressions before a winemaker does.