Every week someone asks us to put a model in the middle of a problem that has a rule-shaped answer. We usually say no, and it costs us money when we do.
These three examples are from our own software rather than client work, because our own software is the part we’re allowed to show you. We build it for ourselves first. That’s where the opinions come from.
1. Travel Ruter: the part that decides what a trip costs
Travel Ruter is a travel planner we build for ourselves. You describe a trip, it proposes an itinerary, and you can price and book it. The stack is deliberately boring: a fast API, Postgres with PostGIS for geography, Mapbox for maps, Stripe for money.
A model writes the itinerary. A model does not work out what it costs.
Distances come out of PostGIS, because PostGIS returns the same answer every time. Prices come from Stripe, because Stripe is the system that has to be right. If you ask a model to add up a route, you get a number that looks correct — and looks correct is the one thing money can’t be.
The rule we use: if the number has to be right, the number doesn’t come from a model.
2. Mnemosyne: deciding whether two bug reports are the same bug
Mnemosyne is a prototype aimed at a dull, expensive problem: security teams reading bug bounty reports that are duplicates of each other. Same bug, forty submissions, forty people to pay.
The obvious design is to ask a model “are these the same?” for every pair of reports. It’s also the worst one. It’s slow, and it’s unstable — ask the same question twice and you can get two answers, which is fatal when the answer decides whether someone gets paid.
What actually runs is a pipeline. Exact payload matching catches the reports that are literally identical. Hybrid retrieval narrows thousands of reports down to a shortlist. Only then does a model look at the text, and a re-ranker decides the order.
The model is genuinely good at the messy part: human prose, written by strangers, in a hurry. It is not the thing that decides.
3. Bookey Reader: the library that has to open instantly
Bookey Reader is an offline reader for book summaries. We built it for our own reading, and the whole point is that a summary opens in the time it takes to lift your thumb off the screen.
The hard part was never the writing. It was assembly: sixteen enrichment sources, scrapers, metadata, deduplication. None of that is a model’s job. The scrapers run when we build the library, not when you tap a book. The app opens a local database. A model helps with rewriting, and that’s where its involvement ends.
Had we asked a model to fetch and structure sixteen sources on demand, the app would open slowly, break without a network, and cost money every time you touched it. Slower, worse, more expensive — all at once.
The rule of thumb
Reach for a model when the input is genuinely messy: a person typing a paragraph with no structure, an invoice from a supplier you’ve never heard of, a ticket with three typos and no category. That’s the work it’s good at, and it’s work that used to be impossible.
Reach for a rule when the answer is a number, a route, a state, or a yes/no you’d be embarrassed to get wrong twice in a row.
Most of the processes we get called about are the second kind. So when we say your problem is a script rather than a project, we mean it — and we’ll write you the script.