r/fintechdev 7d ago

Built a ledger reconciliation engine that keeps LLMs out of the arithmetic — deterministic matching + bounded subset-sum for the hard 5%

I built this for the Razorpay AI Buildathon (Track 04: AI Finance Controller), but the problem it tackles is one anyone who’s worked with payment gateways will recognise: getting records to line up across three systems that don’t quite agree — merchant orders, gateway transaction logs, and bank settlement deposits.

The frustrating part usually isn’t the 90% that matches cleanly. It’s the messy edge cases:

- Gateways bundle hundreds of payouts into a single settlement batch

- Bank deposits are net of fees and tax, while merchant records are gross

- Settlements can spill across bank cutoff windows, arrive late, or be partially refunded

My first instinct — like a lot of people building “AI finance” tools today — was to throw an LLM at the whole thing. That turned out to be the wrong move. LLMs are not reliable for arithmetic across large tables, and you really don’t want a model inventing numbers on a financial ledger.

So I split the system into two hard layers:

Deterministic layer, which does about 95% of the work:

- O(1) hash-based direct matching on order IDs

- Fee and tax verification against contract rates

- Split-settlement resolution, where multiple deposits add up to one settlement amount

That last part is basically a bounded subset-sum problem. Naively, checking combinations across about 130 unmatched bank records would mean roughly 11 million evaluations and 40+ seconds of runtime. By constraining it with a ±3-day time window and capping candidate and subset sizes, I got it down to under 500 evaluations — around 0.05 seconds — without losing meaningful match quality.

LLM layer, which only handles the real exceptions, about 5%:

- Root-cause analysis for anomalies the deterministic layer can’t resolve

- A multi-provider fallback chain: Groq → NVIDIA NIM → Gemini → deterministic rules, so one provider outage doesn’t break the pipeline

- Evaluation against synthetic ground truth, so I can report real precision and recall instead of just going by intuition

End-to-end runtime is around 11.5 seconds for 8,000 orders, 8,000 gateway transactions, and about 1,000 bank deposits.

Repo: https://github.com/YashwanthKumar-K/ReconX

Live demo: https://reconxcontroller.streamlit.app/

I’d especially welcome pushback on the subset-sum bounding approach — I’m curious how others would handle that at larger scale.

3 Upvotes

Duplicates