Skip to content
← Back to blog

Why I went rule-based, not AI, for the cost estimator

A short note on choosing boring, defensible tools when the problem doesn't need anything clever.

When I started the construction cost estimator, the obvious instinct was to point a language model at it. Builder types in a brief, the model returns a number, everyone's happy.

I tried it. I didn't ship it.

The two problems

I'd just finished building the marketing site for ADN Construction, which meant I'd spent a few weeks reading construction quotes, sitting in on calls and watching real conversations between builders, project managers and homeowners. One question kept coming up: "how did they get to that number?" Always asked with a slightly suspicious tone. Always followed by silence on the other side.

That's the first problem with an AI estimate. Defensibility. If a builder uses your number to push back on a quote, they need to be able to say why it's right. "The AI said so" is not a sentence that wins arguments with quantity surveyors. It's barely a sentence that wins arguments with anyone.

The second problem was maintenance. Rates change. Materials change. Regional variation is real — labour in Hampstead isn't labour in Stevenage. Every time I'd want to tweak a number I'd be re-running prompt experiments and crossing my fingers that the model would still respect my new instructions in every scenario.

That was a bad bargain. So I deleted the model.

What replaced it

A small, pure function:

estimate({ type, area, finish, complexity }) => CostRange

Every multiplier lives in a config file you can read in under a minute. Every assumption shows up on screen next to the result. If a number feels off, you open the source, fix the rate, ship a new version. End of conversation.

Worked example for a 40 m² mid-finish extension:

  • Base: £2,200 / m² (extension)
  • Finish multiplier (mid): ×1.10
  • Complexity multiplier (standard): ×1.00
  • Result: 40 × 2,200 × 1.10 × 1.00 = £96,800
  • Range (±15%): £82,300 — £111,300

Every line of that maths is on screen. If a builder thinks the base rate is wrong, they argue with the number, not the model. That's the entire point.

When I would reach for AI

Plenty of jobs do suit a model — summarising a 600-word ticket into three lines, translating a German error message, suggesting the next step in an unfamiliar stack. I'm not anti-AI. I use it daily.

But "give me a defensible number for someone's £100k extension" was never a job for it.

The decision rule I now use is roughly: pick the simplest tool that survives the question "why did it say that?" If the answer is "because of these four lines of config", you're done. If the answer is "because the model felt like it", go back and try again.