Skip to content
JFJeremy Friesen
All projects

Case study

Agent²

Your real estate agent's agent: text a number, take a short call with an AI voice agent, and get a matched listing back by SMS.

GenAI Genesis 2026

View on DevpostWatch the demoSource on GitHub
Agent² landing page

The problem

Finding a home means downloading apps, making accounts, toggling filters and scrolling, or hiring a commission-paid agent whose incentives are not yours. Agent² replaces that with a phone. You text a number, get a call back from an AI voice agent named Maya, describe what you want in plain speech, and receive a matched Zillow listing by SMS. Built at GenAI Genesis 2026.

The approach

  • An SMS state machine in a FastAPI webhook drives the whole flow: a new number is asked to confirm, a YES starts a GPU notebook for the voice model and places an outbound Twilio call, the call's transcript becomes a search, and each listing texted back asks for a 1 (keep it) or a 2 (what didn't you like?). Sessions live in DynamoDB, and RESET and STOP do what they say.
  • The call is a full-duplex voice bridge. Twilio streams 8 kHz mulaw over a WebSocket; the bridge decodes it, upsamples to 24 kHz with a resampler that keeps its state across chunks, Opus-encodes it and streams it to a PersonaPlex 7B speech-to-speech model, with the reverse chain running in a second asyncio task.
  • Both sides of the call are mixed into one recording, transcribed with faster-whisper and uploaded to S3. A Railtracks agent then turns the transcript into a JSON search: location, buy or rent, price, bedrooms, bathrooms, property type, required and nice-to-have features. The prompt trusts the caller's own words over Maya's recap, since the recap can carry speech-recognition errors, and estimates a budget from stated income when none is given.
  • Search scrapes Zillow broadly through ScraperAPI, parses the embedded JSON and each listing's detail page to confirm features such as pet policy, parking and nearby schools, then scores locally: within budget earns points, each confirmed required feature earns more, a missing one costs, and any hard violation moves the listing from matches to nearest.
  • The top five scored listings and every rejection reason so far go to the language model, which picks one. A 2 stores the reason and advances to the next page; a 1 schedules a one-hour cooldown before the next suggestion, so the search refines without another call.

The result

A working pipeline from a text message to a phone call to a listing, with a refinement loop that closes over the caller's rejection reasons. After the hackathon the team wrote a production plan moving the voice model to SageMaker and the API to Lambda, DynamoDB and S3, at an estimated $1.11 a day plus $0.10 a call.

My role

I set up the static landing page and its first theme, which teammates then redesigned, and wrote the original Twilio SMS webhook and sender that the later state machine replaced. On the data side I swapped the Playwright-based Zillow fetcher for a ScraperAPI fetch after trying rotating proxies, added the Railtracks quick-start notebook, and fixed the deployment dependencies.

Team

Chantal Zhang, Juniel Djossou, Mikhai Wilson

Built with

PythonFastAPIAWSPlaywright

More case studies