kilazi. blog
Case study

RAG for Real Estate: The Agent's Intuition, Finally Searchable

My mom was a real estate agent. I built a pre-AI prototype called kvartinator. Then, in Canada, the real thing.

Map of Metro Vancouver drawn from 366 neighbourhood polygons, with a few neighbourhoods highlighted and a 2 km search ring around one point
The short answerRAG for real estate means the AI retrieves real records before it answers: live MLS listings filtered by hard criteria, a vector search for meaning, map polygons for place, and extra local datasets such as schools or crime by neighbourhood. An LLM routes each buyer sentence to the right sources, checks the top listings against them, and writes the answer. That is how "quiet, near a good school" becomes searchable.

This went into the search box, typo and all:

i want 2-3 bedrooms in downtown of North Vancounver; for me its critical to have quiet neighborhood and access to a lot of family/children-friendly amenities

The database heard: bedrooms at least 2, area Downtown, and contains(PublicRemarks, 'quiet'). In English: show me listings whose description happens to contain the word "quiet". A loud street with a poetic seller qualifies. A silent cul-de-sac with a lazy one doesn't.

That gap between what a person means and what a database can filter is the whole job of a real estate agent. It's also the job of the system I built for a real estate team in British Columbia. Real queries, and what each one actually became:

What the database got
Lost in translation

Two generations of the same itch

My mom worked as a real estate agent. Before AI, I built a prototype called kvartinator, from kvartira, Russian for apartment. Apparently it runs in the family.

Pre-AI code could do fields and filters: bedrooms, price, district. It couldn't do the part that makes an agent good. "Quiet." "Good for kids." "Close to a decent school." A good agent hears those and a map lights up in their head. None of it lives in a column.

  1. MomA real estate agent.
  2. Pre-AII build kvartinator, named after kvartira.
  3. First cutA Python prototype for a real estate team in British Columbia. It never shipped.
  4. The AI buildListings, embeddings, map polygons and local datasets, routed by an LLM. Shipped and handed over.

What is RAG for real estate?

RAG (retrieval-augmented generation) means the AI looks things up before it answers: it pulls real records, then writes from them instead of from memory. For real estate, that means live listings plus everything around them.

The idea comes from a 2020 research paper that paired a language model with a searchable index. Listings are the perfect case: they change constantly, and a model answering from memory will cheerfully sell you a house that sold weeks ago.

So the first layer was plumbing. A sync service copies the region's MLS data feed into PostgreSQL: pages of 100, about 150 standard fields per listing, photos and all. The feed has its own query language (an industry standard built on OData), so every buyer sentence has to be translated into it.

The pre-AI way to do that is pattern matching. My first converter turned "3 bedroom condos in Vancouver under $500k" into a search for a street address literally called 3 bedroom condos in vancouver under. An LLM replaced it within two weeks.

11lookups the AI can trigger, from valuations to transit
366neighbourhood outlines on the map
2 kmradius for matching local data by distance

How does a multi-RAG property search work?

Multi-RAG means retrieving from several separate sources for one question, then scoring each listing against all of them. In this build it comes in two layers.

Layer one is the search. Hard filters run as plain SQL: cheap, exact, no opinions. Every listing is also embedded: turned into a list of numbers that captures what it means, so "luxury waterfront condo" finds listings that never use those words. And if the buyer draws a shape on the map, PostGIS keeps only what falls inside it. Filters, meaning and geography, in one database query.

Layer two is the local knowledge. Upload any CSV (crime by neighbourhood, a list of schools, building permits) and an LLM reads the columns, designs a table, finds the location fields and writes a plain-English sentence per row. Those get embedded too. New local knowledge is one upload away; I once tested that by adding a dataset live on a video call, which is either confidence or stupidity.

Then a router, one more LLM call, reads the buyer's sentence and picks up to three datasets to consult. The top 20 listings get checked against each one, three ways: by neighbourhood, by distance (anything within 2 km, scored 80% on closeness, because the nearest school matters most), or by meaning alone.

Some requests run backwards. "Low crime", "quiet area", "away from construction": fewer nearby matches should mean a higher score. My first version got this exactly wrong. In my own words at the time: "now it seems like it searches properties NEAR the demolition permits, not FAR lol". The router flags inverse intent, with a regex as backup in case the model forgets.

A sharp agent

  • Hears "quiet" and skips the streets they know are loud
  • Knows which schools are a short walk away
  • Asks back when you just say "3 bedrooms"

The system

  • Turns "quiet" into an inverse score on local data
  • Measures the top listings against schools within 2 km
  • Asks back too: city, price range, other features?

Everything that isn't a number. Bedrooms and price worked first; adjectives took the rest.

The replays above show it. "Quiet" became a keyword hunt, then vanished from the filter in later runs. "Family-friendly" got dropped with a polite explanation. "Good schools" had no column to land in. You can't filter for an adjective. You can measure what it implies.

Other dents in the paint:

  • Every listing scored the same. My note at the time: "every apartment gives 43% and 49% on crime and schools". The fix was to match crime by neighbourhood and schools by distance, instead of one blurry score for all.
  • Enrichment stops at 20 listings per answer, for speed. Fine for a shortlist, not for a census.
  • The client pushed it hard. They uploaded a very large dataset, and the progress bar parked itself at 75%.
  • The client's verdict on tone was blunt: "The response is not human-like. It currently outputs 'List of Properties' with a Draw Area icon below." Fair. For each listing's AI summary they wanted it to read "like a knowledgeable person calmly describing the home": 220 to 300 characters, no pricing, no investment talk. An agent's voice, written as a spec.
  • The commit log tells on me. "lol". "unbroken". Then "unbroken" again.

None of it is a model problem, and none of it showed up on paper. Real buyer sentences found every hole, which is why I build the demo before I pitch.

Can AI replace a real estate agent?

No. It can carry the agent's map. Reading people, negotiating, the "trust me, skip this one" stays human.

What changed is that the map is finally searchable. Which blocks are calm, where the schools are, which corner is about to sprout cranes: that can now sit in datasets a model checks for every buyer at once.

Same itch, other maps: 1,217 lots from one masterplan JPEG, floor plans turned into drawings.

My mom matched people to homes with what she knew. Kvartinator tried with code. This one hears "quiet" and goes to check the street.

Want AI agents that actually ship?

I build AI agents and the systems around them for businesses: memory, voice, overnight rigs, and the boring guards that make them safe to leave alone.

Talk to me on WhatsAppmax@kilazi.com

Questions people ask

What is the difference between RAG and a normal property search filter?

A filter only matches fields that exist, like bedrooms or price. RAG first retrieves records by meaning and by context (similar descriptions, nearby schools, neighbourhood data) and then lets a language model write an answer grounded in what it found. Filters still do the exact part; RAG covers the adjectives.

Can ChatGPT search MLS listings by itself?

Not reliably. A general chatbot answers from training data, which is stale for a market where listings change constantly. You need a connection to an MLS data feed, a database that stays in sync with it, and a retrieval step that hands the model current listings before it writes anything.

What database do you need for AI property search?

PostgreSQL covers most of it: the pgvector extension stores embeddings for search by meaning, and PostGIS handles maps, from shapes a buyer draws to distances such as "within 2 km of a school". Filters, vectors and geography can then run together in a single query.

How does AI handle a query like "low crime" or "quiet area"?

It has to flip the scoring. For inverse requests, fewer nearby matches in the crime, permits or construction data should mean a higher score. Without that rule, a system that sees the word "crime" happily ranks the busiest blocks first.

Will AI replace real estate agents?

Unlikely. AI search can carry an agent's local knowledge: which blocks are calm, which schools are close, where construction is coming. Reading people, negotiating and saying "skip this one" still needs a human who has been on the street.

Max Sergeev

Max Sergeev. Max builds AI agents and the systems around them: long-term memory, voice, overnight rigs, and the boring guards that make them safe to leave alone. He runs kilazi labs from Buenos Aires. kilazi.com

Sources

  1. Lewis et al. (2020), Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks, arXiv
  2. RESO Web API (the OData-based standard for MLS data)
  3. PostGIS documentation: ST_DWithin
  4. pgvector: open-source vector similarity search for Postgres