Zürich · Finance Transformation & AI

Moritz Richter

I use data and AI to diagnose, quantify, and improve finance operations.

Finance transformation consultant, working across GBS, operating models, performance management and applied AI.

Photo of Moritz Richter

Case Studies

P2P Process Mining

Problem
Every finance transformation deck opens with the same sentence — the process is inefficient and highly manual. Almost nobody can say by how much, or where.
What I built
Mined a 1.6M-event SAP purchase-to-pay log covering 251,734 purchase order line items, reconstructing the path each case actually took rather than the one the process documentation describes. Variant analysis, straight-through rate, the cycle-time cost of rework, and which sequence rules the system genuinely enforces versus merely documents.
Stack
PythonDuckDBLLM APIMatplotlib
Outcome
20%of cases follow the most common path; rework costs 19.6 days
So what
Cycle time here is an exception problem, not a capacity problem — and the expensive exceptions are not the frequent ones. A programme that targets the loudest rework activity would pick one of the cheapest. Prioritisation has to follow volume times penalty, which is only visible once the log is mined.
Cumulative share of cases covered as more process variants are included, on a log-scaled rank axis. The curve rises steeply then flattens: 50% of cases at rank 7, 90% at rank 232, 99% only at rank 9,456.
Coverage against variant rank. Half the cases sit in seven variants; the last percent needs nine thousand more.

GBS Agentic Shift

Problem
McKinsey argues agentic AI is turning the GBS talent pyramid into a diamond — a shrinking transactional base and a new layer managing the agent force. It is a claim about what work looks like, cited far more often than it is checked.
What I built
Read the claim off the labour market instead. Classified 2,110 live GBS and finance-operations postings across ten markets as transactional, judgment or agent-ops — a visible phrase taxonomy carries the headline, an LLM decides only the ambiguous residual, and the classifier's accuracy is measured against a hand-labelled gold set rather than asserted. Splitting by employer is the sharpest cut: captive GBS hires 38% transactional, third-party providers 84%. The base changed employer more than it shrank.
Stack
PythonDuckDBLLM APIMatplotlib
Outcome
2%of postings ask for agent-ops skills — the diamond is not visible yet
So what
Workforce plans built on the diamond thesis are ahead of the evidence. The live decision is not agent-ops recruitment but sourcing: a captive function that looks transformed may simply have moved its transactional base to a provider, and only the employer cut separates the two.
A single stacked bar across 2,110 GBS job postings: transactional 44%, judgment 55%, and a thin agent-ops sliver at 2% annotated in orange at the right edge.
Ten markets, one point-in-time cross-section. A measured 42.9% recall on the agent-ops class makes that 2% a lower bound rather than a ceiling — the classifier reports how wrong it is, so the finding can be read honestly.

GBS Business Case

Problem
A shared-services business case usually rests on numbers guessed in a workshop — automation rate, rework share, handling time — presented as if they were measured.
What I built
Built the case on the P2P Process Mining baseline instead: opportunity sizing and discounted cash flows from the measured straight-through rate and rework cost, then a 10,000-draw Monte Carlo across every assumption still uncertain. Each one is tagged whether diligence could resolve it or genuinely cannot yet, so the variance in the answer sorts into a work plan rather than a caveat.
Stack
PythonDuckDBNumPyMatplotlib
Outcome
62%of NPV variance comes from assumptions diligence can resolve — the work plan, not the caveat
So what
At central assumptions the case does not clear the hurdle rate, which is a result rather than a dead end. The uncertainty that decides it is a handling-time study, not a vendor quote — so a week of desk observation moves the answer further than another round of estimating, and the model says which week to spend.
Horizontal tornado chart of NPV sensitivity by assumption, low value to high value, bars coloured by whether diligence could measure the assumption or not. Minutes per rework touch, a measurable assumption, produces the widest swing — ahead of the implementation one-off cost.
The widest swing comes from a measurable assumption, not the implementation cost quote — the opposite of what a workshop case usually assumes.

DAX Intelligence

Problem
Answering one comparative question across a set of annual reports means opening every PDF and trusting your memory of what each one said.
What I built
Retrieval across 15 DAX 40 annual reports. ChromaDB surfaces the relevant passages and the LLM synthesises them behind a prompt that will not answer without a source, so every claim comes back with a company and a page number.
Stack
PythonChromaDBLLM APIStreamlit
Outcome
15 reportsanswerable in one query, with page citations
So what
Analyst time shifts from finding a passage to judging it. The citation check is what makes that shift safe: an answer carrying a verified page number can go into a client document as it stands, while an unsourced one has to be found by hand anyway — which is the work it was supposed to save.
A synthesised research memo comparing how Siemens and SAP frame AI investment strategy, each claim followed by an inline (Company Year, p.N) citation. Below it a green "VERIFIED — 8/8 citations matched retrieved excerpts exactly" badge, an export button, and the start of an audit trail table listing each retrieved excerpt with its page range and confidence score.
A real query against the 2025 filings. Every claim carries a page citation, and every citation is checked against the retrieved excerpt before it reaches the screen.

FP&A Decision Model

Problem
An FP&A forecast usually gets judged on whether it looks thorough, not on whether it would have been right — the assumptions that actually drive the number rarely get checked against what happened next.
What I built
Built a driver-based forecast for adidas as of FY2024 — using only that year's figures plus adidas's own stated FY2025 guidance — then checked it against FY2025 actuals alongside a naive top-down extrapolation. The driver-based forecast beat naive on every metric. A Monte Carlo run over adidas's own disclosed guidance ranges then asked which assumption actually drove the uncertainty: working capital, not revenue growth. The same model sits behind an interactive cockpit — move an assumption and watch it trace through to free cash flow, with a flag when a value leaves the range the company actually guided to.
Stack
PythonNumPyFastAPINext.jsLLM APIpytest
Outcome
3.4%free cash flow error backtested against FY2025, vs. 14.8% for naive extrapolation
So what
Both forecasts still undershot — adidas beat its own guidance, so 'the model won' is not the same claim as 'the model was accurate.' The actionable read is narrower and more useful: don't spend review time re-arguing the growth assumption, spend it on the working-capital assumption, since that is what actually moves the cash outcome.
Horizontal bar chart comparing forecast error against FY2025 actuals for three metrics — revenue, operating profit, free cash flow — each showing a naive-extrapolation bar and a driver-based bar. The driver-based bar is shorter in all three: 3.1% vs 5.5% on revenue, 14.9% vs 22.3% on operating profit, 3.4% vs 14.8% on free cash flow.
One backtest point, not a track record: built as of FY2024, checked against FY2025 actuals. Driver-based beats naive on every metric, but both still undershot — adidas outperformed its own guidance.

Finance Close Control Agent

Problem
A month-end close raises more exceptions than there are reviewer hours, and most of them are benign. Handing the triage to a model is an obvious idea and a dangerous one: a control has to run the same checks on every item, rest on a policy someone can open and read, and survive an auditor asking six months later what the system knew when it made a recommendation.
What I built
Eighteen deterministic checks run over the ledger in DuckDB before a model sees anything — materiality, approval, segregation of duties, duplicates, reconciliation status. LlamaIndex then retrieves the governing policy sections with document and clause preserved, and the model classifies and recommends inside a closed vocabulary. Every citation it returns is matched against what was actually retrieved and stripped if it was not, and a deterministic gate — not the model — decides whether a person must look. Benchmarked over 60 labelled exceptions on AWS Bedrock, with the whole decision reconstructable from an audit record.
Stack
PythonLangChainLlamaIndexAWS BedrockDuckDB
Outcome
0 missedescalations across 60 exceptions — on two models and a repeat run, at a cost of 7 to 11 false ones
So what
The direction of the error is the finding. Benign items reached a reviewer who did not need to see them; nothing that required review was cleared. That held when the model was swapped for one costing a third as much — risk accuracy fell from 0.87 to 0.70 and missed escalations stayed at zero — and again when the same run was repeated. Judgement is the model's and degrades with its price; the guarantee is the gate's and does not.
A control review for one exception: a table of the four deterministic checks that fired with their severity, observed value and detail; the risk rating, finding and recommended action; a disposition of HUMAN REVIEW REQUIRED with the three reasons that forced it; and four cited policy sections with relevance scores and source file paths.
One exception decided end to end on AWS Bedrock. The checks that fired carry their own thresholds, the disposition names the rule that forced it, and every policy section is quotable back to a file. Real output, typeset; two blocks abridged where marked.

GBS Intelligence Agent

Problem
Competitor and client intelligence reached the team through whoever happened to read the right article — usually weeks after it could have changed a proposal.
What I built
A pipeline that reads 69 feeds across 33 consulting firms, analyst houses and client companies, then has the LLM score every article 0–3 for strategic relevance. Only the top tier reaches the Monday brief; everything below the cut stays searchable in a dashboard.
Stack
PythonLLM APISQLite
Outcome
16 weeksdelivered end to end, no manual step
1,132 articles scored30 reached the brief
So what
Market awareness stops depending on who happened to read what. The summarising is the least of it — the point is that the filter runs on a Monday whether or not anyone remembers to look, which is the difference between a tool that was built and one that is used.
The Intelligence Explorer dashboard: a filter bar above a grid of article cards, each carrying a source logo, topic tags and a relevance badge. Text is obscured.
The Intelligence Explorer — one card per signal, grouped by cluster, filtered by topic and calendar week. Content obscured; the live dashboard carries competitive intelligence.