> ## Documentation Index
> Fetch the complete documentation index at: https://docs.swarms.world/llms.txt
> Use this file to discover all available pages before exploring further.

# Group Chat

> An asynchronous, self-selecting multi-agent conversation for debate, brainstorming, and decision-making

`GroupChat` runs a **turn-based, self-selecting** conversation: there is no fixed speaking order and no speaker-selection function, but exactly one agent speaks per turn. Each turn, every agent privately "bids" — via a forced `respond(score, message)` tool call — on how much it wants the floor; the single highest (recency-adjusted) bidder above `threshold` speaks, and only that reply is posted. A `recency_penalty` discourages the same agent from speaking twice in a row, so the floor moves around the room even though there's no explicit rotation.

## When to Use

* **Debate and discussion**: multiple perspectives on a complex topic
* **Collaborative problem-solving**: agents build on each other through conversation
* **Brainstorming**: emergent ideas from parallel contributions
* **Negotiation**: back-and-forth between stakeholders
* **Peer review**: evaluating work from several angles at once

<Note>
  This is a rewrite of the older speaker-function design. `speaker_function`, `speaker_state`, `set_speaker_function`, `start_interactive_session`, `@mention` routing, and the `round-robin-speaker` / `random-speaker` / `priority-speaker` selectors **no longer exist**. Use `threshold` / `recency_penalty` / `max_loops` to shape the conversation instead. See the [GroupChat API reference](/api/group-chat).
</Note>

## How It Works

1. **Seed** — the task is posted to the shared conversation as the first message; every agent sees it.
2. **Bid (in parallel)** — each turn, every agent is asked concurrently (via a forced `respond(score, message)` tool call) how much it wants to speak, on a `0..1` scale, along with the reply it would give.
3. **Select one speaker** — the single highest *recency-adjusted* bidder that clears `threshold` and has a non-empty reply takes the floor. Only that one reply is posted to the conversation for this turn.
4. **Recency penalty** — an agent that spoke within the last `recency_window` turns has `recency_penalty` subtracted from its bid, so the floor tends to move around the room instead of one agent monologuing.
5. **Stop** — the chat ends when `max_loops` total messages have been posted, or a turn arrives where no agent's adjusted bid clears `threshold` (a conversational lull).

<Note>
  `idle_timeout` is accepted for backward compatibility but is currently unused — the chat stops on a bidding lull (step 5 above), not a wall-clock timeout.
</Note>

## Key Features

* Turn-based self-selection: bids are collected in parallel, but exactly one agent speaks per turn (no fixed speaking order)
* Self-selection: silence is the default; agents speak only when they add value
* Forced `respond(score, message)` decision via `RESPOND_TOOL`
* Threshold-based speaker selection with a recency penalty to rotate the floor
* Auto-equips the `respond` tool into agents (`auto_equip=True`)
* Conversation history tracking and flexible output formats

## Basic Example

```python theme={null}
from swarms import Agent, GroupChat

tech_optimist = Agent(
    agent_name="TechOptimist",
    system_prompt="You argue for the benefits of AI in society.",
    model_name="gpt-5.4",
    max_loops=1,
    persistent_memory=False,
)

tech_critic = Agent(
    agent_name="TechCritic",
    system_prompt="You argue against unchecked AI advancement.",
    model_name="gpt-5.4",
    max_loops=1,
    persistent_memory=False,
)

realist = Agent(
    agent_name="Realist",
    system_prompt="You weigh both sides and seek a balanced view.",
    model_name="gpt-5.4",
    max_loops=1,
    persistent_memory=False,
)

chat = GroupChat(
    name="AI-Ethics-Debate",
    description="Discussion on AI's societal impact",
    agents=[tech_optimist, tech_critic, realist],
    max_loops=8,          # hard cap on total messages
    threshold=0.5,        # only the top bidder above 0.5 takes the floor each turn
    recency_penalty=0.3,  # discourage the same agent speaking twice in a row
)

result = chat.run("Should we prioritize AI development or AI regulation?")
print(result)
```

`auto_equip=True` (the default) injects the `respond` tool into each agent, so you do not need to add `tools_list_dictionary=[RESPOND_TOOL]` yourself.

## Shaping the Conversation

There is no speaker function — you steer the room with three parameters.

### Threshold

```python theme={null}
# Livelier: more agents chime in on each message.
lively = GroupChat(agents=agents, max_loops=20, threshold=0.4)

# More selective: only strongly-motivated, high-value replies are published.
focused = GroupChat(agents=agents, max_loops=12, threshold=0.75)
```

### Recency penalty

```python theme={null}
# Rotate the floor more aggressively so no agent can speak twice in a row.
rotating = GroupChat(agents=agents, max_loops=16, recency_penalty=0.5, recency_window=1)

# Allow an agent to keep the floor across consecutive turns if it keeps winning bids.
persistent = GroupChat(agents=agents, max_loops=16, recency_penalty=0.0)
```

### Max loops (total messages)

`max_loops` caps the **total number of messages** posted (the seed task counts as the first), not turns per agent — it's the primary cost control.

```python theme={null}
# At most 6 messages total, then the chat stops.
quick = GroupChat(agents=[proponent, opponent], max_loops=6)
```

## Key Parameters

<ParamField path="name" type="str" default="dynamic-groupchat">
  Name for the group chat.
</ParamField>

<ParamField path="description" type="str" default="Agents take turns; one speaker per turn.">
  Description of the group chat's purpose.
</ParamField>

<ParamField path="agents" type="List[Agent]" required>
  Participating agents. **At least two are required** — each message is broadcast to the other agents.
</ParamField>

<ParamField path="max_loops" type="int" default="20">
  Hard cap on total messages posted, including the initial user task.
</ParamField>

<ParamField path="threshold" type="float" default="0.5">
  Minimum recency-adjusted decision score (`0..1`) required for an agent to take the floor for a turn.
</ParamField>

<ParamField path="recency_penalty" type="float" default="0.3">
  Amount subtracted from an agent's bid if it spoke within the last `recency_window` turns. Discourages one agent from monologuing; set to `0.0` to disable.
</ParamField>

<ParamField path="recency_window" type="int" default="1">
  How many of the most recent speakers are subject to `recency_penalty`.
</ParamField>

<ParamField path="idle_timeout" type="float" default="8.0">
  Accepted for backward compatibility but currently **unused** — the chat now stops on a bidding lull (no agent clears `threshold`) rather than a wall-clock timeout.
</ParamField>

<ParamField path="output_type" type="str" default="str-all-except-first">
  History format. Use `"list"` or `"dict"` to iterate individual messages.
</ParamField>

<ParamField path="auto_equip" type="bool" default="True">
  Auto-inject the `respond` tool into agents that lack it.
</ParamField>

<ParamField path="verbose" type="bool" default="False">
  Emit internal log messages (decision scores, broadcasts, stop events) and print each posted message as a styled panel.
</ParamField>

## Methods

### run()

Run the group chat until no agent's bid clears `threshold` (a lull) or `max_loops` is hit.

```python theme={null}
result = chat.run("Discuss the future of quantum computing")
```

By default the result is a formatted string. For per-message iteration, set `output_type="list"` and read `role` / `content`:

```python theme={null}
chat = GroupChat(agents=agents, max_loops=8, output_type="list")
for message in chat.run("Discuss the tradeoffs of multi-agent systems."):
    print(f"[{message['role']}]: {message['content']}")
```

### run\_batch()

Run several independent group chats sequentially, one per task.

```python theme={null}
results = chat.run_batch([
    "Topic A to discuss",
    "Topic B to discuss",
])
```

## The `respond` Tool

Every agent must carry `RESPOND_TOOL` so the chat can force a structured speaking decision. With `auto_equip=True` this is automatic; otherwise add it yourself:

```python theme={null}
from swarms import Agent
from swarms.structs.groupchat import GroupChat, RESPOND_TOOL

agents = [
    Agent(
        agent_name=name,
        system_prompt=prompt,
        model_name="gpt-5.4",
        max_loops=1,
        persistent_memory=False,
        tools_list_dictionary=[RESPOND_TOOL],
    )
    for name, prompt in [
        ("Researcher", "You contribute research and evidence."),
        ("Critic", "You stress-test claims and find weaknesses."),
    ]
]

chat = GroupChat(agents=agents, auto_equip=False, max_loops=8)
result = chat.run("Debate the tradeoffs of autonomous agents.")
```

The tool forces a call to `respond(score, message)`: `score` (`0..1`) is how much the agent wants to speak, and `message` is the reply (empty string to stay silent). Each turn, only the single agent with the highest recency-adjusted `score` above `threshold` gets its `message` published.

## Use Cases

### Debate

```python theme={null}
pro = Agent(agent_name="Pro", system_prompt="Argue for the motion.",
            model_name="gpt-5.4", max_loops=1, persistent_memory=False)
con = Agent(agent_name="Con", system_prompt="Argue against the motion.",
            model_name="gpt-5.4", max_loops=1, persistent_memory=False)
moderator = Agent(agent_name="Moderator", system_prompt="Summarize and find common ground.",
                  model_name="gpt-5.4", max_loops=1, persistent_memory=False)

debate = GroupChat(
    name="AI-Debate",
    agents=[pro, con, moderator],
    max_loops=10,
    threshold=0.5,
)
verdict = debate.run("Should AI development be regulated?")
```

### Expert Panel

```python theme={null}
research_chat = GroupChat(
    name="Research-Collaboration",
    agents=[literature_expert, data_scientist, statistician, writer],
    max_loops=14,
    threshold=0.6,  # specialists stay quiet outside their domain
)
paper = research_chat.run("Collaborate on a paper about machine learning.")
```

## Best Practices

<Note>
  **Tuning over speaker functions**: shape participation with `threshold` (selectivity), `recency_penalty` (how aggressively the floor rotates), and `max_loops` (total length) — there is no speaker-selection function.
</Note>

1. **Distinct roles**: give each agent a specific perspective so its `respond` decision is meaningful.
2. **`max_loops=1` + `persistent_memory=False` per agent**: keep each speaking decision a clean single-shot call.
3. **Tune threshold to room size**: lower (`~0.4–0.5`) for 2–3 agents, higher (`~0.6–0.75`) for 4+.
4. **Pick the right `output_type`**: a transcript string by default, or `"list"`/`"dict"` to iterate messages.

<Warning>
  Conversation length grows with agents and turns — use `max_loops` to bound total messages and watch context limits.
</Warning>

## When NOT to Use

* **Simple tasks** — use a single `Agent`.
* **Independent analysis** — when agents shouldn't influence each other, use [ConcurrentWorkflow](/architectures/concurrent-workflow).
* **Strict ordering** — when a fixed sequence is required, use [SequentialWorkflow](/architectures/sequential-workflow).
* **Director-led delegation** — use [HierarchicalSwarm](/architectures/hierarchical-swarm).

## Related Architectures

* [Hierarchical Swarm](/architectures/hierarchical-swarm) - Structured coordination
* [Mixture of Agents](/architectures/mixture-of-agents) - Parallel with synthesis
* [Social Algorithms](/architectures/social-algorithms) - Custom communication patterns
* [Agent Rearrange](/architectures/agent-rearrange) - Custom flows
