[IMPROVE][InteractiveGroupchat][Improve the prompting so the agents acknowledge eachother + speaker functions][DOCS][Improvement]

pull/935/head
Kye Gomez 2 days ago
parent 21b4e89499
commit 6b04ec671e

@ -5,10 +5,21 @@ The InteractiveGroupChat is a sophisticated multi-agent system that enables inte
## Features
- **@mentions Support**: Direct tasks to specific agents using @agent_name syntax
- **Multi-Agent Collaboration**: Multiple mentioned agents can see and respond to each other's tasks
- **Enhanced Collaborative Prompts**: Agents are trained to acknowledge, build upon, and synthesize each other's responses
- **Speaker Functions**: Control the order in which agents respond (round robin, random, priority, custom)
- **Dynamic Speaker Management**: Change speaker functions and priorities during runtime
- **Callable Function Support**: Supports both Agent instances and callable functions as chat participants
- **Comprehensive Error Handling**: Custom error classes for different scenarios
- **Conversation History**: Maintains a complete history of the conversation
- **Flexible Output Formatting**: Configurable output format for conversation history
## Installation
@ -35,6 +46,8 @@ Initializes a new InteractiveGroupChat instance with the specified configuration
| `max_loops` | int | Maximum conversation turns | 1 |
| `output_type` | str | Type of output format | "string" |
| `interactive` | bool | Whether to enable interactive mode | False |
| `speaker_function` | Callable | Function to determine speaking order | round_robin_speaker |
| `speaker_state` | dict | Initial state for speaker function | {"current_index": 0} |
**Example:**
@ -54,7 +67,9 @@ tax_expert = Agent(
model_name="gpt-4"
)
# Initialize group chat
# Initialize group chat with speaker function
from swarms.structs.interactive_groupchat import round_robin_speaker
chat = InteractiveGroupChat(
id="finance-chat-001",
name="Financial Advisory Team",
@ -62,7 +77,8 @@ chat = InteractiveGroupChat(
agents=[financial_advisor, tax_expert],
max_loops=3,
output_type="string",
interactive=True
interactive=True,
speaker_function=round_robin_speaker
)
```
@ -178,7 +194,7 @@ chat = InteractiveGroupChat(
**Description:**
Internal method that updates each agent's system prompt with information about other agents and the group chat.
Internal method that updates each agent's system prompt with information about other agents and the group chat. This includes enhanced collaborative instructions that teach agents how to acknowledge, build upon, and synthesize each other's responses.
**Arguments:**
@ -188,7 +204,231 @@ None
```python
# Agent prompts are automatically updated during initialization
chat = InteractiveGroupChat(agents=[financial_advisor, tax_expert])
# Each agent now knows about the other participants in the chat
# Each agent now knows about the other participants and how to collaborate effectively
```
### Set Speaker Function (`set_speaker_function`)
**Description:**
Dynamically changes the speaker function and optional state during runtime.
**Arguments:**
- `speaker_function` (Callable): Function that determines speaking order
- `speaker_state` (dict, optional): State for the speaker function
**Example:**
```python
from swarms.structs.interactive_groupchat import random_speaker, priority_speaker
# Change to random speaker function
chat.set_speaker_function(random_speaker)
# Change to priority speaker with custom priorities
chat.set_speaker_function(priority_speaker, {"financial_advisor": 3, "tax_expert": 2})
```
### Set Priorities (`set_priorities`)
**Description:**
Sets agent priorities for priority-based speaking order.
**Arguments:**
- `priorities` (dict): Dictionary mapping agent names to priority weights
**Example:**
```python
# Set agent priorities (higher numbers = higher priority)
chat.set_priorities({
"financial_advisor": 5,
"tax_expert": 3,
"investment_analyst": 1
})
```
### Get Speaking Order (`_get_speaking_order`)
**Description:**
Internal method that determines the speaking order using the configured speaker function.
**Arguments:**
- `mentioned_agents` (List[str]): List of agent names that were mentioned
**Returns:**
- List[str]: List of agent names in the order they should speak
**Example:**
```python
# Internal usage (not typically called directly)
mentioned = ["financial_advisor", "tax_expert"]
order = chat._get_speaking_order(mentioned)
print(order) # Order determined by speaker function
```
## Speaker Functions
InteractiveGroupChat supports various speaker functions that control the order in which agents respond when multiple agents are mentioned.
### Built-in Speaker Functions
#### Round Robin Speaker (`round_robin_speaker`)
Agents speak in a fixed order, cycling through the list in sequence.
```python
from swarms.structs.interactive_groupchat import InteractiveGroupChat, round_robin_speaker
chat = InteractiveGroupChat(
agents=agents,
speaker_function=round_robin_speaker,
interactive=False,
)
```
**Behavior:**
- Agents speak in the order they were mentioned
- Maintains state between calls to continue the cycle
- Predictable and fair distribution of speaking turns
#### Random Speaker (`random_speaker`)
Agents speak in random order each time.
```python
from swarms.structs.interactive_groupchat import InteractiveGroupChat, random_speaker
chat = InteractiveGroupChat(
agents=agents,
speaker_function=random_speaker,
interactive=False,
)
```
**Behavior:**
- Speaking order is randomized for each task
- Provides variety and prevents bias toward first-mentioned agents
- Good for brainstorming sessions
#### Priority Speaker (`priority_speaker`)
Agents speak based on priority weights assigned to each agent.
```python
from swarms.structs.interactive_groupchat import InteractiveGroupChat, priority_speaker
chat = InteractiveGroupChat(
agents=agents,
speaker_function=priority_speaker,
speaker_state={"priorities": {"financial_advisor": 3, "tax_expert": 2, "analyst": 1}},
interactive=False,
)
```
**Behavior:**
- Higher priority agents speak first
- Uses weighted probability for selection
- Good for hierarchical teams or expert-led discussions
### Custom Speaker Functions
You can create your own speaker functions to implement custom logic:
```python
def custom_speaker(agents: List[str], **kwargs) -> str:
"""
Custom speaker function that selects agents based on specific criteria.
Args:
agents: List of agent names
**kwargs: Additional arguments (context, time, etc.)
Returns:
Selected agent name
"""
# Your custom logic here
if "urgent" in kwargs.get("context", ""):
return "emergency_agent" if "emergency_agent" in agents else agents[0]
# Default to first agent
return agents[0]
# Use custom speaker function
chat = InteractiveGroupChat(
agents=agents,
speaker_function=custom_speaker,
interactive=False,
)
```
### Dynamic Speaker Function Changes
You can change the speaker function during runtime:
```python
# Start with round robin
chat = InteractiveGroupChat(
agents=agents,
speaker_function=round_robin_speaker,
interactive=False,
)
# Change to random
chat.set_speaker_function(random_speaker)
# Change to priority with custom priorities
chat.set_priorities({"financial_advisor": 5, "tax_expert": 3, "analyst": 1})
chat.set_speaker_function(priority_speaker)
```
## Enhanced Collaborative Behavior
The InteractiveGroupChat now includes enhanced collaborative prompts that ensure agents work together effectively.
### Collaborative Response Protocol
Every agent receives instructions to:
1. **Read and understand** all previous responses from other agents
2. **Acknowledge** what other agents have said
3. **Build upon** previous insights rather than repeating information
4. **Synthesize** multiple perspectives when possible
5. **Delegate** appropriately using @mentions
### Response Structure
Agents are guided to structure their responses as:
1. **ACKNOWLEDGE**: "I've reviewed the responses from @agent1 and @agent2..."
2. **BUILD**: "Building on @agent1's analysis of the data..."
3. **CONTRIBUTE**: "From my perspective, I would add..."
4. **COLLABORATE**: "To get a complete picture, let me ask @agent3 to..."
5. **SYNTHESIZE**: "Combining our insights, the key findings are..."
### Example Collaborative Response
```python
task = "Analyze our Q3 performance. @analyst @researcher @strategist"
# Expected collaborative behavior:
# Analyst: "Based on the data analysis, I can see clear growth trends in Q3..."
# Researcher: "Building on @analyst's data insights, I can add that market research shows..."
# Strategist: "Synthesizing @analyst's data and @researcher's market insights, I recommend..."
```
## Error Classes
@ -237,7 +477,7 @@ except NoMentionedAgentsError as e:
print(f"No agents mentioned: {e}")
```
### InvalidtaskFormatError
### InvalidTaskFormatError
**Description:**
@ -247,19 +487,277 @@ Raised when the task format is invalid.
```python
try:
chat.run("@Invalid@Format")
except InvalidtaskFormatError as e:
except InvalidTaskFormatError as e:
print(f"Invalid task format: {e}")
```
### InvalidSpeakerFunctionError
**Description:**
Raised when an invalid speaker function is provided.
**Example:**
```python
def invalid_speaker(agents, **kwargs):
return 123 # Should return string, not int
try:
chat = InteractiveGroupChat(
agents=agents,
speaker_function=invalid_speaker,
)
except InvalidSpeakerFunctionError as e:
print(f"Invalid speaker function: {e}")
```
## Best Practices
| Best Practice | Description | Example |
|--------------|-------------|---------|
| Agent Naming | Use clear, unique names for agents to avoid confusion | `financial_advisor`, `tax_expert` |
| task Format | Always use @mentions to direct tasks to specific agents | `@financial_advisor What's your investment advice?` |
| Task Format | Always use @mentions to direct tasks to specific agents | `@financial_advisor What's your investment advice?` |
| Speaker Functions | Choose appropriate speaker functions for your use case | Round robin for fairness, priority for expert-led discussions |
| Collaborative Design | Design agents with complementary expertise for better collaboration | Analyst + Researcher + Strategist |
| Error Handling | Implement proper error handling for various scenarios | `try/except` blocks for `AgentNotFoundError` |
| Context Management | Be aware that agents can see the full conversation history | Monitor conversation length and relevance |
| Resource Management | Consider the number of agents and task length to optimize performance | Limit max_loops and task size |
| Dynamic Adaptation | Change speaker functions based on different phases of work | Round robin for brainstorming, priority for decision-making |
## Usage Examples
### Basic Multi-Agent Collaboration
```python
from swarms import Agent
from swarms.structs.interactive_groupchat import InteractiveGroupChat, round_robin_speaker
# Create specialized agents
analyst = Agent(
agent_name="analyst",
system_prompt="You are a data analyst specializing in business intelligence.",
llm="gpt-3.5-turbo",
)
researcher = Agent(
agent_name="researcher",
system_prompt="You are a market researcher with expertise in consumer behavior.",
llm="gpt-3.5-turbo",
)
strategist = Agent(
agent_name="strategist",
system_prompt="You are a strategic consultant who synthesizes insights into actionable recommendations.",
llm="gpt-3.5-turbo",
)
# Create collaborative group chat
chat = InteractiveGroupChat(
name="Business Analysis Team",
description="A collaborative team for comprehensive business analysis",
agents=[analyst, researcher, strategist],
speaker_function=round_robin_speaker,
interactive=False,
)
# Collaborative analysis task
task = """Analyze our company's Q3 performance. We have the following data:
- Revenue: $2.5M (up 15% from Q2)
- Customer acquisition cost: $45 (down 8% from Q2)
- Market share: 3.2% (up 0.5% from Q2)
@analyst @researcher @strategist please provide a comprehensive analysis."""
response = chat.run(task)
print(response)
```
### Priority-Based Expert Consultation
```python
from swarms.structs.interactive_groupchat import InteractiveGroupChat, priority_speaker
# Create expert agents with different priority levels
senior_expert = Agent(
agent_name="senior_expert",
system_prompt="You are a senior consultant with 15+ years of experience.",
llm="gpt-4",
)
junior_expert = Agent(
agent_name="junior_expert",
system_prompt="You are a junior consultant with 3 years of experience.",
llm="gpt-3.5-turbo",
)
assistant = Agent(
agent_name="assistant",
system_prompt="You are a research assistant who gathers supporting information.",
llm="gpt-3.5-turbo",
)
# Create priority-based group chat
chat = InteractiveGroupChat(
name="Expert Consultation Team",
description="Expert-led consultation with collaborative input",
agents=[senior_expert, junior_expert, assistant],
speaker_function=priority_speaker,
speaker_state={"priorities": {"senior_expert": 5, "junior_expert": 3, "assistant": 1}},
interactive=False,
)
# Expert consultation task
task = """We need strategic advice on entering a new market.
@senior_expert @junior_expert @assistant please provide your insights."""
response = chat.run(task)
print(response)
```
### Dynamic Speaker Function Changes
```python
from swarms.structs.interactive_groupchat import (
InteractiveGroupChat,
round_robin_speaker,
random_speaker,
priority_speaker
)
# Create brainstorming agents
creative_agent = Agent(agent_name="creative", system_prompt="You are a creative thinker.")
analytical_agent = Agent(agent_name="analytical", system_prompt="You are an analytical thinker.")
practical_agent = Agent(agent_name="practical", system_prompt="You are a practical implementer.")
chat = InteractiveGroupChat(
name="Dynamic Team",
agents=[creative_agent, analytical_agent, practical_agent],
speaker_function=round_robin_speaker,
interactive=False,
)
# Phase 1: Brainstorming (random order)
chat.set_speaker_function(random_speaker)
task1 = "Let's brainstorm new product ideas. @creative @analytical @practical"
response1 = chat.run(task1)
# Phase 2: Analysis (priority order)
chat.set_priorities({"analytical": 3, "creative": 2, "practical": 1})
chat.set_speaker_function(priority_speaker)
task2 = "Now let's analyze the feasibility of these ideas. @creative @analytical @practical"
response2 = chat.run(task2)
# Phase 3: Implementation (round robin for equal input)
chat.set_speaker_function(round_robin_speaker)
task3 = "Finally, let's plan implementation. @creative @analytical @practical"
response3 = chat.run(task3)
```
### Custom Speaker Function
```python
def context_aware_speaker(agents: List[str], **kwargs) -> str:
"""Custom speaker function that selects agents based on context."""
context = kwargs.get("context", "").lower()
if "data" in context or "analysis" in context:
return "analyst" if "analyst" in agents else agents[0]
elif "market" in context or "research" in context:
return "researcher" if "researcher" in agents else agents[0]
elif "strategy" in context or "planning" in context:
return "strategist" if "strategist" in agents else agents[0]
else:
return agents[0]
# Use custom speaker function
chat = InteractiveGroupChat(
name="Context-Aware Team",
agents=[analyst, researcher, strategist],
speaker_function=context_aware_speaker,
interactive=False,
)
# The speaker function will automatically select the most appropriate agent
task = "We need to analyze our market position and develop a strategy."
response = chat.run(task)
```
### Interactive Session with Enhanced Collaboration
```python
# Create agents designed for collaboration
data_scientist = Agent(
agent_name="data_scientist",
system_prompt="You are a data scientist. When collaborating, always reference specific data points and build upon others' insights with quantitative support.",
llm="gpt-4",
)
business_analyst = Agent(
agent_name="business_analyst",
system_prompt="You are a business analyst. When collaborating, always connect business insights to practical implications and build upon data analysis with business context.",
llm="gpt-3.5-turbo",
)
product_manager = Agent(
agent_name="product_manager",
system_prompt="You are a product manager. When collaborating, always synthesize insights from all team members and provide actionable product recommendations.",
llm="gpt-3.5-turbo",
)
# Start interactive session
chat = InteractiveGroupChat(
name="Product Development Team",
description="A collaborative team for product development decisions",
agents=[data_scientist, business_analyst, product_manager],
speaker_function=round_robin_speaker,
interactive=True,
)
# Start the interactive session
chat.start_interactive_session()
```
## Benefits and Use Cases
### Benefits of Enhanced Collaboration
1. **Reduced Redundancy**: Agents don't repeat what others have already said
2. **Improved Synthesis**: Multiple perspectives are integrated into coherent conclusions
3. **Better Delegation**: Agents naturally delegate to appropriate experts
4. **Enhanced Problem Solving**: Complex problems are addressed systematically
5. **More Natural Interactions**: Agents respond like real team members
### Use Cases
| Use Case Category | Specific Use Case | Agent Team Composition |
|------------------|-------------------|----------------------|
| **Business Analysis and Strategy** | Data Analysis | Analyst + Researcher + Strategist |
| | Market Research | Multiple experts analyzing different aspects |
| | Strategic Planning | Expert-led discussions with collaborative input |
| **Product Development** | Requirements Gathering | Product Manager + Developer + Designer |
| | Technical Architecture | Senior + Junior developers with different expertise |
| | User Experience | UX Designer + Product Manager + Developer |
| **Research and Development** | Scientific Research | Multiple researchers with different specializations |
| | Literature Review | Different experts reviewing various aspects |
| | Experimental Design | Statistician + Domain Expert + Methodologist |
| **Creative Projects** | Content Creation | Writer + Editor + Designer |
| | Marketing Campaigns | Creative + Analyst + Strategist |
| | Design Projects | Designer + Developer + Product Manager |
| **Problem Solving** | Troubleshooting | Technical + Business + User perspective experts |
| | Crisis Management | Emergency + Communication + Technical teams |
| | Decision Making | Executive + Analyst + Specialist |
### Speaker Function Selection Guide
| Use Case | Recommended Speaker Function | Reasoning |
|----------|------------------------------|-----------|
| Team Meetings | Round Robin | Ensures equal participation |
| Brainstorming | Random | Prevents bias and encourages creativity |
| Expert Consultation | Priority | Senior experts speak first |
| Problem Solving | Priority | Most relevant experts prioritize |
| Creative Sessions | Random | Encourages diverse perspectives |
| Decision Making | Priority | Decision makers speak first |
| Research Review | Round Robin | Equal contribution from all reviewers |
## Contributing

@ -0,0 +1,256 @@
"""
Enhanced Collaborative InteractiveGroupChat Example
This example demonstrates the improved collaborative behavior where agents:
1. Read and understand all previous responses
2. Acknowledge what other agents have said
3. Build upon their insights rather than repeating information
4. Synthesize multiple perspectives
5. Delegate appropriately using @mentions
The enhanced prompts ensure agents work as a true collaborative team.
"""
from swarms import Agent
from swarms.structs.interactive_groupchat import (
InteractiveGroupChat,
round_robin_speaker,
)
def create_collaborative_agents():
"""Create agents designed for enhanced collaboration."""
# Data Analyst - focuses on data insights and trends
analyst = Agent(
agent_name="analyst",
system_prompt="""You are a senior data analyst with expertise in business intelligence, statistical analysis, and data visualization. You excel at:
- Analyzing complex datasets and identifying trends
- Creating actionable insights from data
- Providing quantitative evidence for business decisions
- Identifying patterns and correlations in data
When collaborating, always reference specific data points and build upon others' insights with quantitative support.""",
llm="gpt-3.5-turbo",
)
# Market Researcher - focuses on market trends and customer insights
researcher = Agent(
agent_name="researcher",
system_prompt="""You are a market research specialist with deep expertise in consumer behavior, competitive analysis, and market trends. You excel at:
- Understanding customer needs and preferences
- Analyzing competitive landscapes
- Identifying market opportunities and threats
- Providing qualitative insights that complement data analysis
When collaborating, always connect market insights to business implications and build upon data analysis with market context.""",
llm="gpt-3.5-turbo",
)
# Strategy Consultant - focuses on strategic recommendations
strategist = Agent(
agent_name="strategist",
system_prompt="""You are a strategic consultant with expertise in business strategy, competitive positioning, and strategic planning. You excel at:
- Developing comprehensive business strategies
- Identifying competitive advantages
- Creating actionable strategic recommendations
- Synthesizing multiple perspectives into coherent strategies
When collaborating, always synthesize insights from all team members and provide strategic recommendations that leverage the collective expertise.""",
llm="gpt-3.5-turbo",
)
return [analyst, researcher, strategist]
def example_comprehensive_analysis():
"""Example of comprehensive collaborative analysis."""
print("=== Enhanced Collaborative Analysis Example ===\n")
agents = create_collaborative_agents()
# Create group chat with round robin speaker function
group_chat = InteractiveGroupChat(
name="Strategic Analysis Team",
description="A collaborative team for comprehensive business analysis",
agents=agents,
speaker_function=round_robin_speaker,
interactive=False,
)
# Complex task that requires collaboration
task = """Analyze our company's performance in the e-commerce market.
We have the following data:
- Q3 revenue: $2.5M (up 15% from Q2)
- Customer acquisition cost: $45 (down 8% from Q2)
- Customer lifetime value: $180 (up 12% from Q2)
- Market share: 3.2% (up 0.5% from Q2)
- Competitor analysis shows 3 major players with 60% market share combined
@analyst @researcher @strategist please provide a comprehensive analysis and strategic recommendations."""
print(f"Task: {task}\n")
print("Expected collaborative behavior:")
print(
"1. Analyst: Analyzes the data trends and provides quantitative insights"
)
print(
"2. Researcher: Builds on data with market context and competitive analysis"
)
print(
"3. Strategist: Synthesizes both perspectives into strategic recommendations"
)
print("\n" + "=" * 80 + "\n")
response = group_chat.run(task)
print(f"Collaborative Response:\n{response}")
def example_problem_solving():
"""Example of collaborative problem solving."""
print("\n" + "=" * 80)
print("=== Collaborative Problem Solving Example ===\n")
agents = create_collaborative_agents()
group_chat = InteractiveGroupChat(
name="Problem Solving Team",
description="A team that collaborates to solve complex business problems",
agents=agents,
speaker_function=round_robin_speaker,
interactive=False,
)
# Problem-solving task
task = """We're experiencing declining customer retention rates (down 20% in the last 6 months).
Our customer satisfaction scores are also dropping (from 8.5 to 7.2).
@analyst please analyze the retention data, @researcher investigate customer feedback and market trends,
and @strategist develop a comprehensive solution strategy."""
print(f"Task: {task}\n")
print("Expected collaborative behavior:")
print("1. Analyst: Identifies patterns in retention data")
print(
"2. Researcher: Explores customer feedback and market factors"
)
print(
"3. Strategist: Combines insights to create actionable solutions"
)
print("\n" + "=" * 80 + "\n")
response = group_chat.run(task)
print(f"Collaborative Response:\n{response}")
def example_agent_delegation():
"""Example showing how agents delegate to each other."""
print("\n" + "=" * 80)
print("=== Agent Delegation Example ===\n")
agents = create_collaborative_agents()
group_chat = InteractiveGroupChat(
name="Delegation Team",
description="A team that demonstrates effective delegation and collaboration",
agents=agents,
speaker_function=round_robin_speaker,
interactive=False,
)
# Task that encourages delegation
task = """We need to evaluate a potential new market entry opportunity in Southeast Asia.
The initial data shows promising growth potential, but we need a comprehensive assessment.
@analyst start with the market data analysis, then delegate to @researcher for market research,
and finally @strategist should provide strategic recommendations."""
print(f"Task: {task}\n")
print("Expected behavior:")
print(
"1. Analyst: Analyzes data and delegates to researcher for deeper market insights"
)
print(
"2. Researcher: Builds on data analysis and delegates to strategist for recommendations"
)
print(
"3. Strategist: Synthesizes all insights into strategic recommendations"
)
print("\n" + "=" * 80 + "\n")
response = group_chat.run(task)
print(f"Collaborative Response:\n{response}")
def example_synthesis_and_integration():
"""Example showing synthesis of multiple perspectives."""
print("\n" + "=" * 80)
print("=== Synthesis and Integration Example ===\n")
agents = create_collaborative_agents()
group_chat = InteractiveGroupChat(
name="Synthesis Team",
description="A team that excels at integrating multiple perspectives",
agents=agents,
speaker_function=round_robin_speaker,
interactive=False,
)
# Task requiring synthesis
task = """We have conflicting information about our product's market position:
- Sales data shows strong growth (25% increase)
- Customer surveys indicate declining satisfaction
- Competitor analysis shows we're losing market share
- Internal metrics show improved operational efficiency
@analyst @researcher @strategist please analyze these conflicting signals and provide
an integrated assessment of our true market position."""
print(f"Task: {task}\n")
print("Expected behavior:")
print(
"1. Analyst: Clarifies the data discrepancies and identifies patterns"
)
print(
"2. Researcher: Provides market context to explain the contradictions"
)
print(
"3. Strategist: Synthesizes all perspectives into a coherent market assessment"
)
print("\n" + "=" * 80 + "\n")
response = group_chat.run(task)
print(f"Collaborative Response:\n{response}")
def main():
"""Run all enhanced collaboration examples."""
print("Enhanced Collaborative InteractiveGroupChat Examples")
print("=" * 80)
print("This demonstrates improved agent collaboration with:")
print("- Acknowledgment of other agents' contributions")
print("- Building upon previous insights")
print("- Synthesis of multiple perspectives")
print("- Appropriate delegation using @mentions")
print("- Comprehensive understanding of conversation history")
print("=" * 80 + "\n")
# Run examples
example_comprehensive_analysis()
example_problem_solving()
example_agent_delegation()
example_synthesis_and_integration()
print("\n" + "=" * 80)
print("All enhanced collaboration examples completed!")
print("Notice how agents now:")
print("✓ Acknowledge each other's contributions")
print("✓ Build upon previous insights")
print("✓ Synthesize multiple perspectives")
print("✓ Delegate appropriately")
print("✓ Provide more cohesive and comprehensive responses")
if __name__ == "__main__":
main()

@ -0,0 +1,13 @@
from swarms import Agent
# Initialize a new agent
agent = Agent(
model_name="gpt-4o-mini", # Specify the LLM
max_loops=1, # Set the number of interactions
interactive=True, # Enable interactive mode for real-time feedback
streaming_on=True,
print_on=False,
)
# Run the agent with a task
agent.run("What are the key benefits of using a multi-agent system?")

@ -0,0 +1,72 @@
"""
InteractiveGroupChat Speaker Function Examples
This example demonstrates how to use different speaker functions in the InteractiveGroupChat:
- Round Robin: Agents speak in a fixed order, cycling through the list
- Random: Agents speak in random order
- Priority: Agents speak based on priority weights
- Custom: User-defined speaker functions
The example also shows how agents can mention each other using @agent_name syntax.
"""
from swarms import Agent
from swarms.structs.interactive_groupchat import (
InteractiveGroupChat,
random_speaker,
)
def create_example_agents():
"""Create example agents for demonstration."""
# Create agents with different expertise
analyst = Agent(
agent_name="analyst",
system_prompt="You are a data analyst. You excel at analyzing data, creating charts, and providing insights.",
model_name="gpt-4.1",
streaming_on=True,
print_on=True,
)
researcher = Agent(
agent_name="researcher",
system_prompt="You are a research specialist. You are great at gathering information, fact-checking, and providing detailed research.",
model_name="gpt-4.1",
streaming_on=True,
print_on=True,
)
writer = Agent(
agent_name="writer",
system_prompt="You are a content writer. You excel at writing clear, engaging content and summarizing information.",
model_name="gpt-4.1",
streaming_on=True,
print_on=True,
)
return [analyst, researcher, writer]
def example_random():
agents = create_example_agents()
# Create group chat with random speaker function
group_chat = InteractiveGroupChat(
name="Random Team",
description="A team that speaks in random order",
agents=agents,
speaker_function=random_speaker,
interactive=False,
)
# Test the random behavior
task = "Let's create a marketing strategy. @analyst @researcher @writer please contribute."
response = group_chat.run(task)
print(f"Response:\n{response}\n")
if __name__ == "__main__":
# example_round_robin()
example_random()

@ -408,7 +408,7 @@ class Agent:
llm_args: dict = None,
load_state_path: str = None,
role: agent_roles = "worker",
print_on: bool = False,
print_on: bool = True,
tools_list_dictionary: Optional[List[Dict[str, Any]]] = None,
mcp_url: Optional[Union[str, MCPConnection]] = None,
mcp_urls: List[str] = None,
@ -2787,16 +2787,15 @@ class Agent:
return self.role
def pretty_print(self, response: str, loop_count: int):
if self.print_on is False:
if self.streaming_on is True:
# Skip printing here since real streaming is handled in call_llm
# This avoids double printing when streaming_on=True
return
if self.print_on is False:
# Silent mode - no printing at all
return
pass
elif self.print_on is False:
pass
else:
# Use formatted panels (default behavior when print_on=True)
# logger.info(f"Response: {response}")
formatter.print_panel(
f"{self.agent_name}: {response}",
f"Agent Name {self.agent_name} [Max Loops: {loop_count} ]",

@ -1,5 +1,6 @@
import re
from typing import Callable, List, Union
import random
from typing import Callable, List, Union, Optional
from loguru import logger
@ -35,6 +36,91 @@ class InvalidTaskFormatError(InteractiveGroupChatError):
pass
class InvalidSpeakerFunctionError(InteractiveGroupChatError):
"""Raised when an invalid speaker function is provided"""
pass
# Built-in speaker functions
def round_robin_speaker(
agents: List[str], current_index: int = 0
) -> str:
"""
Round robin speaker function that cycles through agents in order.
Args:
agents: List of agent names
current_index: Current position in the cycle
Returns:
Next agent name in the round robin sequence
"""
if not agents:
raise ValueError("No agents provided for round robin")
return agents[current_index % len(agents)]
def random_speaker(agents: List[str], **kwargs) -> str:
"""
Random speaker function that selects agents randomly.
Args:
agents: List of agent names
**kwargs: Additional arguments (ignored)
Returns:
Randomly selected agent name
"""
if not agents:
raise ValueError("No agents provided for random selection")
return random.choice(agents)
def priority_speaker(
agents: List[str], priorities: dict, **kwargs
) -> str:
"""
Priority-based speaker function that selects agents based on priority weights.
Args:
agents: List of agent names
priorities: Dictionary mapping agent names to priority weights
**kwargs: Additional arguments (ignored)
Returns:
Selected agent name based on priority weights
"""
if not agents:
raise ValueError("No agents provided for priority selection")
# Filter agents that exist in the priorities dict
available_agents = [
agent for agent in agents if agent in priorities
]
if not available_agents:
# Fallback to random if no priorities match
return random.choice(agents)
# Calculate total weight
total_weight = sum(
priorities[agent] for agent in available_agents
)
if total_weight == 0:
return random.choice(available_agents)
# Select based on weighted probability
rand_val = random.uniform(0, total_weight)
current_weight = 0
for agent in available_agents:
current_weight += priorities[agent]
if rand_val <= current_weight:
return agent
return available_agents[-1] # Fallback
class InteractiveGroupChat:
"""
An interactive group chat system that enables conversations with multiple agents using @mentions.
@ -49,6 +135,8 @@ class InteractiveGroupChat:
max_loops (int): Maximum number of conversation turns
conversation (Conversation): Stores the chat history
agent_map (Dict[str, Union[Agent, Callable]]): Mapping of agent names to their instances
speaker_function (Callable): Function to determine speaking order
speaker_state (dict): State for speaker functions that need it
Args:
name (str, optional): Name of the group chat. Defaults to "InteractiveGroupChat".
@ -57,6 +145,8 @@ class InteractiveGroupChat:
max_loops (int, optional): Maximum conversation turns. Defaults to 1.
output_type (str, optional): Type of output format. Defaults to "string".
interactive (bool, optional): Whether to enable interactive terminal mode. Defaults to False.
speaker_function (Callable, optional): Function to determine speaking order. Defaults to round_robin_speaker.
speaker_state (dict, optional): Initial state for speaker function. Defaults to empty dict.
Raises:
ValueError: If invalid initialization parameters are provided
@ -71,6 +161,8 @@ class InteractiveGroupChat:
max_loops: int = 1,
output_type: str = "string",
interactive: bool = False,
speaker_function: Optional[Callable] = None,
speaker_state: Optional[dict] = None,
):
self.id = id
self.name = name
@ -80,6 +172,15 @@ class InteractiveGroupChat:
self.output_type = output_type
self.interactive = interactive
# Speaker function configuration
self.speaker_function = (
speaker_function or round_robin_speaker
)
self.speaker_state = speaker_state or {"current_index": 0}
# Validate speaker function
self._validate_speaker_function()
# Initialize conversation history
self.conversation = Conversation(time_enabled=True)
@ -96,6 +197,32 @@ class InteractiveGroupChat:
self._setup_conversation_context()
self._update_agent_prompts()
def _validate_speaker_function(self) -> None:
"""
Validates the speaker function.
Raises:
InvalidSpeakerFunctionError: If the speaker function is invalid
"""
if not callable(self.speaker_function):
raise InvalidSpeakerFunctionError(
"Speaker function must be callable"
)
# Test the speaker function with a dummy list
try:
test_result = self.speaker_function(
["test_agent"], **self.speaker_state
)
if not isinstance(test_result, str):
raise InvalidSpeakerFunctionError(
"Speaker function must return a string"
)
except Exception as e:
raise InvalidSpeakerFunctionError(
f"Speaker function validation failed: {e}"
)
def _validate_initialization(self) -> None:
"""
Validates the group chat configuration.
@ -150,6 +277,26 @@ class InteractiveGroupChat:
}
)
# Create the enhanced prompt that teaches agents how to use @mentions
mention_instruction = """
IMPORTANT: You are part of a collaborative group chat where you can interact with other agents using @mentions.
-COLLABORATIVE RESPONSE PROTOCOL:
1. FIRST: Read and understand all previous responses from other agents
2. ACKNOWLEDGE: Reference and acknowledge what other agents have said
3. BUILD UPON: Add your perspective while building upon their insights
4. MENTION: Use @agent_name to call on other agents when needed
HOW TO MENTION OTHER AGENTS:
- Use @agent_name to mention another agent in your response
- You can mention multiple agents: @agent1 @agent2
- When you mention an agent, they will be notified and can respond
- Example: "I think @analyst should review this data" or "Let's ask @researcher to investigate this further"
AVAILABLE AGENTS TO MENTION:
"""
group_context = (
f"\n\nYou are part of a group chat named '{self.name}' with the following description: {self.description}\n"
f"Other participants in this chat:\n"
@ -163,11 +310,40 @@ class InteractiveGroupChat:
for info in agent_info
if info["name"] != agent.agent_name
]
agent_context = group_context
agent_context = group_context + mention_instruction
for other in other_agents:
agent_context += (
f"- {other['name']}: {other['description']}\n"
)
agent_context += f"- @{other['name']}: {other['description']}\n"
# Add final instruction
agent_context += """
COLLABORATION GUIDELINES:
- ALWAYS read the full conversation history before responding
- ACKNOWLEDGE other agents' contributions: "Building on @analyst's data insights..." or "I agree with @researcher's findings that..."
- BUILD UPON previous responses rather than repeating information
- SYNTHESIZE multiple perspectives when possible
- ASK CLARIFYING QUESTIONS if you need more information from other agents
- DELEGATE appropriately: "Let me ask @expert_agent to verify this" or "@specialist, can you elaborate on this point?"
RESPONSE STRUCTURE:
1. ACKNOWLEDGE: "I've reviewed the responses from @agent1 and @agent2..."
2. BUILD: "Building on @agent1's analysis of the data..."
3. CONTRIBUTE: "From my perspective, I would add..."
4. COLLABORATE: "To get a complete picture, let me ask @agent3 to..."
5. SYNTHESIZE: "Combining our insights, the key findings are..."
EXAMPLES OF GOOD COLLABORATION:
- "I've reviewed @analyst's data analysis and @researcher's market insights. The data shows strong growth potential, and I agree with @researcher that we should focus on emerging markets. Let me add that from a content perspective, we should @writer to create targeted messaging for these markets."
- "Building on @researcher's findings about customer behavior, I can see that @analyst's data supports this trend. To get a complete understanding, let me ask @writer to help us craft messaging that addresses these specific customer needs."
AVOID:
- Ignoring other agents' responses
- Repeating what others have already said
- Making assumptions without consulting relevant experts
- Responding in isolation without considering the group's collective knowledge
Remember: You are part of a team. Your response should reflect that you've read, understood, and built upon the contributions of others.
"""
# Update the agent's system prompt
agent.system_prompt = (
@ -202,6 +378,118 @@ class InteractiveGroupChat:
logger.error(f"Error extracting mentions: {e}")
raise InvalidTaskFormatError(f"Invalid task format: {e}")
def _get_speaking_order(
self, mentioned_agents: List[str]
) -> List[str]:
"""
Determines the speaking order using the configured speaker function.
Args:
mentioned_agents: List of agent names that were mentioned
Returns:
List of agent names in the order they should speak
"""
if not mentioned_agents:
return []
# Use the speaker function to determine order
try:
if self.speaker_function == round_robin_speaker:
# For round robin, we need to maintain state
current_index = self.speaker_state.get(
"current_index", 0
)
ordered_agents = []
# Create the order starting from current index
for i in range(len(mentioned_agents)):
agent = round_robin_speaker(
mentioned_agents, current_index + i
)
ordered_agents.append(agent)
# Update state for next round
self.speaker_state["current_index"] = (
current_index + len(mentioned_agents)
) % len(mentioned_agents)
return ordered_agents
elif self.speaker_function == random_speaker:
# For random, shuffle the list
shuffled = mentioned_agents.copy()
random.shuffle(shuffled)
return shuffled
elif self.speaker_function == priority_speaker:
# For priority, we need priorities in speaker_state
priorities = self.speaker_state.get("priorities", {})
if not priorities:
# Fallback to random if no priorities set
shuffled = mentioned_agents.copy()
random.shuffle(shuffled)
return shuffled
# Sort by priority (higher priority first)
sorted_agents = sorted(
mentioned_agents,
key=lambda x: priorities.get(x, 0),
reverse=True,
)
return sorted_agents
else:
# Custom speaker function
# For custom functions, we'll use the first agent returned
# and then process the rest in original order
first_speaker = self.speaker_function(
mentioned_agents, **self.speaker_state
)
if first_speaker in mentioned_agents:
remaining = [
agent
for agent in mentioned_agents
if agent != first_speaker
]
return [first_speaker] + remaining
else:
return mentioned_agents
except Exception as e:
logger.error(f"Error in speaker function: {e}")
# Fallback to original order
return mentioned_agents
def set_speaker_function(
self,
speaker_function: Callable,
speaker_state: Optional[dict] = None,
) -> None:
"""
Set a custom speaker function and optional state.
Args:
speaker_function: Function that determines speaking order
speaker_state: Optional state for the speaker function
"""
self.speaker_function = speaker_function
if speaker_state:
self.speaker_state.update(speaker_state)
self._validate_speaker_function()
logger.info(
f"Speaker function updated to: {speaker_function.__name__}"
)
def set_priorities(self, priorities: dict) -> None:
"""
Set agent priorities for priority-based speaking order.
Args:
priorities: Dictionary mapping agent names to priority weights
"""
self.speaker_state["priorities"] = priorities
logger.info(f"Agent priorities set: {priorities}")
def start_interactive_session(self):
"""
Start an interactive terminal session for chatting with agents.
@ -303,8 +591,16 @@ class InteractiveGroupChat:
# Add user task to conversation
self.conversation.add(role="User", content=task)
# Get responses from mentioned agents
for agent_name in mentioned_agents:
# Determine speaking order using speaker function
speaking_order = self._get_speaking_order(
mentioned_agents
)
logger.info(
f"Speaking order determined: {speaking_order}"
)
# Get responses from mentioned agents in the determined order
for agent_name in speaking_order:
agent = self.agent_map.get(agent_name)
if not agent:
raise AgentNotFoundError(
@ -319,9 +615,20 @@ class InteractiveGroupChat:
# Get response from agent
if isinstance(agent, Agent):
response = agent.run(
task=f"{context}\nPlease respond to the latest task as {agent_name}."
)
collaborative_task = f"""{context}
COLLABORATIVE TASK: Please respond to the latest task as {agent_name}.
IMPORTANT INSTRUCTIONS:
1. Read the ENTIRE conversation history above
2. Acknowledge what other agents have said before adding your perspective
3. Build upon their insights rather than repeating information
4. If you need input from other agents, mention them using @agent_name
5. Provide your unique expertise while showing you understand the group's collective knowledge
Remember: You are part of a collaborative team. Your response should demonstrate that you've read, understood, and are building upon the contributions of others."""
response = agent.run(task=collaborative_task)
else:
# For callable functions
response = agent(context)

Loading…
Cancel
Save