Skip to main content

Case study · Wabel · MVP

Wabel

A supplier-sourcing engine for the food industry. An invoice or a request for quotation is parsed into a typed sourcing brief, matched against the supplier corpus in two phases, vector recall then LLM rerank, and returned as a ranked list with a relevance score and a written reason for every match.

Client Wabel, France Built by starmo Status MVP

The same stack, a second industry. Nothing in the matching engine is aviation-specific. It is the retrieval and ranking stack that cites manual pages in DocsAI, pointed at a corpus of suppliers instead of a corpus of documents, with the explanation step doing for a buyer what a citation does for an engineer.

The problem

A brief in a buyer's head, a corpus of suppliers

Wabel matches food-industry buyers with suppliers across Europe. A buyer's need arrives as an invoice from a current supplier, a request for quotation, or a few lines of free text. The candidates are a corpus of supplier profiles of uneven completeness, because suppliers describe themselves in their own words and to their own depth.

Matching by keyword misses the supplier who describes the same product in different words. Matching by embedding alone returns a ranked list nobody can argue with, because it gives no reasons. A buyer who is about to pick up the phone needs to know why this supplier and not that one.

The engine had to take an unstructured brief, find the right candidates quickly, and explain each match in a sentence a buyer can read.

The approach

Four decisions

Parse first, match second

Invoices and RFQs are parsed into typed sourcing briefs with structured outputs, so the matcher works from validated fields rather than from a free-text prompt.

Recall fast, rerank behind it

Phase one recalls the top candidates from pgvector and answers within the request. Phase two hands them to an LLM reranker on an async worker, which scores each candidate and streams in behind the first list.

A reason for every match

The reranker writes the reason a buyer can read, not only a score. No black-box ranking.

A corpus that fills itself in

A crawler with a Playwright fallback enriches supplier profiles from their public web presence, so thin records improve without manual data entry.

What shipped

Three screens from the MVP

Wabel sourcing interface turning a free-text brief into ranked, scored supplier matches with explanations
01 · Sourcing

Brief in, reasons out. A free-text brief becomes a ranked list of suppliers, each with a relevance score and a written reason. The list appears at vector-recall speed; the scores and reasons stream in as the reranker finishes each candidate.

Faceted supplier directory across categories and markets
02 · Directory

The corpus, browsable. A faceted supplier directory across categories and markets: the same records the matcher searches, enriched by the crawler.

Clean-label analyzer scoring a product's ingredient list against EU additive data
03 · Clean label

A second product on the same foundations. The clean-label analyzer: an ingredient list matched against EU food-additive grounding data, scored for consumer perception with the worst offenders first, delivered as an audit report.

The engine

Two phases, one explanation

Matching is split so that the cheap, fast phase answers first and the expensive, careful phase improves the answer without making the buyer wait for it.

Invoice · RFQ · text whatever the buyer has Brief parser structured outputs → typed brief Phase 1 · recall pgvector, nearest suppliers Ranked list, within the request what the buyer sees first Arq queue · Redis candidates, per brief Phase 2 · LLM rerank relevance score + written reason, per match SUPPLIER CORPUS Postgres 16 pgvector · pg_trgm Crawler Playwright fallback STREAMS IN ENRICHES READ BY BOTH PHASES
Figure

Blue is where the model reads: the recall phase, and the rerank that streams its scores and reasons back into a list the buyer is already looking at. The corpus is read by both phases and written by the crawler.

01

Parse

An invoice, an RFQ or free text goes to the model with a schema and comes back as a typed sourcing brief. Structured outputs, not a free-text prompt, so the fields are validated before anything is searched.

02

Recall

The brief is embedded and pgvector returns the nearest supplier profiles. This is the list the buyer sees first, within the request.

03

Rerank

The candidates are queued to an Arq worker on Redis. An LLM reranker reads the brief and each profile, assigns a relevance score and writes the reason. Results stream into the list as each one completes.

04

Enrich

Independently, a crawler visits supplier websites and fills in profiles, falling back to Playwright for pages that need a browser. Better profiles make both phases better.

Clean label

Compliance on the same stack

A follow-on build applies the same foundations to label compliance. An ingredient list is matched against EU food-additive grounding data, each additive is scored for how consumers perceive it, and the worst offenders are surfaced first. The result is delivered as an audit report through an email-gated funnel.

A full domain product stood up in days, because retrieval, ranking and explanation were already there. The domain changed; the engine did not.

Stack

What it is made of

LayerChoice
MatchingTwo phases: pgvector recall, then LLM rerank with a relevance score and a written reason per match
BriefsInvoices and RFQs parsed into typed sourcing briefs with structured outputs
EnrichmentWeb crawler over supplier sites, Playwright fallback for pages that need a browser
BackendFastAPI; Arq workers on Redis for the rerank queue
DataPostgres 16 with pgvector and pg_trgm
ComplianceEU food-additive grounding data for the clean-label analyzer
Tests51 backend, green CI

Have a workflow like this?

Tell us about it: if it is not a fit, we say so in the first five minutes.