Skip to content

Commit 604613f

Browse files
committed
[feat][async-groupchat][rewrite groupchat as self-selecting async
chat][feat][respond-tool][export respond tool for groupchat agents][improvement][drop-speaker-functions][remove speaker function api from router and exports][improvement][agent-tools-default][default tools_list_dictionary to empty list][improvement][groupchat-examples-refresh][update groupchat examples to new api][feat][new-groupchat-examples][add dynamic and router groupchat examples][feat][fable-agent-example][add fable single agent example][docs][groupchat-docs][rewrite groupchat docs and guides][improvement][groupchat-tests][rewrite groupchat tests for new api]
1 parent ac59f95 commit 604613f

36 files changed

Lines changed: 1313 additions & 3747 deletions

CLAUDE.md

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -575,25 +575,49 @@ result = swarm.run("Produce a comprehensive competitive analysis of the AI chip
575575

576576
### GroupChat
577577

578-
Agents engage in a round-table discussion. A speaker selection function decides who speaks next. Use for brainstorming, debate, or collaborative problem-solving.
578+
An asynchronous, self-selecting groupchat. There are no rounds or speaker-selection functions — every agent listens in parallel and decides on its own whether to chime in. A forced `respond(score, message)` function call asks each agent how much it wants to speak (0..1); replies above `threshold` are broadcast. The chat ends when `max_loops` messages have been posted or no message arrives for `idle_timeout` seconds.
579579

580580
```python
581-
from swarms import Agent, GroupChat
582-
from swarms.structs.groupchat import expertise_based, round_robin_speaker
581+
from swarms import Agent
582+
from swarms.structs.groupchat import GroupChat, RESPOND_TOOL
583583

584-
optimist = Agent(agent_name="Optimist", system_prompt="You argue for the benefits.", model_name="gpt-4.1", max_loops=1)
585-
pessimist = Agent(agent_name="Pessimist", system_prompt="You argue for the risks.", model_name="gpt-4.1", max_loops=1)
586-
realist = Agent(agent_name="Realist", system_prompt="You seek balanced analysis.", model_name="gpt-4.1", max_loops=1)
584+
# Every agent MUST carry RESPOND_TOOL so the chat can ask it whether to speak.
585+
# Recommended per-agent: max_loops=1, persistent_memory=False.
586+
optimist = Agent(
587+
agent_name="Optimist",
588+
system_prompt="You argue for the benefits.",
589+
model_name="gpt-4.1",
590+
max_loops=1,
591+
persistent_memory=False,
592+
tools_list_dictionary=[RESPOND_TOOL],
593+
)
594+
pessimist = Agent(
595+
agent_name="Pessimist",
596+
system_prompt="You argue for the risks.",
597+
model_name="gpt-4.1",
598+
max_loops=1,
599+
persistent_memory=False,
600+
tools_list_dictionary=[RESPOND_TOOL],
601+
)
602+
realist = Agent(
603+
agent_name="Realist",
604+
system_prompt="You seek balanced analysis.",
605+
model_name="gpt-4.1",
606+
max_loops=1,
607+
persistent_memory=False,
608+
tools_list_dictionary=[RESPOND_TOOL],
609+
)
587610

588611
chat = GroupChat(
589612
agents=[optimist, pessimist, realist],
590-
speaker_fn=round_robin_speaker, # or expertise_based, random_speaker, priority_speaker
591-
max_loops=3, # 3 rounds of discussion
613+
max_loops=10, # hard cap on total messages posted
614+
threshold=0.5, # min decision score (0..1) to publish a reply
615+
idle_timeout=8.0, # seconds of silence before stopping
592616
)
593617
result = chat.run("Should we adopt AI for medical diagnosis?")
594618
```
595619

596-
**Speaker functions:** `round_robin_speaker`, `expertise_based`, `random_speaker`, `priority_speaker`, `random_dynamic_speaker`
620+
**Tuning:** raise `threshold` for a more selective room; lower it for livelier chats. Raise `idle_timeout` if agents need time to think before replying.
597621

598622
---
599623

README.md

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -500,29 +500,38 @@ print(recommendation)
500500

501501
### GroupChat
502502

503-
`GroupChat` creates a conversational environment where multiple agents can interact, discuss, and collaboratively solve a problem. You can define the speaking order or let it be determined dynamically. This architecture is ideal for tasks that benefit from debate and multi-perspective reasoning, such as contract negotiation, brainstorming, or complex decision-making.
503+
`GroupChat` is an asynchronous, self-selecting groupchat. All agents listen in parallel; for each broadcast message, every other agent runs a forced `respond(score, message)` function call to decide whether to chime in, and replies above `threshold` are broadcast. The chat ends when `max_loops` messages have been posted or no message arrives for `idle_timeout` seconds. There is no turn order — multiple agents can react to the same message at the same time, and silent agents stay silent.
504504

505505
```python
506-
from swarms import Agent, GroupChat
506+
from swarms import Agent, GroupChat, RESPOND_TOOL
507507

508-
# Define agents for a debate
509-
tech_optimist = Agent(agent_name="TechOptimist", system_prompt="Argue for the benefits of AI in society.", model_name="gpt-5.4")
510-
tech_critic = Agent(agent_name="TechCritic", system_prompt="Argue against the unchecked advancement of AI.", model_name="gpt-5.4")
508+
# Every agent MUST carry RESPOND_TOOL so the chat can ask it whether to speak.
509+
tech_optimist = Agent(
510+
agent_name="TechOptimist",
511+
system_prompt="Argue for the benefits of AI in society.",
512+
model_name="gpt-4.1",
513+
max_loops=1,
514+
persistent_memory=False,
515+
tools_list_dictionary=[RESPOND_TOOL],
516+
)
517+
tech_critic = Agent(
518+
agent_name="TechCritic",
519+
system_prompt="Argue against the unchecked advancement of AI.",
520+
model_name="gpt-4.1",
521+
max_loops=1,
522+
persistent_memory=False,
523+
tools_list_dictionary=[RESPOND_TOOL],
524+
)
511525

512-
# Create the group chat
513526
chat = GroupChat(
514527
agents=[tech_optimist, tech_critic],
515-
max_loops=4, # Limit the number of turns in the conversation
528+
max_loops=10, # hard cap on total messages posted
529+
threshold=0.5, # min decision score (0..1) to publish a reply
530+
idle_timeout=8.0, # seconds of silence before stopping
516531
)
517532

518-
# Run the chat with an initial topic
519-
conversation_history = chat.run(
520-
"Let's discuss the societal impact of artificial intelligence."
521-
)
522-
523-
# Print the full conversation
524-
for message in conversation_history:
525-
print(f"[{message['agent_name']}]: {message['content']}")
533+
result = chat.run("Let's discuss the societal impact of artificial intelligence.")
534+
print(result)
526535
```
527536

528537
----

docs/MULTI_AGENT_STRUCTURES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ The table below lists every multi-agent structure currently shipped, with a one-
4747
| `CouncilAsAJudge` | Council evaluates a response across multiple dimensions; ranks/scores outputs. | [link](swarms/structs/council_as_judge.py) |
4848
| `LLMCouncil` | Independent expert agents respond, peer-review each other, then synthesize. | [link](swarms/structs/llm_council.py) |
4949
| `DebateWithJudge` | Adversarial debate rounds followed by a judge ruling; supports self-refinement. | [link](swarms/structs/debate_with_judge.py) |
50-
| `GroupChat` | Round-table chat with pluggable speaker-selection (round-robin, expertise, random, priority, dynamic). | [link](swarms/structs/groupchat.py) |
50+
| `GroupChat` | Asynchronous self-selecting groupchat — every agent independently scores each message via a forced `respond(score, message)` tool call and broadcasts when the score clears `threshold`. | [link](swarms/structs/groupchat.py) |
5151
| `ForestSwarm` | A forest of `Tree`s of `TreeAgent`s; routes tasks to the best matching tree leaf. | [link](swarms/structs/tree_swarm.py) |
5252
| `AdvisorSwarm` | Cheap executor + powerful advisor consulted on-demand between turns. | [link](swarms/structs/advisor_swarm.py) |
5353
| `PlannerGeneratorEvaluator` | Three-agent harness: Planner emits step contracts, Generator produces, Evaluator scores. | [link](swarms/structs/planner_generator_evaluator.py) |

docs/PERFORMANCE_AUDIT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def __getattr__(name):
177177
```
178178

179179
### 4.2 Repeated regex compilation
180-
`groupchat.py:952, 311`, `cron_job.py:121`, agent-name sanitisation. Hoist to module-level `_COMPILED = re.compile(...)`.
180+
`cron_job.py:121`, agent-name sanitisation. Hoist to module-level `_COMPILED = re.compile(...)`.
181181

182182
### 4.3 Serialisation round-trips
183183
- `base_structure.py:333-356` does `json.dumps(json.dumps(data))` before gzip — double encoding, ~2× the bytes.

docs/swarms/concept/how_to_choose_swarms.md

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -468,13 +468,13 @@ print(recommendation)
468468

469469
[📖 Documentation](https://docs.swarms.world/swarms/structs/group_chat/)
470470

471-
GroupChat creates a conversational environment where multiple agents can interact, discuss, and collaboratively solve problems. Agents take turns in conversation, building on each other's ideas and reaching consensus through dialogue. This architecture is ideal for brainstorming, negotiation, and complex decision-making requiring iterative discussion.
471+
GroupChat is an asynchronous, self-selecting room. Every agent listens to every broadcast message in parallel and independently scores how much it wants to reply via a forced `respond(score, message)` tool call. Replies whose score exceeds the configured `threshold` are broadcast back into the room. There are no rounds, no turn order, and no central speaker selector — agents decide for themselves whether each message is worth a response. The chat ends when either `max_loops` total messages have been posted or no new message arrives for `idle_timeout` seconds.
472472

473473
Best For: GroupChat is ideal for brainstorming sessions, negotiation and debate, collaborative problem-solving, real-time decision-making, creative ideation, and contract or agreement drafting.
474474

475-
Advantages: This architecture enables natural conversational interaction, builds on collective intelligence, allows for clarification and follow-up, and mimics human collaborative processes.
475+
Advantages: This architecture lets specialised agents stay silent on messages outside their expertise, mixes model providers transparently, and scales to many participants without a coordinator bottleneck.
476476

477-
Trade-offs: GroupChat can be unpredictable in direction, may require careful moderation, has conversation length that can be variable, and is not suitable for time-critical tasks.
477+
Trade-offs: GroupChat can be unpredictable in direction, requires `threshold` tuning to avoid either silent rooms or runaway chatter, has variable conversation length, and is not suitable for time-critical tasks.
478478

479479
### Architecture Diagram
480480

@@ -499,50 +499,54 @@ graph TD
499499
### Code Example
500500

501501
```python
502-
from swarms import Agent, GroupChat
502+
from swarms import Agent, GroupChat, RESPOND_TOOL
503+
504+
# Define agents with different perspectives for an asynchronous discussion.
505+
# Every participant must include tools_list_dictionary=[RESPOND_TOOL] so the
506+
# chat can read each agent's structured (score, message) decision.
503507

504-
# Define agents with different perspectives for a debate
505508
optimist = Agent(
506509
agent_name="TechnologyOptimist",
507510
system_prompt="Argue for the benefits and opportunities of AI advancement. Focus on positive impacts.",
508511
model_name="anthropic/claude-sonnet-4-5",
509-
top_p=None,
510512
max_loops=1,
511-
dynamic_temperature_enabled=True,
513+
persistent_memory=False,
514+
tools_list_dictionary=[RESPOND_TOOL],
512515
)
513516

514517
critic = Agent(
515518
agent_name="TechnologyCritic",
516519
system_prompt="Critically examine AI development challenges, risks, and potential negative consequences.",
517520
model_name="anthropic/claude-sonnet-4-5",
518-
top_p=None,
519521
max_loops=1,
520-
dynamic_temperature_enabled=True,
522+
persistent_memory=False,
523+
tools_list_dictionary=[RESPOND_TOOL],
521524
)
522525

523526
ethicist = Agent(
524527
agent_name="EthicsSpecialist",
525528
system_prompt="Focus on ethical implications, responsible AI development, and societal considerations.",
526529
model_name="anthropic/claude-sonnet-4-5",
527-
top_p=None,
528530
max_loops=1,
529-
dynamic_temperature_enabled=True,
531+
persistent_memory=False,
532+
tools_list_dictionary=[RESPOND_TOOL],
530533
)
531534

532535
moderator = Agent(
533536
agent_name="Moderator",
534537
system_prompt="Facilitate constructive dialogue, ensure all voices are heard, and help reach balanced conclusions.",
535538
model_name="anthropic/claude-sonnet-4-5",
536-
top_p=None,
537539
max_loops=1,
538-
dynamic_temperature_enabled=True,
540+
persistent_memory=False,
541+
tools_list_dictionary=[RESPOND_TOOL],
539542
)
540543

541-
# Create the group chat with controlled conversation length
544+
# Create the group chat. Replies are broadcast only when score > threshold.
542545
chat = GroupChat(
543546
agents=[optimist, critic, ethicist, moderator],
544-
max_loops=6, # Limit conversation turns for focused discussion
545-
speaker_selection_method="round_robin" # Alternating turns
547+
max_loops=10, # hard cap on total messages
548+
threshold=0.55, # raise to silence weak replies, lower for liveliness
549+
idle_timeout=8.0, # stop after 8 seconds with no new message
546550
)
547551

548552
# Run the collaborative discussion
@@ -553,10 +557,7 @@ conversation_history = chat.run(
553557

554558
# Display the full conversation
555559
print("=== Group Chat Discussion ===\n")
556-
for i, message in enumerate(conversation_history, 1):
557-
print(f"Turn {i}: [{message['agent_name']}]")
558-
print(f"{message['content']}\n")
559-
print("-" * 50)
560+
print(conversation_history)
560561
```
561562

562563
---

docs/swarms/concept/swarm_architectures.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Multi-agent architectures leverage these communication patterns to ensure that a
2626
| Sequential Coordination | Agents perform tasks in a specific sequence, where the completion of one task triggers the start of the next. | [Learn More](https://docs.swarms.world/swarms/structs/sequential_workflow/) | Step-by-step assembly lines, sequential sales processes, stepwise patient treatment workflows |
2727
| Mixture of Agents | A heterogeneous architecture where agents with different capabilities are combined to solve complex problems. | [Learn More](https://docs.swarms.world/swarms/structs/moa/) | Financial forecasting, complex problem-solving requiring diverse skills |
2828
| Graph Workflow | Agents collaborate in a directed acyclic graph (DAG) format to manage dependencies and parallel tasks. | [Learn More](https://docs.swarms.world/swarms/structs/graph_workflow/) | AI-driven software development pipelines, complex project management |
29-
| Group Chat | Agents engage in a chat-like interaction to reach decisions collaboratively. | [Learn More](https://docs.swarms.world/swarms/structs/group_chat/) | Real-time collaborative decision-making, contract negotiations |
29+
| Group Chat | Asynchronous self-selecting chat — each agent independently scores whether each message warrants a reply. | [Learn More](https://docs.swarms.world/swarms/structs/group_chat/) | Real-time collaborative decision-making, contract negotiations |
3030
| Interactive Group Chat | Enhanced group chat with dynamic speaker selection and interaction patterns. | [Learn More](https://docs.swarms.world/swarms/structs/interactive_groupchat/) | Advanced collaborative decision-making, dynamic team coordination |
3131
| SpreadSheet | Manages tasks at scale, tracking agent outputs in a structured format like CSV files. | [Learn More](https://docs.swarms.world/swarms/structs/spreadsheet_swarm/) | Large-scale marketing analytics, financial audits |
3232
| Router | Routes and chooses the architecture based on the task requirements and available agents. | [Learn More](https://docs.swarms.world/swarms/structs/swarm_router/) | Dynamic task routing, adaptive architecture selection, optimized agent allocation |
@@ -347,7 +347,7 @@ graph TD
347347
### Group Chat
348348

349349
**Overview:**
350-
Enables agents to engage in chat-like interactions to reach decisions collaboratively through discussion and consensus building.
350+
An asynchronous, self-selecting room where every agent listens to every broadcast message in parallel and independently scores whether to reply via a forced `respond(score, message)` tool call. Replies above the configured `threshold` are broadcast back into the room; the chat ends when `max_loops` messages have been posted or no new message arrives for `idle_timeout` seconds.
351351

352352
**Use Cases:**
353353

0 commit comments

Comments
 (0)