Building Roamstead: Google Cloud가 동남아시아 공동 주택 에이전트를 만드는 데 도움을 준 방법

작성자

카테고리:

← 피드로
DEV Community · vv · 2026-08-30 개발(SW)

Hackathon disclosure: I created this article for the purpose of entering the All Things Agentic Hackathon.

Moving to another country can open a path to a better quality of life and lower housing costs. But finding a home across borders is much harder than opening a real-estate website and choosing a listing.

I started Roamstead with a question I could not ignore: where will I be able to afford to live when I retire?

Rising home prices and the everyday cost of living have made it impossible for me to afford a home where I currently live. This is not only about me. I am building Roamstead with my family’s future in mind because I want us to understand what a stable and affordable retirement could realistically look like.

I believe many other Americans are asking versions of the same question as housing, healthcare, and everyday expenses continue to rise. Retiring abroad will not be right for everyone, but people considering it deserve better than a pile of listings and optimistic assumptions. They need a way to compare real evidence, see what remains unknown, and stay in control of every consequential change.

That became the idea behind Roamstead: a collaborative housing decision partner for people investigating an affordable place to retire or live in Southeast Asia.

Roamstead project overview

Affordable does not simply mean the lowest price

A lower listing price does not automatically make a home affordable, safe, or suitable.

Healthcare access, food and daily needs, space, neighborhood conditions, remote-work reliability, ownership or rental restrictions, currency differences, and missing listing facts can completely change a decision. Property sites are good at showing options, but this evidence is scattered across pages, photographs, maps, and unfamiliar local context.

Roamstead treats affordability as personal. Budget is a hard gate, not a preference the agent can quietly loosen. The remaining choices are compared against the user’s approved priorities, including healthcare, daily-needs proximity, space, reliable remote work, quiet surroundings, and waterfront access.

The goal is not to promise that a property is affordable or legally suitable. Roamstead is decision support, not legal, tax, financial, immigration, or inspection advice. Its job is to help someone investigate the available evidence and make a more grounded choice.

From search box to collaborative partner

Roamstead currently covers Ho Chi Minh City, Bangkok, and Kuala Lumpur, with Ho Chi Minh City as the deepest market experience. A user chooses whether to buy or rent, sets a budget and other hard constraints, and creates an editable decision profile.

The product does not immediately produce a confident answer. It first measures which preference change would most affect the qualified top ten. A counterfactual ranking tool chooses the highest-impact tradeoff, and Gemini turns that measured tradeoff into one concise clarification.

The answer becomes a typed proposal that shows its predicted effect. The user can Accept, Soften, or Reject it. Nothing changes before approval.

This approval boundary matters to me. An agent that silently learns can become surprising or manipulative. A collaborative partner should be able to say, “I noticed this pattern. Would you like me to update your profile?”

The Roamstead collaboration loop

The agent also remembers feedback. If a person rejects different properties for the same underlying reason—even using different words—semantic memory can recognize the pattern and propose a revision. Retrieved memories remain advisory. They cannot become hard filters or invisible Fit Score inputs.

My first non-negotiable decision: no synthetic listings

One of the earliest technical temptations was to generate a polished sample catalog. That would have made the frontend easier to build, but it would also have undermined the reason the product exists.

I decided that every displayed property had to come from a real listing source.

Roamstead persists 240 publishable property records:

  • 100 homes for sale and 100 rentals in Ho Chi Minh City
  • 10 homes for sale and 10 rentals in Bangkok
  • 10 homes for sale and 10 rentals in Kuala Lumpur

The current source snapshots come from Batdongsan, PropertyHub, and PropertyGenie. Source rights and terms remain with the respective publishers, and any larger public or commercial deployment requires a formal permissions review.

The source data is messy. Prices arrive in local currencies. Descriptions may require translation. Property types are inconsistent. Some images show a room; others show a document, floor plan, map, or marketing graphic.

A record is publishable only when it has a numeric source price, a valid source page, retrievable image bytes, and a non-duplicate photograph hash. The ingestion workflow normalizes presentation into English, calculates a comparable USD value server-side, retains the source and observation time, and writes accepted records to Firestore. Visitors browse the saved catalog rather than triggering another model search on every page load.

Real ranked listings, decision profile, and map

Hard requirements belong to code

The matching profile separates hard requirements from weighted lifestyle priorities.

Budget, property type, bedrooms, and bathrooms are deterministic gates. If a home is over budget or does not have the required space, it is excluded. Gemini cannot reinterpret the filter or place an attractive but ineligible property at the top.

Qualified homes receive an inspectable Fit Score. The interface shows why a property fits, which facts are CONFIRMED, what is INFERRED, and what remains UNKNOWN.

This became one of the most important architectural lessons in the project:

Models should reason about ambiguity. Deterministic tools should enforce promises.

The same separation applies to profile revisions, evidence transitions, selected listing IDs, prices, and the number of correction attempts allowed during an agent run.

Building a visible multi-agent workflow

When a user selects exactly three qualified properties, Roamstead creates a Decision Brief through a durable Google Agent Development Kit workflow.

The PartnerCoordinator combines deterministic function nodes with specialized model nodes:

  1. Lock the profile version, three listing IDs, and Fit Scores.
  2. Retrieve a compact profile-isolated semantic-memory packet.
  3. Use Gemini 3.5 Flash to analyze the bounded evidence.
  4. Start two Gemma critics in parallel.
  5. Wait for both critic branches at a deterministic join.
  6. Verify every claim against the evidence packet.
  7. Allow at most one bounded correction.
  8. Compose and persist the final Decision Brief and public event trace.

Google ADK PartnerCoordinator workflow

The model roles are intentionally different:

  • gemini-3.5-flash performs listing analysis, evidence verification, brief composition, and bounded preference phrasing.
  • gemini-embedding-001 creates 768-dimensional vectors for profile-isolated semantic memory.
  • gemma-4-26b-a4b-it audits the exact listing photographs and challenges unsupported visual claims.
  • gemma-4-31b-it checks the comparison against the approved profile and retrieved memory.
  • Veo 3.1 Lite generates one persisted orientation video for each supported city.
  • Gemini 3.1 Flash TTS generates the factual narration paired with each orientation.

The two Gemma critics begin before the join and cannot change a price, Fit Score, profile, or evidence state. Their job is to find problems, not rewrite source facts.

Every workflow event is written to persistence before it is emitted over server-sent events. The interface shows action summaries, model identities, statuses, timings, critic branches, the join, correction routing, and persistence without exposing private chain-of-thought.

Persisted multi-model execution proof

Why persistence is part of the agent

Cloud Run can scale to zero, so the application cannot rely on one process staying alive forever. Firestore became the durable memory of Roamstead.

It stores:

  • Listings and source provenance
  • User profiles and immutable revision history
  • Clarification answers and feedback
  • Preference proposals and decisions
  • Semantic decision memories
  • Agent runs and streamed events
  • Decision Briefs
  • Decision Watches and evidence revisions

This changed the product from a temporary conversation into a persistent decision process. A user can reconnect to an interrupted run or reload a completed brief without replaying finished model work.

Semantic retrieval is deliberately bounded to at most five profile-isolated memories and a 6,000-character context packet. Raw vectors are never returned by the public API. If vector generation fails, the deterministic product remains usable and the run records the degradation.

Going beyond recommendations with Decision Watch

A recommendation is useful, but a partner should continue helping after the shortlist is created.

Decision Watch examines the evidence gaps for the three selected homes and proposes the smallest useful due-diligence plan. Depending on the property, that plan can include rechecking source availability, comparing the advertised price, reviewing photographic evidence, renormalizing currency, or verifying proximity claims.

The user sees the plan before anything runs. Only after approval can the selected tools append immutable before-and-after evidence revisions. If a listing disappears or a claim becomes contradictory, its state becomes UNKNOWN. Roamstead never invents a replacement fact or synthetic property.

That feature brought the collaboration model together: retrieve real information, reason about it, ask permission, take a bounded action, and persist the result.

The Google Cloud architecture

I designed the system as separate, observable components rather than one large application process.

Roamstead Google Cloud architecture

Cloud Run

The Next.js web application and FastAPI/ADK backend run as separate Cloud Run services. Cloud Run Jobs provide bounded execution for catalog maintenance, approved Decision Watch checks, and agent evaluation. Services scale to zero, and instance limits keep the public demonstration financially controlled.

Firestore and Cloud Storage

Firestore is the production source of truth and vector-memory database. Cloud Storage holds validated listing photographs, generated city orientations, and evaluation artifacts. Persisted media avoids repeated generation and fragile external hotlinks.

Secret Manager and IAM

Gemini credentials remain in Secret Manager and are available only to the service identities that need them. The browser never receives the model credential. The Google Maps browser key is separate and restricted by API and website referrer.

BigQuery and Cloud Trace

The workflow sends sanitized operational metadata to BigQuery and Cloud Trace. I can inspect model selection, tool stages, duration, workflow version, and failure modes without storing prompts, private profiles, raw vectors, listing content, or hidden reasoning.

Pub/Sub, Cloud Build, and Artifact Registry

Pub/Sub carries bounded maintenance completion and failure events. Every push to main triggers Cloud Build checks, creates commit-tagged API and web images, stores them in Artifact Registry, deploys both Cloud Run services, and verifies the public endpoints.

GitHub-to-Cloud Run delivery and proof

The uncomfortable moments improved the product

This project did not move forward in a straight line.

At one point, the ingestion pipeline was technically running, but the interface showed only one useful property in each category. At another point, a property had a photograph, but the photograph was actually a document. The data passed a shallow check while failing the experience I was trying to create.

It would have been easy to fill those gaps with generated homes or placeholder images. Instead, I returned to the same rule: if the source cannot support a property, Roamstead should not pretend that it can.

The same thing happened with clarification. An early question asked the user to choose between ocean access and proximity to a hospital, but it was not responding to the actual profile or qualified catalog. It sounded intelligent while behaving like a script.

I removed it. That failure led to the counterfactual ranking tool and my working definition of useful agent behavior: not language that sounds smart, but behavior connected to real state with a measurable consequence.

What I learned

Persistence is part of agent intelligence

An agent that forgets everything after a container restart is not much of a partner. Durable memory, approval history, resumable workflows, and inspectable traces are product capabilities—not background plumbing.

More models help only when they have different jobs

I did not want to add models only to increase a model count. The visual critic and memory critic address different failure modes, and both outputs are visible in the run trace and final brief.

Trust comes from boundaries

Typed proposals, deterministic gates, immutable revisions, bounded retries, explicit degradation, and visible evidence states made the system more useful than a confident black-box recommendation.

Cost constraints can improve architecture

Designing around a small public-demo budget pushed me toward scale-to-zero services, cached property snapshots, generate-once media, bounded context, one correction pass, paused schedules, and explicit concurrency limits.

What I would build next

The next version of Roamstead would expand verified retirement-market coverage and compare recurring living costs alongside housing. I also want to add multilingual evidence review, stronger automated source refresh and change detection, and sourced checks for healthcare access, visas, ownership rules, and recurring property costs.

Those features must preserve the same boundaries: user approval, auditable changes, explicit unknowns, and a clear separation between decision support and professional legal or financial advice.

I would rather expand carefully than create a large catalog of low-confidence or synthetic choices.

Closing thought

I started Roamstead because homeownership and a secure retirement feel increasingly out of reach for my family. I ended up building more than a property search tool. The project became an exploration of trust, memory, evidence, approval, and what it means for an agent to collaborate with a person instead of deciding for them.

Google Cloud made that distinction real. Cloud Run made the application deployable. Firestore gave it durable state and semantic retrieval. Cloud Storage made evidence and generate-once media persistent. Secret Manager protected credentials. Google Maps made unfamiliar cities spatially understandable. ADK, Gemini, Gemma, and Veo turned a shortlist into a visible, reviewable workflow.

Roamstead does not try to decide where someone should live.

It helps people and families investigate that decision with clearer evidence, personalized tradeoffs, and control over every consequential change.

원문에서 계속 ↗