Short answer: when a grower phones to say block 7 may have a residue problem, the question is which bottles contain block 7 fruit, and in what share. If the cellar is recorded as a graph of lots and volume-weighted movements, that is a recursive query that runs in seconds. Put a GenAI agent in front of it through a few MCP tools (trace back, trace forward, bottling status) and a winemaker can ask the question in plain English and get an answer with every percentage computed by tested code. The agent writes the recall memo. It never decides the recall.
It is a Tuesday in September and a grower phones. A spray on block 7 may have gone on inside the withholding period. Nobody knows yet whether it matters, but the winery needs to know, today, where that fruit went. Which tanks? Which blends? Which bottlings, and which of those have already shipped?
In most wineries that becomes a two-day job with a stack of work orders and a spreadsheet. It does not need to be. The movement ledger from earlier in this series already holds every answer. It just needs to be read as a graph.
The cellar is a graph already
Every lot of wine is a node. Every movement is an edge with a volume on it. Fruit from a block goes into a tank. Part of that tank goes into another tank that already holds something else. Two tanks are blended into a third, which is bottled.
When wine moves into a vessel, the new composition is a volume-weighted average:
new share = (volume already there x its share + volume arriving x its share) / total volume
In the figure, tank B held 7,000 litres of block 9 and received 3,000 litres of block 7, so it is 30% block 7. Bottling lot D takes 5,000 litres from B and 5,000 from C, so it is 15% block 7. That is the whole mechanism. It just has to be applied to every movement in the right order, which is exactly what computers are for and exactly what people in a hurry get wrong.
The recursive query
You do not need a graph database for this. A winery has thousands of movements a year, and a recursive common table expression in the warehouse you already run walks them comfortably.
WITH RECURSIVE forward AS (
SELECT to_lot AS lot_id, share AS source_share, 1 AS depth
FROM lot_edges
WHERE from_lot = 'BLOCK-07-2025'
UNION ALL
SELECT e.to_lot, f.source_share * e.share, f.depth + 1
FROM forward f
JOIN lot_edges e ON e.from_lot = f.lot_id
WHERE f.depth < 30
)
SELECT lot_id, SUM(source_share) AS block7_share
FROM forward
GROUP BY lot_id;
Here share on each edge is the fraction of the destination lot that came from the source lot, computed once in the silver layer from the ledger volumes. Walk the edges forwards from a block and multiply the shares along the way: that gives every downstream lot and how much of the block it contains. Walk them backwards from a bottling lot and you get its full recipe, down to vineyard blocks.
The depth limit is not decoration. Barrel programmes with years of topping create long chains, and a stray loop from a data-entry error will otherwise run until the warehouse gives up.
The same query proves the label
Genealogy is not only for bad days. The same composition answers the question the marketing team asks every vintage: can this blend carry the label we want?
The thresholds vary by market. In the EU, a variety or vintage on the label generally needs at least 85% of the wine to qualify. In the US, a varietal name needs 75% in most cases, an AVA needs 85%, and a vintage date needs 95% when an AVA is named and 85% otherwise. Those percentages are exactly what a backwards trace produces: share of the lot by variety, by vintage and by origin. Put the rules for your markets in a small table and a check can tell you, before the artwork is printed, whether a blend clears them and by how much.
Putting a GenAI agent in front of it
A winemaker should not have to write a recursive CTE while the grower is still on the phone. This is a good job for an agent, if the agent is built so it cannot get the numbers wrong.
The Model Context Protocol (MCP) is the standard way to give a language model a set of tools in 2026. For traceability, three tools are enough:
trace_forward(source, min_share)returns every lot and bottling containing a block or lot, with shares above a threshold.trace_back(lot)returns the full composition of a lot by block, variety and vintage.bottling_status(lot)returns cases produced, on hand and shipped, and to whom.
Each tool is a tested query. The agent’s job is to understand the question, call the right tools in the right order and write up what they return. Asked “where did block 7 go, and has any of it shipped?”, it calls trace_forward, then bottling_status for each bottling it finds, and produces a short memo: two tanks still in the cellar, one bottling at 15% block 7 with 400 cases shipped to three distributors, and the list of those distributors.
A few rules keep it trustworthy:
- Read-only tools. The agent can look but not move wine or change records. Holds and recalls are actions a person takes.
- Numbers come from tool output only. The memo quotes the shares and case counts the tools returned. If the model computes a figure itself, that is a bug in the prompt.
- Test it with mock recalls. Many food and drink regimes expect you to trace one step back and one step forward, and good wineries run mock recall drills. Turn the last few drills into a test set with known answers and run the agent against them whenever anything changes.
The difference is time. A recall question that used to take two days of paperwork takes a few minutes, and the winemaker spends those minutes checking the answer instead of assembling it.
Where this breaks
Composition assumes perfect mixing. The maths treats a tank as uniform. A tank that was topped without being stirred, or drawn from before a blend was mixed, is not. For recall purposes, assume the worst case and trace with generous thresholds.
Topping creates dust. Years of topping barrels from mixed sources leaves thousands of tiny fractions: 0.2% of this, 0.05% of that. Decide on a threshold below which a source is reported but not chased, and state it in the memo.
The graph is only as good as the ledger. One unrecorded transfer breaks the chain, and the trace will say block 7 stopped at tank B when it did not. The adjustment events from the loss map are a good early warning of where the chain is weak.
The agent must not decide. Whether to hold stock, notify distributors or recall is a judgement with legal and commercial weight. The agent gathers the facts fast. A person signs the decision.
The bottom line
Every blend is a graph, whether or not the winery records it as one. Store the movements with their volumes, calculate composition once in the pipeline, and a recursive query answers the hardest question a grower can ask. Wrap those queries as MCP tools and a GenAI agent can answer it in plain English, with every percentage coming from code you have tested. The model makes the answer quick to reach. The ledger is what makes it right.
Next in the series: excise returns as data contracts, where the same ledger has to reconcile to the taxman. Blending from the other direction, choosing components to hit a target, is covered in AI for Wine Blending Optimisation. The full list is on the Cellar Ledger series page.
Frequently asked questions
How do you trace a wine blend back to the vineyard block? Treat every lot as a node and every movement as an edge carrying a volume. When wine moves into a vessel, the new composition is the volume-weighted mix of what was there and what arrived. A recursive query walks the edges backwards from a bottling lot to its sources, or forwards from a vineyard block to every lot and bottling that contains it, multiplying the shares along the way.
Do you need a graph database for winery traceability? Usually not. A winery has thousands of movements a year, not billions, and a recursive common table expression in the lakehouse or warehouse you already run handles that comfortably. A graph database becomes worth it when you have many sites, very long barrel histories, or you want graph algorithms beyond tracing.
What does MCP add to a winery recall agent? MCP, the Model Context Protocol, is a standard way to give a language model a set of tools. For a recall agent, the tools are trace_back, trace_forward and bottling_status, each running a tested query. The model decides which tool to call and writes up the result, but every share and volume comes from the tool, not from the model’s own arithmetic.