A bid desk that shows its work.
Public-procurement triage for a manufacturer, built so a machine can narrow the field but a human owns, and can defend, every bid or no-bid. Client anonymized.
The problem
Relevant public contracts are scattered across the EU tender portal and national ones. Someone skims them by hand every day, and misses the ones that matter under the ones that don't. In one running month the system pulled 109 notices; only a handful were worth a bid.
The instinct, rejected
The obvious build is one model call per tender: read it, output bid or no-bid. But a model that silently rules out a public contract you never saw is a liability, not a filter. When you skip a two-million-euro bid, "the AI said no" is not an answer you can give.
The design: score, approve, control
Three layers. The machine scores with a rules-and-LLM ensemble: procurement-code rules, keyword rules with confidence bands, then an LLM that reads the full notice against the catalog and ranks the fit. The machine only ever auto-disqualifies the clear noise; anything that might fit goes to a human to approve. It never auto-approves a bid. And every decision is written to a control layer: an append-only log.
AI proposes, a human disposes, and that gate is the product, not a limitation. In regulated work the accountable "yes" has to stay human. Everything the machine does is written down and nothing overwrites history, a credit-risk audit trail applied to procurement.
Software that makes a call should be able to defend it. The scoring is cheap. The trail you can inspect is the product. And the catalog it scores against comes from another system I built, so the two compound.
Honest scope: this system is built and demonstrated on 109 real public notices. It is a decision-architecture case, the point is how the decisions are made and recorded, not a claim about bids won. What I deliberately did not build: auto-submission, ERP wiring, or any AI signature.
Have decisions that need to survive an audit?
Tell me where the calls get made. I read every message myself and reply personally, usually within a day.
Start a conversation →