The Address Matching Challenge




A user types "48 Charlotte Street, London" into a search field. Somewhere in a database of ten million addresses, the right one exists. The system needs to find it accurately, instantly and at scale. It sounds straightforward but it isn't. In a recent Passion Academy session, Dr. Fabio Rodríguez walked through why address matching is a surprisingly hard problem and how a four-stage pipeline solves it without reaching for an LLM until the very last moment.
The natural instinct is to throw an LLM at it (feed the query in, get the best match back).The problem is that to find the closest address, the LLM would need to compare the input against every entry in the database. At ten million addresses that means ten million comparisons either crammed into a single context window, or spread across ten million API calls. The latency is unworkable and the cost is extreme.
String distance methods like Levenshtein (which measure how many edits it takes to turn one string into another) are fast but brittle. They're sensitive to word order, abbreviations and formatting. "St." versus "Street", "Apt" versus "Apartment", "near" versus "close to"...all of these trip them up. They don't understand intent, only character sequences.
Embeddings capture semantic meaning well but miss the fine-grained details that matter most in addresses: unit numbers, street numbers, postal codes. Two addresses on the same street can have nearly identical embeddings while being completely different locations. Threshold tuning is difficult and false positives are a real problem at scale.
None of these approaches works alone, the solution is to combine them carefully in sequence.
Before any matching can happen, the input needs to be cleaned. Raw address text is inconsistent: mixed case, punctuation, abbreviations, spelling variations. Canonicalisation standardises everything into a common form.
"Flat 2, Ros stret. (LDN)" becomes "flat 2 ros stret london" (lowercased, punctuation removed, abbreviations expanded). Both the query and every entry in the database go through this process, so comparisons are always made between representations in the same format. Two database indexes are then applied:
Rather than scanning every row in the database, the system uses trigrams (overlapping three-character sequences) to rapidly identify the most promising candidates.
"Street" becomes STR, TRE, REE, EET. A dictionary maps every trigram to the list of database entries that contain it. When a query comes in, the system finds all entries that share the largest number of trigrams with the input. This gives a shortlist of around 200 candidates in milliseconds, without touching the rest of the database. Trigrams are particularly well suited to address matching because they capture partial matches, tolerate typos and work across different word orderings...exactly the kinds of variation addresses produce in the real world.
With roughly 200 candidates retrieved, the system applies a more sophisticated similarity score using a Token-Set-Ratio approach. This,
The advantage over basic string distance is that it's order-independent. I.e. "flat 2 rose street" and "rose street flat 2" score identically. It also handles typos gracefully: "flat 4 page street" against "page stret flat 4" still scores around 96 because the edit distance between "street" and "stret" is small.
The top ten candidates from stage three are passed to an LLM for final disambiguation. At this point the LLM isn't searching, it's choosing between a small, pre-filtered shortlist. The context window is entirely manageable, the cost per query is negligible and the LLM can apply genuine semantic reasoning to resolve the cases that scoring alone can't handle: ambiguous house numbers, address intent, contextual clues in the original query.
If the LLM is confident, the match is confirmed. If not, the case is flagged for manual review rather than returning a wrong answer silently.
The architecture works because each stage does only what it's good at. Canonicalisation removes noise before any comparison happens. Trigram retrieval narrows ten million records to two hundred in milliseconds. RapidFuzz reranks those candidates with order-independent, typo-tolerant scoring. And GPT resolves the ambiguous edge cases that no deterministic method could handle reliably.
This applies to any search problem at scale: don't ask a powerful model to do what a fast index can do better. Use the LLM where reasoning actually matters: which is usually at the end on a small set of genuine candidates