Agent Orchestration: Coordinating Multiple Agents - AG2
Agent Orchestration: Coordinating Multiple Agents
In our financial compliance example, we've successfully implemented a human-in-the-loop agent that processes transactions and flags suspicious ones for human approval. This works well for basic compliance checking, but what if we need to provide detailed summary reports after all transactions are processed?
We could expand the system message of our finance_bot to include this functionality, but this approach isn't scalable as requirements grow more complex. The finance_bot would have multiple responsibilities, making it harder to maintain and extend.
The Need for Specialized Agents
As our financial compliance system evolves, we might need to:
- Generate formatted summary reports of all transactions
- Perform risk analysis on transaction patterns
- Create visualizations of financial data
- Send notifications to relevant stakeholders
Each of these tasks requires different specialized knowledge and skills. This is where AG2's orchestration patterns come in - they allow us to coordinate multiple specialized agents to work together seamlessly.
Introducing the Group Chat Pattern
AG2 offers several orchestration patterns, and for our evolving financial compliance system, the Group Chat pattern is particularly powerful. It allows specialized agents to collaborate with dynamic handoffs to achieve complex workflows.
An Analogy for Group Chat Pattern:
Continuing our hospital treatment system analogy from the HITL. Think of the Group Chat pattern like a hospital emergency in the hospital:
- The patient first sees whichever specialist is most appropriate (a triage agent)
- Each specialist (specialized agent) handles a specific aspect of patient care
- After completing their work, specialists can explicitly transfer the patient to another specialist based on what they found (agent handoffs)
- If a specialist doesn't specify who should see the patient next, we can revert to the hospital coordinator (Group chat manager) who can review the patient's chart and decide which specialist would be most appropriate
- The patient record follows them through the entire process (shared context)
- The entire system works together to ensure the patient receives the right care at the right time
This pattern leverages specialized skills while maintaining a cohesive workflow across multiple participants, with both direct handoffs and intelligent coordination when needed.
From Concept to Implementation
Implementing a group chat in AG2 is a simple two-step process:
- First, create a pattern that defines how agents will interact
- Then, initialize the group chat using the pattern
The pattern defines the orchestration logic - which agents are involved, who speaks first, and how to transition between agents. AG2 provides several pre-defined patterns to choose from:
- DefaultPattern: A minimal pattern for simple agent interactions where the handoffs and transitions needs to be explicitly defined
- AutoPattern: Automatically selects the next speaker based on conversation context
- RoundRobinPattern: Agents speak in a defined sequence
- RandomPattern: Randomly selects the next speaker
- ManualPattern: Allows human selection of the next speaker
The easiest pattern to get started with is the AutoPattern, where a group manager agent automatically selects agents to speak by evaluating the messages in the chat and the descriptions of the agents. This creates a natural workflow where the most appropriate agent responds based on the conversation context.
Here's how you implement a basic group chat:
from autogen import ConversableAgent, LLMConfig
from autogen.agentchat import initiate_group_chat
from autogen.agentchat.group.patterns import AutoPattern
# build a Config List
llm_config = LLMConfig(
config_list={
"api_type": "openai",
"model": "gpt-5-nano",
"api_key": os.environ.get("OPENAI_API_KEY"),
}
)
# Create your specialized agents
agent_1 = ConversableAgent(name="agent_1", llm_config=llm_config, system_message="goto agent_2")
agent_2 = ConversableAgent(name="agent_2", llm_config=llm_config, system_message="go back to agent_1")
# Create human agent if needed
human = ConversableAgent(name="human", human_input_mode="ALWAYS")
# Set up the pattern for orchestration
pattern = AutoPattern(
initial_agent=agent_1, # Agent that starts the workflow
agents=[agent_1, agent_2], # All agents in the group chat
user_agent=human, # Human agent for interaction
group_manager_args={"llm_config": llm_config} # Config for group manager
)
# Initialize the group chat
result, context_variables, last_agent = initiate_group_chat(
pattern=pattern,
messages="Initial request", # Starting message
)
Enhancing Our Financial Compliance System with Group Chat
Now that we understand the group chat pattern, let's see how it solves our challenge of adding specialized summary reporting to our financial compliance system.
The Challenge
In our Human in the Loop example, we built a finance_bot that could process transactions and get human approval for suspicious ones. However, we now need professional, formatted summary reports of all the transactions.
Our Group Chat Solution
Here's how we'll enhance our system:
- Keep the
finance_botfocused on transaction processing and human approval - Create a new
summary_botspecialized in generating formatted transaction reports - Use the group chat with
AutoPatternpattern to automatically transition fromfinance_bottosummary_botwhen all transactions are processed - Maintain human oversight for suspicious transaction approval and to terminate the conversation
Implementation: Creating the Necessary Agents
Let's create a new specialized agent for generating summary reports. We'll also keep our existing finance_bot for transaction processing and a human agent for oversight.
from autogen import ConversableAgent, LLMConfig
from autogen.agentchat import initiate_group_chat
from autogen.agentchat.group.patterns import AutoPattern
import os
import random
from dotenv import load_dotenv
load_dotenv()
# Note: Make sure to set your API key in your environment first
# Build a LLM Config List
llm_config = LLMConfig(
config_list={
"api_type": "openai",
"model": "gpt-5-nano",
"api_key": os.environ.get("OPENAI_API_KEY"),
}
)
# Define the system message for our finance bot
finance_system_message = """
You are a financial compliance assistant. You will be given a set of transaction descriptions.
For each transaction:
- If it seems suspicious (e.g., amount > $10,000, vendor is unusual, memo is vague), ask the human agent for approval.
- Otherwise, approve it automatically.
Provide the full set of transactions to approve at one time.
If the human gives a general approval, it applies to all transactions requiring approval.
When all transactions are processed, summarize the results and say "You can type exit to finish".
"""
# Define the system message for the summary agent
summary_system_message = """
You are a financial summary assistant. You will be given a set of transaction details and their approval status.
Your task is to summarize the results of the transactions processed by the finance bot.
Generate a markdown table with the following columns:
- Vendor
- Memo
- Amount
- Status (Approved/Rejected)
The summary should include the total number of transactions, the number of approved transactions, and the number of rejected transactions.
The summary should be concise and clear.
"""
# Create the finance agent with LLM intelligence
finance_bot = ConversableAgent(
name="finance_bot",
llm_config=llm_config,
system_message=finance_system_message,
)
summary_bot = ConversableAgent(
name="summary_bot",
llm_config=llm_config,
system_message=summary_system_message,
)
# Create the human agent for oversight
human = ConversableAgent(
name="human",
human_input_mode="ALWAYS",
)
# Generate sample transactions - this creates different transactions each time you run
VENDORS = ["Staples", "Acme Corp", "CyberSins Ltd", "Initech", "Globex", "Unicorn LLC"]
MEMOS = ["Quarterly supplies", "Confidential", "NDA services", "Routine payment", "Urgent request", "Reimbursement"]
def generate_transaction():
amount = random.choice([500, 1500, 9999, 12000, 23000, 4000])
vendor = random.choice(VENDORS)
memo = random.choice(MEMOS)
return f"Transaction: ${amount} to {vendor}. Memo: {memo}."
# Generate 3 random transactions
transactions = [generate_transaction() for _ in range(3)]
# Format the initial message
initial_prompt = (
"Please process the following transactions one at a time:\n\n" +
"\n".join([f"{i+1}. {tx}" for i, tx in enumerate(transactions)])
)
# Create pattern for the group chat
pattern = AutoPattern(
initial_agent=finance_bot, # Start with the finance bot
agents=[finance_bot, summary_bot], # All agents in the group chat
user_agent=human, # Provide our human-in-the-loop agent
group_manager_args={"llm_config": llm_config} # Config for group manager
)
# Initialize the group chat
result, context_variables, last_agent = initiate_group_chat(
pattern=pattern,
messages=initial_prompt, # Initial request with transactions
)