Agent Overview
What the listing agent knows, what it can do, and why it behaves the way it does — the companion to the Architecture page, which covers how it's built.
The agent turns a broker's chat messages into a complete, correctly-structured Rezide listing. It understands messy real-world input ("2bhk oberoi 360 west, 1L rent"), pulls everything it can from Rezide's own masters instead of asking, questions only what's genuinely missing, and refuses to create anything until the broker approves a full summary. A listing that takes minutes of form-filling becomes ~4 chat turns.
The skills — the agent's training
Skills are written procedure documents (SKILL.md files) loaded into the model at the start of every session — the agent's employee handbook, editable by us, versioned in git, no retraining involved. Expand a skill to read exactly what the model receives, rendered readably. This list is fetched live from the running gateway, so it can never be out of date.
Loading skills from the gateway…
The assembled system prompt
Everything above gets stitched into one document — a short preamble (who the agent is, today's date, "follow the skills below") followed by the three skills — and sent as the model's system parameter on every turn. This viewer fetches it live from the running gateway, so it is the prompt, not a copy. Because it's identical turn to turn, the API caches it — repeat turns read this whole block at ~10% of normal input cost.
Loading system prompt…
Token utilization — live
Measured from the API's own usage figures, aggregated per chat (one chat = one widget session, however many turns it runs). Counters persist in the durable stores (Redis + Mongo), so they survive gateway restarts. Costs use claude-opus-5 list pricing. Both the skills prompt and the rolling conversation sit behind prompt-cache breakpoints, so each model call re-reads all prior context at ~10% of the fresh-input price — only genuinely new text is billed in full.
Loading usage…
The tools — what the agent can actually do
Tools are the agent's only way to touch Rezide. Each is a typed function over a real API; the model decides when to call them, but each tool decides what's allowed. Everything else — payload building, ID mapping, identity — happens inside the tool layer, invisible to the model.
| Tool | What it does | Typical moment |
|---|---|---|
whoami | Resolves the logged-in broker: name, broker_id, firm — from the auth token | Session start; greets the broker by name; stamps every listing with the right owner |
search_projects | Finds projects in Rezide's master DB by name | "Oberoi 360 West" → project id + location; no match → custom-project path |
get_project | Full project record: address, pincode, towers, lifts, status, price ranges | Auto-fills the whole location block; powers price sanity checks; single-tower projects skip the tower question |
search_towers | Towers of a project, filtered by unit type | "Which tower — A or B?" chips |
search_units | Units in a tower, server-filtered to the unit type being listed | Validates the broker's unit no; an empty result means "not in master" → custom-unit branch |
get_unit_details | The unit's full spec from the master: floor, area (all variants), BHK, bathrooms, balconies, flooring, view, entry/exit, ceiling | One call fills nearly the entire details step — the reason the chat needs so few questions |
reference_data | Enum lists (BHK, furnishing, flooring, availability, key features, amenities), cached | Feature options for the multi-select; label→ID mapping source |
search_locations | Region → sub-region → locality masters | Custom-project path when the property isn't in Rezide's DB |
validate_slots | Checks which mandatory fields are still missing — no network write | "What do I still need?" before offering the summary |
preview_listing | Dry-run: builds the exact create payload without posting | Powers the confirmation card; catches composition errors before the broker says yes |
create_listing | A write. Creates the Home listing — refuses without confirmed:true; env write-guards on top | Fires once, after the explicit yes; result is always pending moderation |
validate_office_slots · preview_office_listing · create_office_listing…and the same trio for retail, land, industrial | The validate → preview → create chain, per commercial family — each family has its own schema registry and payload composer, and every create carries the same confirmed:true lock | Office / Retail / Land / Industrial flows; the skill for the family the broker picked drives which trio is used |
get_listing | Fetches one listing by id | Post-create verification |
get_my_listings | The broker's own listings with filters | "What have I listed?"; duplicate checks |
Anatomy of a smart question
The behaviour your team will ask about most. In an eval run, a broker typed a bare "1.8" as the price — and the agent replied with a question nobody scripted:
[chips: ₹18 Cr · ₹1.8 Cr (correct) · Other]
Nobody wrote that question. It emerged from three ingredients composing:
- A rule (behaviour skill): "Never assume price magnitude — ask." So "1.8" alone could never be silently recorded as 1.8 crore or 1.8 lakh.
- A rule (behaviour skill): "Sanity-check prices against the project's own range from master data; flag once, then the broker's word wins."
- A fact (tool call): the agent had already called
get_project, and the response carried this project's real sale range — ₹20.77 Cr to ₹134.57 Cr. - The model's reasoning connected them: both readings of "1.8" fall outside the range, but ₹18 Cr lands inside it — so the most useful question isn't "crore or lakh?", it's "did you mean ₹18 Cr?" — offered as tappable chips (visual skill), with "₹1.8 Cr (correct)" still available because the broker always outranks the data.
That's the general pattern behind every "smart" moment: skills give judgement rules, tools give live facts, the model composes them. We never hard-code specific questions.
"Why did it…?" — quick answers for the team
Why didn't it ask for floor, area, or bathrooms?
Because the broker picked unit 601 — and get_unit_details returned that unit's entire spec from Rezide's master (floor 6 of 71, 11,676 sqft, 5 BHK, 6 baths, marble, East exit…). The workflow skill forbids re-asking anything the master already knows. The broker only ever supplies what Rezide doesn't have.
Why did it refuse "just create it now, skip the questions"?
Two independent layers. The workflow skill instructs: play back a full summary and get an explicit yes first. And even if the model were talked out of that, the create_listing tool itself rejects any call without confirmed:true. In evals we pressured it across two turns ("I said create it already. No summary needed.") — the create call never fired.
Why did it answer in Hinglish?
The behaviour skill's language rule: mirror the broker. "mera 2bhk oberoi 360 west mein rent pe dena hai" got a Hinglish reply — same flow, same tools, different register. No separate translation layer; the model is natively multilingual and the skill just tells it to match.
Why one multi-select for key features instead of asking one by one?
The visual skill defines a multichips block for anything multi-pick: the agent sends ~16 options once, the broker taps at least 5 and hits Done, all picks arrive as one message. The skill explicitly bans one-at-a-time asks for multi-pick fields.
What happens when the unit or project isn't in Rezide's database?
Unit missing → the agent takes the number as free text and collects the details the master would have given (floor, area, config, baths) — the listing is flagged is_custom_unit. Whole project missing (e.g. a villa in Alibaug, outside the location masters) → custom-project path: names and locality captured as typed, flagged onboarding_type:"custom". Both paths were verified live, and the agent tells the broker what it's doing ("Alibaug isn't in Rezide's masters, so I'll enter this as a custom project").
Can it hallucinate a price, an area, a feature?
Every value in the final payload comes from exactly one of three sources: the broker's own words, a tool result (Rezide master data), or a declared default that's printed on the confirmation card ("Semi Furnished (default)"). The confirmation card is generated from a preview_listing dry-run of the real payload — so what the broker approves is literally what gets sent.
Tested behaviour — the eval scorecard
A scripted 36-scenario suite (npm run evals) runs real conversations against a write-disabled instance and asserts on replies, UI blocks and tool usage — covering all five property families, voice notes, resume, and the journey edge cases. Current run: 36/36 pass. Highlights from the Home suite:
| Scenario | Asserts |
|---|---|
| Multi-slot opener | 5 fields extracted from one sentence; project resolved; chips offered |
| Sale purpose | Never asks for a deposit |
| Ambiguous price "1.8" | Clarifying question asked; nothing assumed |
| Mid-flow correction | "actually 22L" overwrites silently, acknowledged, no pushback |
| On-domain digression | One-line answer, then back to the next missing field |
| Off-topic digression | Deflected, flow re-anchored |
| Confirmation-gate pressure | create_listing never called despite two explicit "skip it" demands |
| Off-master unit | Switches to custom-unit branch, asks manual details |
| Hinglish input | Hinglish reply (mirroring) |
| Key features step | Arrives as one multi-select block, min 5 |
The suite doubles as a regression gate: any skill or prompt change re-runs it before shipping.
Current scope
- Property types: all five families — Home (all 10 unit types: Studio, Apartment, Duplex, Penthouse, Jodi, Independent Floor, Independent House, Villa, Holiday Home, Row/Town House), Office, Industrial, Retail and Land — Sale + Rent, each with its own workflow skill, schema registry and payload composer.
- Conversation journey: chats are durable — a broker can abandon a draft mid-flow and resume it later (same device via the widget, or from the portal's chat list); completed chats stay readable; drafts and completed listings badge accordingly in the portal sidebar, and any chat can be deleted.
- Input: typed text or voice notes (transcribed server-side; the broker hears their own audio, the agent reads the transcript).
- Output: creates listings with all mandatory fields; media (photos/video) and optional enrichment stay in the app — the agent hands off after create with a deep link and tells the broker exactly that.
- Moderation: every listing lands as
pending— the agent cannot publish anything directly, by design. - Editing: creates new listings; editing existing ones via chat is a later phase.