AI Operations & Monitoring in Treasury
Building the model was the easy part. Keep it accurate, tested and auditable in production.
- 01The AI operations cycle, 3 types of drift and 8 KPIs for treasury AI
- 02Automation with Power Automate, a Power BI monitoring dashboard and 6 test types
- 03Audit trail, retraining triggers, and Microsoft Fabric for scale
- A live model monitor with a retrain trigger
- A pytest data validation suite
- An audit trail record script
Building the model was the easy part
An often-quoted industry estimate says most machine learning models never make it into production (87% is the number you will see). The ones that fail rarely fail because the model is bad. They fail because operations are missing.
Forecast error drifts from 5% to 22% over 6 months. Nobody notices until the CFO asks why the forecast is always wrong.
The business wins a major new customer. Cash flow patterns change. The model still predicts from the old data.
Someone updates a Python library. The output format changes. The Excel macro downstream breaks. The morning report fails.
The auditor asks: which model version produced this forecast? When was it last validated? Who approved the parameters? Silence.
The treasury AI operations cycle
This cycle runs continuously, monthly at minimum. Not once.
Model drift: when your forecast goes stale
Data drift. The input data changes.
Example: A new customer segment with different payment patterns.
DetectCompare current input distributions with the training data.
Concept drift. The relationship between inputs and outputs changes.
Example: COVID permanently changed cash flow patterns. A pre-COVID model is obsolete.
DetectTrack forecast error over time. A rising trend means concept drift.
Feature drift. A feature disappears or changes meaning.
Example: The bank changes its MT940 format. Transaction codes shift. Feature extraction breaks.
DetectMonitor null rates per feature. A sudden spike means feature drift.
All three end in retraining, but the fix is different: data drift may mean fixing the source, concept drift a new model, feature drift a repaired pipeline.
The treasury AI KPI framework
| KPI | What it measures | Target | Frequency |
|---|---|---|---|
| Forecast error (MAPE) | Average error vs actuals, on receipts and payments | < 10% | Weekly |
| Forecast bias | Over- or under-forecasting tendency | Within ±2% | Weekly |
| Data freshness | Age of the input data at forecast time | < 24 hours | Daily |
| Model uptime | % of scheduled runs completed | > 99% | Monthly |
| Exception rate | % of outputs needing manual correction | < 5% | Weekly |
| Retraining frequency | How often the model is retrained | Monthly minimum | Monthly |
| Drift score | Statistical distance: current vs training data | Below your threshold | Monthly |
| Audit completeness | % of AI outputs with a full audit trail | 100% | Monthly |
For net flow, which crosses zero, track the average error in EUR instead of MAPE (Module 9).
Automation: Power Automate for treasury AI
Four patterns. Each is a trigger and an action, built visually.
Run the Python forecast script
→ Forecast CSV saved to SharePoint
Parse the statement, match against the ERP, flag exceptions
→ Exception report emailed to the analyst
Forecast error above 10% for 3 consecutive weeks
→ Alert to the Treasury Manager + retrain flag
Generate the reconciliation report, compile board pack data
→ Draft board pack to the Treasury Director for review
Where does the Python run? A cloud flow cannot run a script on your laptop. Host the script in an Azure Function (or Azure Automation), or run it on a machine through a Power Automate Desktop flow. Triggering a desktop flow from a cloud flow needs a premium (RPA) licence. Agree this with IT before you promise a daily run.
Power BI: the model performance dashboard
Weekly forecast error over the last 12 months. Green below 7%, amber 7–10%, red above 10%. Shows degradation over time.
Predicted vs actual per week. The gap is the error. The visual for non-technical stakeholders.
A gauge for over- vs under-forecasting. Centered is good. Skewed is a systematic error to correct.
Completeness, freshness and null rates per source. Red flags fire before they hit the forecast.
The same four panels appear in the live monitor later in this module, so you can see what they tell you before you build them in Power BI.
Testing framework: what to test, when
| Test | What you check | When | Tool |
|---|---|---|---|
| Unit | Each function produces the expected output | Every code change | pytest |
| Data validation | Input passes the Module 8 quality checks | Every run | pytest / Great Expectations |
| Accuracy | Error metrics within thresholds | Weekly | Python script + Power BI |
| Regression | The new model version is at least as accurate as the old | Before redeployment | Backtest (Module 9) |
| Integration | End to end: data in > model > report out | Monthly | Power Automate test flow |
| Stress | Extreme scenarios: 2x volume, missing data | Quarterly | Synthetic data injection |
A data validation suite in 22 lines · tested
Five checks on the Module 8 clean dataset. Save it next to the CSV and run python -m pytest test_cash_data.py (install with pip install pytest). All five pass on the clean file. Run it on a file where missing receipts were interpolated and the reconciliation test fails, which is exactly its job.
import pandas as pd
FLOWS = ['receipts', 'supplier_payments', 'payroll', 'tax', 'intercompany', 'other']
def load(path='treasury_cash_flows_clean.csv'):
return pd.read_csv(path, parse_dates=['date'])
def test_no_missing_values():
assert load()[FLOWS].isnull().sum().sum() == 0
def test_no_duplicate_weeks():
assert not load()['week_number'].duplicated().any()
def test_weeks_are_consecutive():
assert (load()['date'].diff().dropna() == pd.Timedelta(days=7)).all()
def test_net_flow_reconciles():
df = load()
assert ((df[FLOWS].sum(axis=1) - df['net_flow']).abs() < 1).all()
def test_payments_are_negative():
assert (load()['supplier_payments'] <= 0).all()
The AI audit trail: what to document
| Field | Example | Where stored |
|---|---|---|
| Model version | cash-forecast v1.3 (Prophet), trained 2026-03-01 on 52 weeks | Model registry / SharePoint |
| Input data hash | SHA-256 of the input CSV. Proves which data was used. | Alongside the output file |
| Parameters | changepoint_prior_scale 0.05, regressors: payroll, tax | Config file in version control |
| Output summary | 13-week forecast, backtest error, 2 breach weeks flagged | Log database / Excel log |
| Validation | Reviewed by the Treasury Manager (name), approved 2026-03-15 08:42 | Sign-off log |
| Deviations | Manual override, week 45: +EUR 200K (new contract) | Override log with justification |
An audit record per run · tested
Run after the Module 9 script. It hashes the input and the output and appends one line per run to audit_log.jsonl. Reviewer and approval stay empty: a human fills them in at sign-off, never the script. No Python at hand? On Windows, Get-FileHash file.csv in PowerShell gives the same SHA-256.
import hashlib, json, os
from datetime import datetime, timezone
import pandas as pd
import prophet
def sha256(path):
with open(path, 'rb') as f:
return hashlib.sha256(f.read()).hexdigest()
fc = pd.read_csv('forecast_13_weeks.csv')
record = {
'run_at': datetime.now(timezone.utc).isoformat(timespec='seconds'),
'model_version': 'cash-forecast v1.3',
'library': f'prophet {prophet.__version__}',
'input_file': 'treasury_cash_flows_clean.csv',
'input_sha256': sha256('treasury_cash_flows_clean.csv'),
'parameters': {'changepoint_prior_scale': 0.05, 'regressors': ['is_payroll_week', 'is_tax_week'],
'train_weeks': 52, 'one_offs_excluded': [38]},
'output_file': 'forecast_13_weeks.csv',
'output_sha256': sha256('forecast_13_weeks.csv'),
'breach_weeks': int((fc['pessimistic_status'] == 'BREACH').sum()),
'reviewed_by': None, # filled in at sign-off, never by the script
'approved_at': None,
}
with open('audit_log.jsonl', 'a') as f:
f.write(json.dumps(record) + '\n')
print(json.dumps(record, indent=2))
Retraining: when and how
Scheduled (monthly). Add the latest 4 weeks, retrain, compare the backtest with the previous version. Deploy only if it is as good or better.
Drift alert (error above 10% for 3 weeks). Investigate first: data drift or concept drift? If data, fix the source. If concept, retrain with a longer window or different features.
Business event (major customer won or lost). Add the date as a changepoint and retrain on data from before and after the event.
Annual (full refresh). Rebuild from scratch: feature selection, parameter tuning, full backtest. Document everything.
from prophet import Prophet # A major customer was won on 2 March 2026: tell the model the trend may change there m = Prophet(changepoints=['2026-03-02'])
Prophet takes changepoints as a list when you create the model. There is no separate "add changepoint" method (checked on Prophet 1.1.7 and 1.4). Never set and forget: retraining is maintenance, not failure.
Build a monitoring dashboard with vibe coding
The Module 5 method, applied to AI operations. Paste the prompt into Claude (Artifacts) or any AI tool that builds interactive apps, then refine.
Build me an interactive AI Model Monitoring Dashboard as a React artifact. PURPOSE: A treasury team monitors the performance of its cash flow forecasting model. DATA: Pre-fill 12 weeks of simulated monitoring data. Each week has: week, forecast_receipts, actual_receipts, data_age_hours, exceptions_count. Make the actuals drift away from the forecast in the last 4 weeks. CALCULATIONS: - Weekly error % = |actual - forecast| / actual - Running 4-week average error - Bias % = sum(forecast - actual) / sum(actual) - Status per week: GREEN (error < 7%), AMBER (7-10%), RED (> 10%) VISUAL: - Top row: 4 KPI cards (current error, 4-week average, bias, data freshness) - Error trend line chart with green/amber/red zones - Forecast vs actual comparison chart - Data quality table with status indicators - Alert section: weeks with error > 10% or data older than 24 hours COLOR: Teal accent. Red/amber/green for status. EXPORT: A CSV button for the full monitoring log.
Add a banner at the top: 'RETRAIN RECOMMENDED' in red if the error has been above 10% for 3 consecutive weeks. Otherwise 'MODEL HEALTHY' in green. Make the actual values editable so I can test the banner.
The thresholds in the prompt match the KPI framework: target below 10%, green below 7%, and the same "3 consecutive weeks above 10%" rule that Power Automate alerts on. One rule everywhere, or your dashboard and your alert will disagree.
The monitor, live
12 weeks of receipts forecast vs actual (EUR K). Edit any actual and watch the KPIs, statuses and banner update.
| Week | Forecast | Actual | Error | Age | Status |
|---|---|---|---|---|---|
| W1 | 846 | 6h | |||
| W2 | 849 | 5h | |||
| W3 | 851 | 7h | |||
| W4 | 854 | 6h | |||
| W5 | 857 | 30h | |||
| W6 | 860 | 6h | |||
| W7 | 863 | 5h | |||
| W8 | 866 | 6h | |||
| W9 | 869 | 7h | |||
| W10 | 872 | 6h | |||
| W11 | 875 | 5h | |||
| W12 | 877 | 6h |
What it shows: actual receipts fall from week 6 while the forecast keeps rising. That is drift, most likely a customer lost or paying later. The bias confirms it: the model over-forecasts. Diagnose before you retrain.
Microsoft Fabric for treasury AI at scale
When you outgrow Excel + Python + Power BI, Fabric brings it together. You do not need it today. You will when you run several models across many entities with frequent retraining.
Data Factory. Automated pipelines that pull bank feeds and ERP data on a schedule.
Replaces: Manual downloads + Power Query
Lakehouse. All treasury data in one place, structured and unstructured.
Replaces: Many Excel files on shared drives
Notebooks. Python and SQL directly on the lakehouse data: pandas, Prophet, ML.
Replaces: Local Python + manual data transfer
Power BI (integrated). Dashboards connected straight to the lakehouse.
Replaces: Separate Power BI + manual refresh
ML models. Train, register and deploy models with versioning built in.
Replaces: Model files on a drive, no versioning
What you take away
Building the model is the small part of the work. Operating it is the large part.
The operations cycle: DEPLOY > MONITOR > ALERT > DIAGNOSE > RETRAIN > TEST.
3 types of drift: data, concept, feature. Monitor all three.
8 KPIs for treasury AI, with one threshold rule used everywhere.
Power Automate for scheduling and alerts; Power BI for dashboards the whole team can read.
6 test types, starting with a data validation suite that runs on every file.
An audit trail per run: model version, data hash, parameters, output, validation, deviations.
Retraining: monthly, drift-triggered, event-based, and an annual full refresh.
Microsoft Fabric when you are ready to scale.
You started as a user. You finish as a builder.
Ten modules, from where AI works in treasury to building and operating AI systems.
The only thing left is execution. Start this week.
Built by a treasurer, for treasurers. · treasuryease.com