Skip to content

anchauha/demand-forecasting-copilot

Repository files navigation

Demand Forecasting Copilot

Forecasting for slow-moving retail SKUs, where most days have zero sales and ordinary time-series models fall apart. The project pairs an intermittent-demand forecasting pipeline with an agent and a domain knowledge base, served from a live AWS deployment and driven from a React dashboard.

Forecast Explorer: a smooth-demand SKU routed to LightGBM, with its forward forecast and feature-importance drivers

The problem

At the item-store-day level, most retail SKUs sell nothing on a given day. In the M5 (Walmart) dataset, 51% of days are zero and 87% of series are intermittent or lumpy. MAPE is undefined when the actual is zero, so accuracy is measured with WAPE and MASE, and the models that actually work are the intermittent-demand family (Croston, SBA, TSB, ADIDA) alongside gradient-boosted trees.

Each series is classified by how often it sells (ADI) and how variable the quantity is (CV²), which gives four regimes: smooth, intermittent, erratic, and lumpy. Different regimes are won by different models, which is the idea behind the router below.

What it does

  • Forecaster. A ladder from naive baselines through the Croston family to a global LightGBM model, backtested per regime. A router picks the model that wins each regime, and forecasts are reconciled with MinT so they stay consistent across the item, department, store, and state hierarchy.
  • Copilot. A Bedrock agent over the forecast API. It sends simple lookups to a cheaper model (Haiku) and reasoning to a stronger one (Sonnet), and calls tools for forecasts, recent history, and driver explanations.
  • Knowledge base. A retail demand-planning corpus covering product categories, SNAP and holiday effects, weekly seasonality, and replenishment. The copilot can search it, so one assistant answers both "what is the forecast?" and "how do SNAP days move demand, and how much should I stock?"
  • Dashboard. A React UI over a FastAPI backend that ties the pieces together.

Results

Accuracy comes from a rolling-origin backtest: train before a cutoff, then score against the real sales after it. On the full M5 Foods set of 14,370 series, the regime-aware router lands ahead of every individual model on the held-out window.

In practice the gains over a well-tuned moving average are small, which is expected for intermittent demand. The lasting wins are per-regime routing, where LightGBM is about 6% better than the baseline on smooth SKUs, and hierarchical reconciliation, which drops the cross-level coherence error from 16.1 to 0 so the store, department, and total forecasts add up.

Demo

The same Forecast Explorer routes a smooth SKU to LightGBM and an intermittent one to TSB:

Smooth demand (LightGBM) Intermittent demand (TSB)
Smooth SKU routed to LightGBM with feature-importance drivers Intermittent SKU routed to TSB with recent-demand drivers

The copilot sends a simple lookup to a cheap model and a reasoning question to a stronger one:

Forecast lookup Reasoning with the knowledge base
Copilot answering a forecast lookup with the value and model Copilot combining a forecast with SNAP demand to recommend a stock level
A lookup: the agent calls the forecast tool and reports the value and model. A reasoning question: it combines the forecast with SNAP demand from the knowledge base and recommends a stock level.
Dashboard Knowledge base
System overview and headline numbers Grounded answer with cited sources
System overview and headline numbers. Grounded answers with cited sources.

Backtested WAPE by model and demand regime, plus hierarchical reconciliation

Architecture

React dashboard  ->  FastAPI backend (local)
                       /forecast, /history, /info  ->  local model or the AWS Lambda
                       /chat                        ->  Bedrock agent + tools
                       /rag                         ->  Qdrant + Bedrock
                       /results                     ->  reports/

train  ->  MLflow registry  ->  exported model  ->  Docker  ->  ECR  ->  Lambda + Function URL
drift monitor:  EventBridge (daily)  ->  Lambda  ->  CloudWatch metric + alarm  (reads from S3)

The forecast API and its monitoring run on AWS. The dashboard and backend run locally and call Bedrock and the deployed Lambda. The endpoint is never hard-coded. It comes from an environment variable or is read from the CloudFormation stack output at runtime.

Run it

uv sync                                      # Python environment
uv run poe api                               # FastAPI backend at http://localhost:8000
cd frontend && npm install && npm run dev    # React UI at http://localhost:5173

Common tasks:

uv run poe <task> What it does
check lint, format check, and tests
data, eda fetch M5, write the intermittency report
benchmark backtest the model ladder
reconcile hierarchical reconciliation
train train and register the production router
serve, api the lean forecast API, or the full backend for the UI
copilot, rag the agent and knowledge-base demos

Deploy with uv run poe export-model, then sam build and sam deploy (see infra/). Tear down with sam delete --stack-name spf --region us-east-1.

Tech stack

Area Tools
Language and tooling Python 3.12, uv, poethepoet, ruff
Forecasting Nixtla (statsforecast, mlforecast, hierarchicalforecast), LightGBM
MLOps MLflow, Docker
Cloud AWS Lambda, Function URL, ECR, S3, EventBridge, CloudWatch, SAM
Agent and RAG Bedrock (Haiku and Sonnet, Titan embeddings), Qdrant, Mangum
Frontend React, TypeScript, Vite, Recharts
CI pytest, pre-commit with gitleaks, GitHub Actions

Repo layout

src/spf/    data, intermittency, models, reconcile, evaluate, registry, serving, agent, rag
frontend/   React + TypeScript + Vite dashboard
kb/         retail knowledge base (RAG corpus)
infra/      Dockerfiles, SAM template, drift monitor
notebooks/  EDA, model benchmark, reconciliation
config/, tests/, reports/

About

Forecasts demand for slow-moving, hard-to-predict retail products. It picks the best forecasting method for each product's pattern, keeps the store/region/total consistent, runs in the cloud (AWS). Includes a chat assistant that explains forecasts and answers demand-planning questions (AI copilot + RAG), all viewable in a web dashboard (React)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors