Shelf Price Decision Systems: Demand Model, Grid, and Gate

Most “pricing ML” demos train a model that spits out a dollar figure and call it done. That works in a notebook. It fails the first week a category manager asks why milk moved 12 cents when the rival across the car park did not, or why we broke a volume promise on a house-brand twin.

Here is the one-sentence version: I do not predict shelf price — I train a demand model, score a small price grid, and pick the candidate that maximises margin after volume and competitive-anchor penalties, then I refuse the move unless improvement clears a dollar and percent gate.

That pattern is AI architecture for commercial decisions: classical ML plus explicit business rules, not a chat model inventing stickers. When people say enterprise AI architecture, this is the shape I mean in production — not model shopping. Examples below use Harbourline Mart — a fictional multi-store grocer name I made up for this series, not a real company — so the shapes stay concrete without leaking any real employer. Engineers get the loop and contracts. Managers get one scoreboard: can we show the runner-up prices and why we held or moved?

What the architecture owns for shelf pricing

Here that means the design of how demand estimates, cost, rival prices, and policy become an auditable shelf recommendation — data contracts, model boundaries, optimiser objective, publish path, and refusal rules. The LightGBM binary is one component. Most production pain lives outside it.

Analogy: think of the weekly specials board. You do not ask a black box “what should the sticker say?” You estimate how many units move at each plausible sticker, subtract COGS, check you still look sane versus the store down the road, and only change the board if the upside beats noise. Same judgment, encoded as software.


Three-stage shelf price decision loop: demand model, score the grid with penalties, decide and ship; Azure path Blob to Azure ML to PostgreSQL to App
Three stages own different contracts: demand estimates units, the optimiser owns commercial trade-offs, the gate owns “do nothing.” Azure is the plumbing, not the strategy. Click image to zoom.

Predict the price vs decide the price

This is the fork that decides whether you built a demo or a system merchandising will trust.

Dimension Predict the sticker Decide with a grid
Model output A single price ŷ Demand û at many candidate prices
Who owns policy Buried in training labels Explicit objective + penalties
Rival awareness Hope features encode it Anchor penalty on the scored candidates
“Do nothing” Unnatural — model always speaks Native — gate vs current shelf price
Audit story “The model said so” Runner-up grid + reason codes

Side-by-side: predict the sticker path versus decide with demand curve, grid scoring, and change gate
Same inputs, different contract. If you cannot show runner-ups and a hold decision, you still have a price model — not a price decision system. Click image to zoom.

I still use dynamic pricing machine learning language with stakeholders when it helps them search their own notes. Under the hood I mean a price decision system: demand first, commercial objective second, publish third.

The three-stage loop (Harbourline Mart — fictional)

In this walkthrough, fictional Harbourline Mart runs dozens of stores. For each store × SKU family (house brand vs branded twin treated carefully — more on that in part 2), the daily loop looks like this.

1. Demand model — predict units, not dollars

Features include own price history, lags and rolls, calendar/weekday effects, promo flags, and distance-weighted competitor shelf prices. The target is units sold (or a basket-volume proxy), not “the right price.” I prefer one model family per store×product slice with shared feature definitions — local elasticity, shared playbook.

Monotonic constraints on own-price features keep the demand curve from doing physics-breaking tricks in the tails. That is boring classical ML, and boring is good when money moves.

2. Score a small shelf-price grid

Around the current sticker (and sometimes a promo anchor), I build a small step grid — think 5-cent steps, not a continuous optimiser that invents $4.173. For each candidate price p:

  • Predict demand û(p), optionally with a simple competitor-response assumption
  • Contribution ≈ (p − unit COGS) × û(p)
  • Subtract a shortfall penalty if û falls under the expected units for that weekday and margin band
  • Subtract an anchor penalty if p wanders outside a distance-weighted rival band plus historical differential

Objective in one line:

score(p) = contribution(p) − shortfall_penalty(p) − anchor_penalty(p)
p* = argmax score(p) over the grid

Part 3 of this series unpacks the penalties and objective weights in depth. Part 1 only needs the shape: the optimiser is where business policy lives, not inside gradient leaves — and the dual change gate already defined here stays the publish rule.

3. Decide — gate the move, then publish

Even if p* wins the grid, I compare it to today’s shelf price. If either the dollar lift or the percent lift fails its threshold, I hold — both legs must clear. That is the difference between a decision system and a twitchy sticker bot.

Publish writes a recommended price, scores for the top candidates, and reason codes (margin, shortfall, anchor, gate). Humans still own the board; software owns the evidence pack.

Cadence beats hero models

Cadence Job Why it is separate
Daily Feature build + freshness checks Sales, costs, rival scrapes drift every day
Weekly Train / retrain demand models Stable enough for elasticity; cheap enough to schedule
Frequent Score grid + gate + write decisions Rivals and own costs move inside the week
On read App / API serves latest decision pack Training cluster stays off the hot path

If you collapse train and serve into one overnight “recompute the universe” job, you will either score stale rivals or retrain too often. Split the cadences on purpose.

Azure path at hub height

I keep the cloud story boring on purpose — same idea as the AI architecture boundaries post: platform choices should not hide weak decision contracts.

  1. Blob / Data Lake — daily feature tables, model artifacts, metrics bundles
  2. Azure Machine Learning jobs — orchestrator + batch workers for train and score (part 4)
  3. PostgreSQL — decision rows, candidate scores, reason codes (upsert, not blind insert)
  4. App Service / Static Web Apps + APIM — pricing UI and internal APIs for store tools

That is enough for an AI solution architect conversation without turning part 1 into an ARM template. The read path must not require a live training cluster. The write path must be idempotent when score jobs retry.

Scoreboard for engineers and managers

Question Healthy answer Smell
What does the model output? Demand (units) at candidate prices A lone “optimal price”
Where do commercial rules live? Objective + penalties + gate Prompt text or tribal knowledge
Can we hold? Yes — both $ and % legs must clear Every SKU moves every run
Can we explain p* vs runner-up? Candidate table + reason codes SHAP dump with no commercial story
Is the hot path train-free? App reads decisions DB UI waits on a training job

This sits next to how I think about security-reviewable AI decisions and production RAG failure modes: separate “did the model run?” from “did we make a defensible choice?” Integration-style boundaries still matter when the “system of record” is a shelf board instead of a queue — see the config-driven integration patterns series for the Azure Functions side of that plumbing.

Series roadmap

Part Focus You should leave able to…
1 · this post Hub: predict vs decide, stages, cadence, Azure sketch Redraw the three-stage loop
2 Multi-store demand features + LightGBM per store×product Name the feature families and split traps
3 Grid objective: margin, shortfall, competitive anchors Write the score function without hand-waving
4 Azure ML jobs, storage handoffs, production gaps List the first five ops fixes before “more models”

I alternate this series with Azure integration deep dives so neither lane starves. Part 2 lands after the next integration post in the queue.

What I refuse to ship in part 1

  • A model that outputs price as the only artifact
  • LLM-written stickers without a demand curve and gate
  • Vertical commodity or employer-branded scenarios dressed up as “generic grocery”
  • A continuous optimiser that invents non-board prices ops cannot print

Mild opinion: if your pricing deck leads with model brand names and buries the objective function, you are selling theatre. Put the objective on slide two.

FAQ

Is this the same as dynamic pricing machine learning?
Searchers use that phrase; I use it as a secondary. Operationally I mean a price decision system: demand model + scored grid + commercial penalties + change gate. Dynamic without a gate is just automated twitching.

Why not let an LLM set Harbourline Mart’s shelf prices?
(Reminder: Harbourline Mart is fictional.) Language models are weak at stable multi-constraint numeric trade-offs across thousands of store×SKU cells, and worse at auditable “why this 5¢ step.” Use LLMs for explanation copy over structured decision packs if you must — not as the optimiser.

Do I need Azure specifically?
No. The architecture is storage → train/score jobs → decisions database → app read. Azure ML + Blob + PostgreSQL + APIM is one solid production shape. The contracts matter more than the logos.

Does this still count as enterprise AI architecture if there is no agent?
Yes. The label is about boundaries, evidence, and operable decisions under policy — not about whether a planner loop is involved. Shelf pricing is a high-stakes batch decision system. Agents are optional later for exception workflows, not a substitute for the grid.

What unit does the demand model predict?
Units sold per store×SKU family per day (or a basket-volume proxy) — always with a path back to contribution dollars, not an abstract “demand index.”

When should the system do nothing?
When the best grid candidate does not clear both the dollar and percent legs of the improvement gate versus the current shelf price, or when data freshness/quality checks fail before scoring. Holding is a first-class outcome.


Part 1 of the Price Decision Systems series (grocery). Harbourline Mart is a fictional brand used only as a teaching example. Next up in this lane: multi-store demand features and per-location LightGBM — after the interleaved Azure integration post.

Similar Posts