***

title: InfoGathererAgent
slug: /reference/python/agents/prefabs/info-gatherer-agent
description: Collects answers to a series of questions in sequence, with optional confirmation for critical fields.
---------------------

For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

[agentbase]: /docs/server-sdks/reference/python/agents/agent-base

Collects answers to a series of questions in sequence, with optional confirmation for
critical fields. Supports both static questions (defined at construction) and dynamic
questions (determined at runtime via a callback).

```python
from signalwire.prefabs import InfoGathererAgent
```

<ParamField path="questions" type="list[dict]" toc={true}>
  List of question dictionaries. If `None`, the agent operates in dynamic mode where
  questions are determined by a callback at request time. Each question dict has:
</ParamField>

<Indent>
  <ParamField path="questions[].key_name" type="str" required={true} toc={true}>
    Identifier for storing the answer (e.g., `"email"`).
  </ParamField>

  <ParamField path="questions[].question_text" type="str" required={true} toc={true}>
    The question to ask the user.
  </ParamField>

  <ParamField path="questions[].confirm" type="bool" default="False" toc={true}>
    If `True`, the agent confirms the answer with the user before proceeding. Use for
    critical data like email addresses and phone numbers.
  </ParamField>
</Indent>

<ParamField path="name" type="str" default="info_gatherer" toc={true}>
  Agent name for identification and logging.
</ParamField>

<ParamField path="route" type="str" default="/info_gatherer" toc={true}>
  HTTP route for this agent.
</ParamField>

### Built-in Tools

| Tool              | Description                                       | Parameters     |
| ----------------- | ------------------------------------------------- | -------------- |
| `start_questions` | Begin the question sequence                       | (none)         |
| `submit_answer`   | Submit an answer and advance to the next question | `answer` (str) |

### Dynamic Questions

Instead of static questions, use `set_question_callback()` to determine questions at
request time based on query parameters, headers, or request body:

```python
from signalwire.prefabs import InfoGathererAgent

def get_questions(query_params, body_params, headers):
    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."}
        ]
    return [
        {"key_name": "name", "question_text": "What is your name?"},
        {"key_name": "message", "question_text": "How can I help?"}
    ]

agent = InfoGathererAgent()  # No static questions
agent.set_question_callback(get_questions)

if __name__ == "__main__":
    agent.run()
```

### set\_question\_callback

<ParamField path="callback" type="Callable[[dict, dict, dict], list[dict]]" required={true} toc={true}>
  A function receiving `(query_params, body_params, headers)` that returns a list of
  question dictionaries in the same format as the `questions` constructor parameter.
</ParamField>

### Accessing Collected Data

Answers are stored in `global_data` and available in SWAIG function handlers:

```python
from signalwire import AgentBase
from signalwire.core.function_result import FunctionResult

agent = AgentBase(name="assistant", route="/assistant")
agent.set_prompt_text("You are a helpful assistant.")

@agent.tool(description="Process collected answers")
def process_answers(args, raw_data=None):
    # Inside a tool handler
    global_data = raw_data.get("global_data", {})
    answers = global_data.get("answers", [])
    # [{"key_name": "name", "answer": "John Doe"}, ...]
    return FunctionResult(f"Processed {len(answers)} answers.")

agent.serve()
```

### Example

```python
from signalwire.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?"}
    ],
    name="appointment-scheduler"
)

agent.add_language("English", "en-US", "rime.spore")
agent.prompt_add_section("Brand", "You are scheduling appointments for Dr. Smith's office.")

if __name__ == "__main__":
    agent.run()
```