*** id: 54c7afd0-5b9c-44ad-92e4-f9b62d110f27 title: Info Gatherer sidebar-title: Info Gatherer slug: /python/guides/info-gatherer max-toc-depth: 3 ---------------- # Prefab Agents Prefabs are pre-built agent archetypes for common use cases. Use them directly or extend them to quickly build information gatherers, FAQ bots, surveys, receptionists, and concierges. ## What Are Prefabs? Prefabs are ready-to-use agent classes that implement common conversational patterns: | Prefab | Description | | ---------------- | ------------------------------------------ | | **InfoGatherer** | Collect answers to a series of questions | | **FAQBot** | Answer questions from a knowledge base | | **Survey** | Conduct automated surveys with validation | | **Receptionist** | Greet callers and transfer to departments | | **Concierge** | Provide information and booking assistance | ## Why Use Prefabs? * **Faster Development:** Pre-built conversation flows * **Best Practices:** Proven patterns for common scenarios * **Extensible:** Inherit and customize as needed * **Production-Ready:** Includes validation, error handling, summaries ## Quick Examples ### InfoGatherer ```python from signalwire_agents.prefabs import InfoGathererAgent agent = InfoGathererAgent( questions=[ {"key_name": "name", "question_text": "What is your name?"}, {"key_name": "email", "question_text": "What is your email?", "confirm": True}, {"key_name": "reason", "question_text": "How can I help you?"} ] ) agent.run() ``` ### FAQBot ```python from signalwire_agents.prefabs import FAQBotAgent agent = FAQBotAgent( faqs=[ {"question": "What are your hours?", "answer": "We're open 9 AM to 5 PM."}, {"question": "Where are you located?", "answer": "123 Main Street, Downtown."} ] ) agent.run() ``` ### Survey ```python from signalwire_agents.prefabs import SurveyAgent agent = SurveyAgent( survey_name="Customer Satisfaction", questions=[ {"id": "rating", "text": "Rate your experience?", "type": "rating", "scale": 5}, {"id": "feedback", "text": "Any comments?", "type": "open_ended", "required": False} ] ) agent.run() ``` ### Receptionist ```python from signalwire_agents.prefabs import ReceptionistAgent agent = ReceptionistAgent( departments=[ {"name": "sales", "description": "Product inquiries", "number": "+15551234567"}, {"name": "support", "description": "Technical help", "number": "+15551234568"} ] ) agent.run() ``` ### Concierge ```python from signalwire_agents.prefabs import ConciergeAgent agent = ConciergeAgent( venue_name="Grand Hotel", services=["room service", "spa", "restaurant"], amenities={ "pool": {"hours": "7 AM - 10 PM", "location": "2nd Floor"}, "gym": {"hours": "24 hours", "location": "3rd Floor"} } ) agent.run() ``` ## Chapter Contents | Section | Description | | ------------------------------------------------------------ | -------------------------------------- | | [InfoGatherer](/docs/agents-sdk/python/guides/info-gatherer) | Collect information through questions | | [FAQBot](/docs/agents-sdk/python/guides/faq-bot) | Answer frequently asked questions | | [Survey](/docs/agents-sdk/python/guides/survey) | Conduct automated surveys | | [Receptionist](/docs/agents-sdk/python/guides/receptionist) | Greet and transfer callers | | [Concierge](/docs/agents-sdk/python/guides/concierge) | Provide venue information and services | ## Importing Prefabs ```python # Import individual prefabs from signalwire_agents.prefabs import InfoGathererAgent from signalwire_agents.prefabs import FAQBotAgent from signalwire_agents.prefabs import SurveyAgent from signalwire_agents.prefabs import ReceptionistAgent from signalwire_agents.prefabs import ConciergeAgent # Or import all from signalwire_agents.prefabs import ( InfoGathererAgent, FAQBotAgent, SurveyAgent, ReceptionistAgent, ConciergeAgent ) ``` ## Extending Prefabs All prefabs inherit from `AgentBase`, so you can extend them: ```python from signalwire_agents.prefabs import FAQBotAgent from signalwire_agents.core.function_result import SwaigFunctionResult class MyFAQBot(FAQBotAgent): def __init__(self): super().__init__( faqs=[ {"question": "What is your return policy?", "answer": "30-day returns."} ] ) # Add custom prompt sections self.prompt_add_section("Brand", "You represent Acme Corp.") # Add custom functions self.define_tool( name="escalate", description="Escalate to human agent", parameters={"type": "object", "properties": {}}, handler=self.escalate ) def escalate(self, args, raw_data): return SwaigFunctionResult("Transferring to agent...").connect("+15551234567") ``` ## Basic Usage ```python from signalwire_agents.prefabs import InfoGathererAgent agent = InfoGathererAgent( questions=[ {"key_name": "full_name", "question_text": "What is your full name?"}, {"key_name": "email", "question_text": "What is your email address?", "confirm": True}, {"key_name": "reason", "question_text": "How can I help you today?"} ] ) if __name__ == "__main__": agent.run() ``` ## Question Format | Field | Type | Required | Description | | --------------- | ------- | -------- | ----------------------------------- | | `key_name` | string | Yes | Identifier for storing the answer | | `question_text` | string | Yes | The question to ask the user | | `confirm` | boolean | No | If true, confirm answer before next | ## Constructor Parameters ```python InfoGathererAgent( questions=None, # List of question dictionaries name="info_gatherer", # Agent name route="/info_gatherer", # HTTP route **kwargs # Additional AgentBase arguments ) ``` ## Flow Diagram InfoGatherer Flow. ## Built-in Functions InfoGatherer provides these SWAIG functions automatically: | Function | Description | | ----------------- | ----------------------------------- | | `start_questions` | Begin the question sequence | | `submit_answer` | Submit answer and get next question | ## Dynamic Questions Instead of static questions, use a callback to determine questions at runtime: ```python from signalwire_agents.prefabs import InfoGathererAgent def get_questions(query_params, body_params, headers): """Dynamically determine questions based on request""" question_set = query_params.get('type', 'default') if question_set == 'support': return [ {"key_name": "name", "question_text": "What is your name?"}, {"key_name": "issue", "question_text": "Describe your issue."}, {"key_name": "urgency", "question_text": "How urgent is this?"} ] else: return [ {"key_name": "name", "question_text": "What is your name?"}, {"key_name": "message", "question_text": "How can I help?"} ] # Create agent without static questions agent = InfoGathererAgent() # Set the callback for dynamic questions agent.set_question_callback(get_questions) if __name__ == "__main__": agent.run() ``` ## Accessing Collected Data The collected answers are stored in `global_data`: ```python # In a SWAIG function or callback: global_data = raw_data.get("global_data", {}) answers = global_data.get("answers", []) # answers is a list like: # [ # {"key_name": "full_name", "answer": "John Doe"}, # {"key_name": "email", "answer": "john@example.com"}, # {"key_name": "reason", "answer": "Product inquiry"} # ] ``` ## Complete Example ```python #!/usr/bin/env python3 # appointment_scheduler.py - Info gatherer for scheduling appointments from signalwire_agents.prefabs import InfoGathererAgent agent = InfoGathererAgent( questions=[ {"key_name": "name", "question_text": "What is your name?"}, {"key_name": "phone", "question_text": "What is your phone number?", "confirm": True}, {"key_name": "date", "question_text": "What date would you like to schedule?"}, {"key_name": "time", "question_text": "What time works best for you?"}, {"key_name": "notes", "question_text": "Any special notes or requests?"} ], name="appointment-scheduler" ) # Add custom language agent.add_language("English", "en-US", "rime.spore") # Customize prompt agent.prompt_add_section( "Brand", "You are scheduling appointments for Dr. Smith's office." ) if __name__ == "__main__": agent.run() ``` ## Best Practices ### Questions * Keep questions clear and specific * Use confirm=true for critical data (email, phone) * Limit to 5-7 questions max per session * Order from simple to complex ### key\_name Values * Use descriptive, unique identifiers * snake\_case convention recommended * Match your backend/database field names ### Dynamic Questions * Use callbacks for multi-purpose agents * Validate questions in callback * Handle errors gracefully