From d894366e9780bfb87be863e9a5be17382b56da27 Mon Sep 17 00:00:00 2001 From: Aksh Parekh Date: Tue, 21 Oct 2025 20:19:58 -0700 Subject: [PATCH] [UPDATE] With New Tools Updated the real estate swarm documentation to include new property fetching and agent integration features, enhancing the workflow for lead generation, property research, and marketing. --- docs/examples/realestate_swarm.md | 443 ++++++++++-------------------- 1 file changed, 151 insertions(+), 292 deletions(-) diff --git a/docs/examples/realestate_swarm.md b/docs/examples/realestate_swarm.md index 0a2498fb..6f5464c0 100644 --- a/docs/examples/realestate_swarm.md +++ b/docs/examples/realestate_swarm.md @@ -50,52 +50,93 @@ To set up and run the Real Estate Swarm, follow these steps: ```python -from typing import List +from swarms import Agent, SequentialWorkflow +import http.client +import json -from swarms.structs.agent import Agent -from swarms.structs.conversation import Conversation -from swarms.utils.history_output_formatter import history_output_formatter +def get_properties(postal_code: str, min_price: int, max_price: int, limit: int = 1) -> str: + """ + Fetches real estate properties from Realty-in-US API using given zipcode, min price, and max price. + All other payload fields remain constant. -# --- Exa Search Tool Integration --- -# Import and define exa_search as a callable tool for property research. -from swarms_tools import exa_search -# System prompts for each agent + Returns the property's data as a string (JSON-encoded). + """ -LEAD_GENERATION_PROMPT = """ -You are the Lead Generation Agent for Real Estate. + payload_dict = { + "limit": limit, + "offset": 0, + "postal_code": postal_code, + "status": ["for_sale", "ready_to_build"], + "sort": {"direction": "desc", "field": "list_date"}, + "price_min": min_price, + "price_max": max_price + } + + payload = json.dumps(payload_dict) + + conn = http.client.HTTPSConnection("realty-in-us.p.rapidapi.com") + headers = { + "x-rapidapi-key": "35ae958601msh5c0eae51c54f989p1463c4jsn098ec5be18b8", + "x-rapidapi-host": "realty-in-us.p.rapidapi.com", + "Content-Type": "application/json" + } + + conn.request("POST", "/properties/v3/list", payload, headers) + res = conn.getresponse() + data = res.read() + decoded = data.decode("utf-8") + try: + result_dict = json.loads(decoded) + except Exception: + return decoded + props_data = ( + result_dict.get("data", {}) + .get("home_search", {}) + .get("results", []) + ) + if not props_data: + return json.dumps({"error": "No properties found for that query."}) + return json.dumps(props_data[:limit]) -ROLE: -Collect potential leads for real estate transactions by identifying buyers, sellers, and investors through various channels. +REQUIREMENTS_ANALYZER_PROMPT = """ +You are the Requirements Analyzer Agent for Real Estate. +ROLE: +Extract and clarify requirements from user input to create optimized property search queries. RESPONSIBILITIES: -- Identify potential clients through: - * Real estate websites - * Social media platforms - * Referral networks - * Local community events -- Conduct initial consultations to understand: - * Client's property requirements - * Budget constraints - * Preferred locations - * Investment goals -- Qualify leads by assessing: - * Financial readiness - * Specific property needs - * Urgency of transaction +- Engage with the user to understand: + * Desired property types and features + * Required amenities and specifications + * Preferred locations (city/area/zip) + * Price/budget range + * Timeline and purchase situation + * Additional constraints or priorities +- Analyze user responses to identify: + * Key search terms and must-have features + * Priority factors in selection + * Deal-breakers or constraints + * Missing or unclear information to be clarified +- Generate search strategies: + * Formulate 3-5 targeted search queries based on user requirements OUTPUT FORMAT: -Provide a comprehensive lead report that includes: -1. Client profile and contact information -2. Detailed requirements and preferences -3. Initial assessment of client's real estate goals -4. Qualification status -5. Recommended next steps - -IMPORTANT CONTEXT SHARING: -When preparing the lead report, clearly summarize and include all answers and information provided by the user. Integrate these user responses directly into your analysis and the lead report. This ensures that when your report is sent to the next agent, it contains all relevant user preferences, requirements, and context needed for further research and decision-making. - -REMEMBER: -- Ensure the user's answers are explicitly included in your report so the next agent can use them for property research and analysis. +Provide a comprehensive requirements analysis: +1. User Profile Summary: + - Property types/requirements of interest + - Key features and specifications + - Location and budget preferences + - Priority factors +2. Search Strategy: + - 3-5 optimized search queries (plain language, suitable for next agent's use) + - Rationale for each query + - Expected property/result types +3. Clarifications Needed: + - Questions to refine search + - Any missing info +IMPORTANT: +- INCLUDE all user responses verbatim in your analysis. +- Format queries clearly for the next agent. +- Ask follow-up questions if requirements are unclear. """ PROPERTY_RESEARCH_PROMPT = """ @@ -104,40 +145,25 @@ ROLE: Conduct in-depth research on properties that match client criteria and market trends. TOOLS: -You have access to the exa_search tool. Use exa_search to find up-to-date and relevant information about properties, market trends, and neighborhood data. Leverage the answers provided by the user and the outputs from previous agents to formulate your search queries. Always use exa_search to supplement your research and validate your findings. - +You have access to get_properties. Use get_properties to find up-to-date and relevant information about properties for sale. Use ALL search queries produced by the previous agent (REQUIREMENTS_ANALYZER) as arguments to get_properties. RESPONSIBILITIES: -- Perform comprehensive property market analysis using exa_search: - * Local market trends - * Property value assessments - * Investment potential - * Neighborhood evaluations -- Research properties matching client specifications (using both user answers and previous agent outputs): - * Price range - * Location preferences - * Property type - * Specific amenities -- Compile detailed property reports including: - * Comparative market analysis (use exa_search for recent comps) - * Property history - * Potential appreciation - * Neighborhood insights (gathered via exa_search) - -INSTRUCTIONS: -- Always use exa_search to find the most current and relevant information for your analysis. -- Formulate your exa_search queries based on the user's answers and the outputs from previous agents. -- Clearly indicate in your report where exa_search was used to obtain information. +- Perform property research using get_properties: + * Seek properties by each proposed query and shortlist promising results. + * Analyze each result by price, location, features, and comparables. + * Highlight market trends if apparent from results. + * Assess investment or suitability potential. +- Structure and cite property search findings. OUTPUT FORMAT: Provide a structured property research report: -1. Shortlist of matching properties (include sources from exa_search) -2. Detailed property analysis for each option (cite exa_search findings) -3. Market trend insights (supported by exa_search data) -4. Investment potential assessment -5. Recommendations for client consideration - -REMEMBER: -Do not rely solely on prior knowledge. Always use exa_search to verify and enhance your research with the latest available data. +1. Shortlist of matching properties (show summaries of each from get_properties results) +2. Detailed property analysis for each option +3. Insights on price, area, trends +4. Investment or suitability assessment +5. Recommendations for client +INSTRUCTIONS: +- Always use get_properties for up-to-date listing info; do not fabricate. +- Clearly indicate which properties are found from which query. """ MARKETING_PROMPT = """ @@ -220,236 +246,69 @@ Provide a comprehensive property maintenance report: 5. Contractor and service provider details """ -class RealEstateSwarm: - def __init__( - self, - name: str = "Real Estate Swarm", - description: str = "A comprehensive AI-driven real estate transaction workflow", - max_loops: int = 1, - user_name: str = "Real Estate Manager", - property_type: str = "Residential", - output_type: str = "json", - user_lead_info: str = "", - ): - self.max_loops = max_loops - self.name = name - self.description = description - self.user_name = user_name - self.property_type = property_type - self.output_type = output_type - self.user_lead_info = user_lead_info - - self.agents = self._initialize_agents() - self.conversation = Conversation() - self.handle_initial_processing() - self.exa_search_results = [] # Store exa_search results for property research - - def handle_initial_processing(self): - self.conversation.add( - role=self.user_name, - content=f"Company: {self.name}\n" - f"Description: {self.description}\n" - f"Property Type: {self.property_type}" - ) - - def _initialize_agents(self) -> List[Agent]: - return [ - Agent( - agent_name="Alex-Lead-Generation", - agent_description="Identifies and qualifies potential real estate clients across various channels.", - system_prompt=LEAD_GENERATION_PROMPT, - max_loops=self.max_loops, - dynamic_temperature_enabled=True, - output_type="final", - ), - Agent( - agent_name="Emma-Property-Research", - agent_description="Conducts comprehensive property research and market analysis.", - system_prompt=PROPERTY_RESEARCH_PROMPT, - max_loops=self.max_loops, - dynamic_temperature_enabled=True, - output_type="final", - ), - Agent( - agent_name="Jack-Marketing", - agent_description="Develops and executes marketing strategies for properties.", - system_prompt=MARKETING_PROMPT, - max_loops=self.max_loops, - dynamic_temperature_enabled=True, - output_type="final", - ), - Agent( - agent_name="Sophia-Transaction-Management", - agent_description="Manages legal and financial aspects of real estate transactions.", - system_prompt=TRANSACTION_MANAGEMENT_PROMPT, - max_loops=self.max_loops, - dynamic_temperature_enabled=True, - output_type="final", - ), - Agent( - agent_name="Michael-Property-Maintenance", - agent_description="Oversees property condition, maintenance, and market preparation.", - system_prompt=PROPERTY_MAINTENANCE_PROMPT, - max_loops=self.max_loops, - dynamic_temperature_enabled=True, - output_type="final", - ), - ] - - def find_agent_by_name(self, name: str) -> Agent: - for agent in self.agents: - if name in agent.agent_name: - return agent - return None - - def lead_generation(self): - alex_agent = self.find_agent_by_name("Lead-Generation") - # Directly inject the user_lead_info into the prompt for the first agent - alex_output = alex_agent.run( - f"User Lead Information:\n{self.user_lead_info}\n\n" - f"History: {self.conversation.get_str()}\n" - f"Generate leads for {self.property_type} real estate transactions. Identify potential clients and their specific requirements." - ) - self.conversation.add( - role="Lead-Generation", content=alex_output - ) - - # --- After lead generation, use user_lead_info as queries for exa_search --- - queries = [] - if isinstance(self.user_lead_info, list): - queries = [str(q) for q in self.user_lead_info if str(q).strip()] - elif isinstance(self.user_lead_info, str): - if "\n" in self.user_lead_info: - queries = [q.strip() for q in self.user_lead_info.split("\n") if q.strip()] - else: - queries = [self.user_lead_info.strip()] if self.user_lead_info.strip() else [] - - self.exa_search_results = [] - for q in queries: - result = exa_search(q) - self.exa_search_results.append({ - "query": q, - "exa_result": result - }) - - def property_research(self): - emma_agent = self.find_agent_by_name("Property-Research") - # Pass ALL exa_search results as direct context to the property research agent - exa_context = "" - if hasattr(self, "exa_search_results") and self.exa_search_results: - # Directly inject all exa_search results as context - exa_context = "\n\n[Exa Search Results]\n" - for item in self.exa_search_results: - exa_context += f"Query: {item['query']}\nExa Search Result: {item['exa_result']}\n" - - emma_output = emma_agent.run( - f"History: {self.conversation.get_str()}\n" - f"{exa_context}" - f"Conduct research on {self.property_type} properties, analyze market trends, and prepare a comprehensive property report." - ) - self.conversation.add( - role="Property-Research", content=emma_output - ) - - def property_marketing(self): - jack_agent = self.find_agent_by_name("Marketing") - jack_output = jack_agent.run( - f"History: {self.conversation.get_str()}\n" - f"Develop marketing strategies for {self.property_type} properties, create listings, and manage client interactions." - ) - self.conversation.add( - role="Marketing", content=jack_output - ) - - def transaction_management(self): - sophia_agent = self.find_agent_by_name("Transaction-Management") - sophia_output = sophia_agent.run( - f"History: {self.conversation.get_str()}\n" - f"Manage legal and financial aspects of the {self.property_type} property transaction." - ) - self.conversation.add( - role="Transaction-Management", content=sophia_output - ) - - def property_maintenance(self): - michael_agent = self.find_agent_by_name("Property-Maintenance") - michael_output = michael_agent.run( - f"History: {self.conversation.get_str()}\n" - f"Assess and manage maintenance for the {self.property_type} property to prepare it for market." - ) - self.conversation.add( - role="Property-Maintenance", content=michael_output - ) - - def run(self, task: str): - """ - Process the real estate workflow through the swarm, coordinating tasks among agents. - """ - self.conversation.add(role=self.user_name, content=task) - - # Execute workflow stages - self.lead_generation() - self.property_research() - self.property_marketing() - self.transaction_management() - self.property_maintenance() - - return history_output_formatter( - self.conversation, type=self.output_type - ) - def main(): - """FOR ACTUAL INPUT FROM USER""" - # # Collect user lead information at the beginning - # print("Please provide the following information for lead generation:") - # questions = [ - # "What are the client's property requirements?", - # "What is the client's budget range or constraints?", - # "What are the client's preferred locations?", - # "What are the client's investment goals?", - # "What is the client's contact information?", - # "What is the urgency of the transaction?", - # "Is the client financially ready to proceed?" - # ] - - # user_lead_info = "" - # for q in questions: - # answer = input(f"{q}\n> ").strip() - # user_lead_info += f"Q: {q}\nA: {answer if answer else '[No answer provided]'}\n\n" - # Pre-filled placeholder answers for each question - user_lead_info = [ - "Spacious 3-bedroom apartment with modern amenities", - "$1,000,000 - $1,500,000", - "Downtown Manhattan, Upper East Side", - "Long-term investment with high ROI", - "john.doe@email.com, +1-555-123-4567", - "Within the next 3 months", - "Yes, pre-approved for mortgage" - ] + user_requirements = """ + I'm looking for a spacious 3-bedroom apartment with modern amenities. + - Price: $1,000,000 - $1,500,000 + - Location: Downtown Manhattan, Upper East Side + - Investment: Long-term, high ROI preferred + - Contact: john.doe@email.com, +1-555-123-4567 + - Timeline: Within the next 3 months + - Financials: Pre-approved for mortgage + """ + agents = [ + Agent( + agent_name="Alex-Requirements-Analyzer", + agent_description="Analyzes user property requirements and creates optimized property search queries.", + system_prompt=REQUIREMENTS_ANALYZER_PROMPT, + model_name="gpt-4.1", + max_loops=1, + temperature=0.7, + ), + Agent( + agent_name="Emma-Property-Research", + agent_description="Conducts comprehensive property search and market analysis.", + system_prompt=PROPERTY_RESEARCH_PROMPT, + model_name="gpt-4.1", + max_loops=1, + temperature=0.7, + tools=[get_properties], + ), + Agent( + agent_name="Jack-Marketing", + agent_description="Develops and executes marketing strategies for properties.", + system_prompt=MARKETING_PROMPT, + model_name="gpt-4.1", + max_loops=1, + temperature=0.7, + ), + Agent( + agent_name="Sophia-Transaction-Management", + agent_description="Handles legal, financial, and document aspects of property transactions.", + system_prompt=TRANSACTION_MANAGEMENT_PROMPT, + model_name="gpt-4.1", + max_loops=1, + temperature=0.7, + ), + Agent( + agent_name="Michael-Property-Maintenance", + agent_description="Oversees property condition, maintenance, and market readiness.", + system_prompt=PROPERTY_MAINTENANCE_PROMPT, + model_name="gpt-4.1", + max_loops=1, + temperature=0.7, + ), + ] - # Initialize the swarm - real_estate_swarm = RealEstateSwarm( + workflow = SequentialWorkflow( + name="real-estate-sequential-workflow", + agents=agents, max_loops=1, - name="Global Real Estate Solutions", - description="Comprehensive AI-driven real estate transaction workflow", - user_name="Real Estate Director", - property_type="Luxury Residential", - output_type="json", - user_lead_info=user_lead_info, + team_awareness=True, ) - # Sample real estate task - sample_task = """ - We have a high-end luxury residential property in downtown Manhattan. - Client requirements: - - Sell the property quickly - - Target high-net-worth individuals - - Maximize property value - - Ensure smooth and discreet transaction - """ - # Run the swarm - real_estate_swarm.run(task=sample_task) + workflow.run(user_requirements) if __name__ == "__main__": main()