08 · Shipped & live · 2026
Ganymede
Which delinquent borrower is worth an agent-minute, and what to say once the call starts.
A collections team has more accounts in arrears than it has hours to call them. Ganymede decides which accounts are worth calling, then helps the agent through the call that follows. It ranks by the money a call is expected to recover rather than by the probability the borrower defaults. Those two orderings are not the same, and the difference is most of the value. The outcome of each call becomes the label that retrains the model that picked it.
The questionA risk score sorts borrowers by how likely they are to get worse. A collections team does not need that list. It needs the list of calls that recover the most money per agent-minute. How much does the difference between those two lists actually cost?
How it’s put together
01
Panel
- Loan-level servicing history
- Monthly borrower panel
- Contact events by channel
Real dates, real delinquency transitions.
02
Score
- L1 trajectory: does this worsen
- L2 self-cure: does it fix itself
- L4 promise kept
- Calibration, then reason codes
Two questions, not one.
03
Allocate
- Uplift over self-cure
- Weighted by exposure
- Under a capacity constraint
- Do not contact is a scored action
Expected value, never probability.
04
Coach
- Tier 1 renders under a millisecond
- Tier 2 waits for the next pause
- Branches on borrower state
Two tiers, set by the measured gap.
05
Learn
- Every decision logs its arm and propensity
- Promise resolved against payment
- Drift monitors on input and score
Rough sketch
Allocator studio
Agent desk
Evidence
What happens, step by step
- Build the panel. Loan-level servicing history becomes a monthly borrower panel. Calendar dates are the point: a timing feature from a source without real dates is refused at the feature layer rather than caught in review.
- Score two questions, not one. L1 asks whether the account worsens over the next ninety days. L2 asks whether it recovers without contact. An agent reads those numbers at face value, so calibration is the gate rather than AUC.
- Rank by money, not by risk. The allocator maximises expected recovered value per agent-minute: uplift over self-cure, weighted by exposure, under the capacity the team actually has. Probability never sorts the queue.
- Coach inside the measured gap. 328 inter-turn gaps from a real call give a median of 479 ms and a p25 of 292 ms. The budget is 300 ms because that is what the distribution allows. A hint that misses the gap arrives after the moment it was for.
- Log the decision, then resolve it. Every score, hint and override is written down with its experiment arm and its propensity. When the payment arrives or does not, the promise resolves and both lenses retrain on the result.
A decision that shaped it
Rank by expected valueinstead of Rank by probability of default
Risk-ranking calls a 1,289 euro account early and never reaches a 1.93 million euro one anywhere in the capacity sweep. Twelve agent-minutes cost more than the whole uplift on the small account is worth. At 15% capacity the value ordering recovers 59% more using roughly half the contacts. At 60% the edge falls to 2.4%, because with enough agents to call everyone the ordering stops mattering. The gain lives exactly where the constraint is real.
- Python
- Polars
- LightGBM
- scikit-learn
- Calibration
- Uplift modelling
- LLM orchestration
- Vercel