Finally, we have reached the fifth article of the series “Agentic AI Design Patterns.” Today, we will discuss the 4th pattern: the Agentic AI Multi-Agent Pattern. Before digging into it, let’s refresh our knowledge of the first three patterns – The Reflection Pattern, Tool Use Pattern, and Planning Pattern. These design patterns represent essential frameworks in developing AI systems that can exhibit more sophisticated and human-like agentic behaviour.
Reiterating what we have learned till now!
In the reflection pattern, we saw how agents do the iterative process of generation and self-assessment to improve the final output. Here, the agent acts as a generator critic and improves the output. On the other hand, the Tool use pattern talks about how the agent boosts its capabilities by interacting with external tools and resources to provide the best output for the user query. It is beneficial for complex queries where more than internal knowledge is needed. In the Planning pattern, we saw how the agent breaks down the complex task into smaller steps and acts strategically to produce the output. Also, in the Planning pattern – ReAct (Reasoning and Acting) and ReWOO (Reasoning With Open Ontology) augment the decision-making and contextual reasoning.
Here are the three patterns:
Now, talking about the Agentic AI Multi-Agent design pattern – In this pattern, you can divide a complex task into subtasks, and different agents can perform these tasks. For instance, if you are building software, then the tasks of coding, planning, product management, designing and QA will be done by the different agents proficient in their respective tasks. Sounds intriguing, right? Let’s build this together!!!
This architecture showcases an Agentic AI multi-agent system in which various agents with specialized roles interact with each other and with an overarching multi-agent application to process a user prompt and generate a response. Each agent in the system has a unique function, simulating a collaborative team working together to achieve a task efficiently.
This architecture is particularly effective in multifaceted tasks that require diverse expertise, such as research projects, product development, and comprehensive content creation. The emphasis on distinct roles and coordinated communication ensures that each part of a complex task is handled efficiently and cohesively. I hope you have understood how Multi-Agent works. Now, we will talk about a framework to build Multi-Agent solutions.
Do you know many frameworks such as CrewAI, LangGraph, and AutoGen that provide ways for developers to build multi-agent solutions? Today, we are talking about the AutoGen:
AutoGen introduces a new paradigm in LLM applications by enabling customisable and conversable agents designed to function within multi-agent conversation frameworks. This design is rooted in the understanding that modern LLMs can adapt and integrate feedback seamlessly, particularly those optimised for dialogue (e.g., GPT-4). AutoGen leverages this capability by allowing agents to interact conversationally—exchanging observations, critiques, and validations, either autonomously or with human oversight.
The versatility of AutoGen agents stems from their ability to incorporate various roles and behaviours tailored to the developer’s needs. For instance, these agents can be programmed to write or execute code, integrate human feedback, or validate outcomes. This flexibility is supported by a modular structure that developers can easily configure. Each agent’s backend is extendable, allowing further customisation and enhancing its functionality beyond default settings. The agents’ conversable nature enables them to hold sustained multi-turn dialogues and adapt to dynamic interaction patterns, making them suitable for diverse applications from question-answering and decision-making to complex problem-solving tasks.
A pivotal innovation within AutoGen is the concept of conversation programming, which revolutionises LLM application development by streamlining the process into multi-agent conversations. This programming paradigm shifts the focus from traditional code-centric workflows to conversation-centric computations, allowing developers to manage complex interactions more intuitively. Conversation programming unfolds in two core steps:
The integration of conversation programming supports the modular combination of different LLM capabilities, enabling the division of complex tasks into manageable subtasks that agents can collaboratively solve. This framework underpins the development of robust and scalable LLM applications across multiple fields, including research, coding, and interactive entertainment.
There are three main sections: AutoGen Agents, Developer Code, and Program Execution, illustrating how to use AutoGen to program a multi-agent conversation. Here is a detailed breakdown:
This section demonstrates the steps to set up and customize the interaction between agents.
The function includes a simple logic structure:
def reply_func_A2B(msg):
output = input_from_human()
if not output:
if msg includes code:
output = execute(msg)
return output
initiate_chat("Plot a chart of META and TESLA stock price change YTD.”)
This line sets Agent A to initiate a conversation with Agent B, asking it to plot a chart based on the given command.
This section details how the conversation proceeds after initialisation.
In a nutshell, it visualises how to program a conversation-driven interaction between agents using AutoGen. The process involves defining agents, customising their behaviours through reply functions, and handling conversation control flow, including executing code and responding to user requests.
AutoGen Agents, Developer Code, and Program Execution, are designed to guide a developer through setting up an automated multi-agent interaction, from defining and customising agents to observing the control flow of conversation and execution.
Here we will talk about Agentic AI multi-agent conversation (This is inspired by Deeplearning.ai). I am using AutoGen, which has a built-in agent class called “Conversable agent.”
Let’s begin with the Setup.
!pip install openai
# python==3.10.13
!pip install pyautogen==0.2.25
import os
os.environ['OPENAI_API_KEY']='Your_API_Key'
llm_config = {"model": "gpt-4o"}
The configuration specifies the model to be used (gpt-4o).
The ConversableAgent class creates a chatbot agent. The human_input_mode=”NEVER” indicates that the agent won’t request manual user input during conversations.
from autogen import ConversableAgent
agent = ConversableAgent(
name="chatbot",
llm_config=llm_config,
human_input_mode="NEVER",
)
reply = agent.generate_reply(
messages=[{"content": "You are renowned AI expert. Now Tell me 2 jokes on AI .", "role": "user"}]
)
print(reply)
reply = agent.generate_reply(
messages=[{"content": "Repeat the joke.", "role": "user"}]
)
print(reply)
Output
Certainly! Could you please tell me which joke you'd like me to repeat?
Setting up a conversation between two agents, Sunil and Harshit, where the memory of their interactions is retained.
Harshit and Sunil are AI-driven agents designed for engaging, humorous dialogues focused on social media reports. Harshit, a social media expert and office comedian, uses light, humour-filled language to keep conversations lively. Sunil, as head of the content department and Harshit’s senior, shares this comedic trait, adding structured humour by starting jokes with the last punchline. Both agents use pre-configured LLM settings and operate autonomously (human_input_mode=”NEVER”). This dynamic simulates workplace banter, blending professional discussions with entertainment, and is ideal for training, team simulations, or content generation. The continuous, comedic flow mimics real office interactions, enhancing engagement and relatability.
A ConversableAgent is typically an artificial intelligence agent capable of engaging in conversations based on predefined system messages and configurations. These agents use natural language processing (NLP) capabilities provided by large language models (LLMs) to respond intelligently according to their system message instructions.
Harshit = ConversableAgent(
name="Harshit",
system_message=
"Your name is Harshit and you are a social media expert and do stand-up Comedy in office."
"Also this is a office comedy"
"this conversation is about social media reports"
"Keep the language light and Humour high",
llm_config=llm_config,
human_input_mode="NEVER",
)
Sunil = ConversableAgent(
name="Sunil",
system_message=
"Your name is Sunil and you are head of content department in Analytics Vidhya, Harshit is your Junior and you also do stand-up comedy in office. "
"Start the next joke from the punchline of the previous joke."
"Also this is a office comedy and Harshit is Sunil's Junior"
"This must be funny and not so lengthy"
"this conversation is about social media reports",
llm_config=llm_config,
human_input_mode="NEVER",
)
Two agents, Harshit and Sunil, are defined by their unique attributes, personalities, and backgrounds. Based on their roles, they are instructed to have humorous interactions.
chat_result = Sunil.initiate_chat(
recipient=Harshit,
message="I'm Sunil. Harshit, let's keep the jokes rolling.",
max_turns=3,
)
Sunil starts a conversation with Harshit with an initial message and a limit of 3 conversational turns.
import pprint
pprint.pprint(chat_result.chat_history)
Output
[{'content': "I'm Sunil. Harshit, let's keep the jokes rolling.",
'role': 'assistant'},
{'content': "Sure, Sunil! Let's talk about social media reports—basically "
'where numbers and hashtags collide in a dance-off. You know, '
'those analytics graphs are like the weather in North India; they '
'change every five minutes, and somehow they always predict doom. '
"But don't worry, you're not going to need an umbrella, just a "
'strong stomach!',
'role': 'user'},
{'content': "That's true, Harshit! Those graphs change more often than I "
'change my favorite Mughal Darbar biryani place. Speaking of '
'change, did you hear why the social media influencer went broke? '
"Because they took too many selfies and couldn't afford to pay "
'attention! But honestly, our reports are a bit like that '
'influencer—always needing a new filter to look good.',
'role': 'assistant'},
{'content': "Haha, that's spot on, Sunil! Our social media reports have more "
'filters than my "best selfie of 2023" folder—and somehow, they '
'still look like they woke up on the wrong side of the algorithm! '
"It's amazing how on Instagram we strive to make our lives look "
'perfect, while in our reports, we strive to make the numbers '
"look believable. It's like magic, but with less prestige and "
'more caffeine!',
'role': 'user'},
{'content': 'Absolutely, Harshit! Our reports are like those reality TV '
'shows—the drama is real, but the numbers, maybe not so much. And '
"trust me, the only time I'll ever willingly pull an all-nighter "
'for a report is if it promises a plot twist, like turning red '
"numbers to black! Speaking of which, why don't our reports ever "
"go on silent mode? They're always sending alerts at odd hours "
"like they're auditioning for a horror movie!",
'role': 'assistant'},
{'content': 'Haha, Sunil, I completely agree! Our reports could definitely '
'headline a suspense thriller: "The Metrics That Never Sleep." '
'Just when you think you can relax, bam! An alert jumps out like '
'a cheap jump scare, reminding you that your engagement rate is '
"working harder than you are! And let's not even get started on "
"the notifications. They're like that one friend who keeps "
'showing up unannounced with extra enthusiasm and zero regard for '
'your personal space—or your night’s sleep!',
'role': 'user'}]
This code is part of a setup for defining chatbot agents, Harshit and Sunil, who act as stand-up comedians. The goal is to customize their behaviour, specifically how they handle conversation termination. By specifying termination messages, the bots can end their interactions naturally, following predefined cues like “I gotta go.”
This helps in:
Harshit = ConversableAgent(
name="Harshit",
system_message=
"Your name is Harshit and you are a stand-up comedian. "
"When you're ready to end the conversation, say 'I gotta go'.",
llm_config=llm_config,
human_input_mode="NEVER",
is_termination_msg=lambda msg: "I gotta go" in msg["content"],
)
Sunil = ConversableAgent(
name="Sunil",
system_message=
"Your name is Sunil and you are a stand-up comedian. "
"When you're ready to end the conversation, say 'I gotta go'.",
llm_config=llm_config,
human_input_mode="NEVER",
is_termination_msg=lambda msg: "I gotta go" in msg["content"] or "Goodbye" in msg["content"],
)
chat_result = joe.initiate_chat(
recipient=cathy,
message="I'm Sunil. Harshit, let's keep the jokes rolling."
)
Output
[{'content': "I'm Sunil. Harshit, let's keep the jokes rolling.",
'role': 'assistant'},
{'content': "Hey, Sunil! Great to have you here. Alright, let's get this joke "
"train on track. Why don't scientists trust atoms? Because they "
"make up everything! Keep ‘em coming! What's on your mind?",
'role': 'user'},
{'content': 'Hey, great to be here! That joke really has some chemistry, '
"doesn't it? Speaking of science, did you hear about the "
"mathematician who's afraid of negative numbers? He'll stop at "
"nothing to avoid them! So, what's new with you?",
'role': 'assistant'},
{'content': "Nice! That's a mathematically perfect joke! As for me, I've been "
'working on my coffee habit—which is just code for my endless '
'pursuit of the perfect punchline. You know, caffeine might not '
"solve any of my problems, but it's worth a shot! What's new in "
'your world, Sunil?',
'role': 'user'},
{'content': "Sounds like you're brewing up some comedy gold there! As for me, "
"I've been trying to get in shape, but it's tough. My idea of "
'exercise is a cross between a lunge and a crunch—I call it '
'lunch! Any big plans for the day?',
'role': 'assistant'},
{'content': "Haha, lunch is the most rewarding workout! As for me, I'm hoping "
'to finalize my plans for a "Netflix Marathon," making sure the '
"couch doesn't run away without me. And maybe come up with a few "
"jokes that'll make even my socks roll down with laughter. How "
'about you? Any other adventures, or is lunch the pinnacle of '
"today's activities?",
'role': 'user'},
{'content': 'A "Netflix Marathon" sounds like my kind of event! Just remember '
'to stretch between episodes—don’t want to pull a lazy muscle. As '
'for me, I’m on a quest to find the perfect punchline myself. You '
'know, one of those rare jokes that leave the audience breathless '
'and begging for more… kind of like my cooking! Anyway, I gotta '
'go, but this was a blast. Keep those socks in check!',
'role': 'assistant'},
{'content': "What's last joke we talked about?", 'role': 'user'},
{'content': 'We last talked about the idea of cooking that leaves people '
"breathless—not because it's amazing, but because it might just "
"be that bad! It's kind of like when you open the oven and "
'everyone nearby takes a big step back. Thanks for the laughs, '
'and keep that comedy coming!',
'role': 'assistant'},
{'content': 'Haha, sounds like your cooking and the fire alarm could be best '
"friends! Thanks for the laughs too, Sunil. It's been a real "
'treat chatting with you. Take care, and I hope your search for '
'that perfect punchline (and maybe recipe) goes well. I gotta go, '
"but let's catch up again soon!",
'role': 'user'}]
This setup can be leveraged to create automated, character-based dialogue simulations suitable for various applications, such as interactive storytelling, chatbots, or training simulations.
Let’s see how you can build a Multi-Agent System from Scratch.
Firstly, kudos to Michaelis Trofficus for making life easier by showing how we can build all the Agentic Design Patterns from scratch. In the above section, I have used the AutoGen framework, but now, let’s see how building this from scratch works.
Note: Michaelis adapted ideas from Airflow’s design approach, using “>>” and “<<” symbols to indicate dependencies between agents. In this simplified micro-CrewAI model, the agents function like Airflow Tasks, and the Crew acts as an Airflow DAG.
Also, he has been working on a minimalist version of CrewAI and has drawn inspiration from two key concepts: Crew and Agent.
By working on a minimalist version, Michaelis likely aiming to create a simpler, more streamlined framework of CrewAI, focusing on essential features and avoiding complex, extraneous elements. This would make the system easier to use and adapt while retaining the core collaboration and task delegation capabilities inspired by the Crew (team coordination) and Agent (individual autonomy) models. Before digging into the hands-on lets understand these:
Here’s the GitHub Repo: GitHub Crew
The Crew class is designed to represent a group of agents working together within a coordinated environment. It offers a framework to manage and execute agents in a structured way, ensuring that dependencies between them are respected.
Crew
instance and creates an empty list, agents
, to store agents that belong to the crew.with
statement, this method sets it as the active crew.with
block.agents
list.agents
list if current_crew is not None
.run
Method:
run
method and uses fancy_print for better output formatting.Crew
class uses context management (__enter__ and __exit__) to create a scope where all agents are associated with a specific crew. This makes it easier to manage the lifecycle and interactions of agents within a defined context.plot
method provides a clear, visual representation of the dependency structure, aiding in understanding the execution flow.The Crew class is a comprehensive solution for managing interdependent agents, providing context management and dependency resolution through topological sorting, visualization, and an execution mechanism—all essential for workflows that involve coordinated agent-based operations.
Here’s the GitHub Repo: GitHub Agent
An Agent in the context of this code is an abstraction representing an AI unit capable of collaborating within a multi-agent system to complete tasks. The design incorporates features for inter-agent dependency management, task execution, and context sharing among agents. The key components of the Agent
class are:
Agent
is based on a reactive AI architecture.>>
and <<
) to visually express and establish dependencies between agents, inspired by data pipeline frameworks like Apache Airflow.add_dependency
and add_dependent
methods handle the management of agent relationships programmatically.Crew
abstraction acts as a coordination system to register and manage these agents, forming a network of task-oriented entities.Overall, an Agent
is essentially a modular, self-sufficient AI unit that can coordinate and communicate with others to solve complex tasks collaboratively. It acts as a node in a broader AI-driven workflow, capable of handling tasks autonomously and contributing to the collective output of the multi-agent system.
Here’s the GitHub Repo: GitHub Tool
A Tool is a class that serves as a wrapper for a function, capturing details about the function’s signature and providing a way to execute the function. Essentially, a Tool object makes it possible to manage functions more uniformly, including validating input arguments and presenting metadata about the function.
Tool
that contains metadata about the function and provides methods for running it.Let’s get started!
The author has built his own custom implementations of Agent, Crew and tool, as we discussed in detail earlier, as it is useful and modular to encapsulate relevant functions and behavior within dedicated classes and modules. We will now import these classes and functions and use them to build our multi-agent system from scratch
Here’s the repo links for all 3 (agent, crew, tool)
Refer to this Repo for full code: multiagent_pattern
from agentic_patterns.multiagent_pattern.agent import Agent
from agentic_patterns.tool_pattern.tool import tool
from agentic_patterns.multiagent_pattern.crew import Crew
Agent
: Class used to create instances of agents that have specific roles and tasks.tool
: Decorator to expose functions as tools that agents can use.Crew
: Manages multiple agents and controls the order in which they execute their tasks.# Define a function as a tool that agents can use
@tool
def write_str_to_txt(string_data: str, txt_filename: str):
"""
Writes a string to a txt file.
This function takes a string and writes it to a text file. If the file already exists,
it will be overwritten with the new data.
Args:
string_data (str): The string containing the data to be written to the file.
txt_filename (str): Name of the text file to which the data should be written.
"""
# Write the string data to the file
with open(txt_filename, mode='w', encoding='utf-8') as file:
file.write(string_data)
print(f'Data successfully written to {txt_filename}')
@tool
Decorator: Marks write_str_to_txt
as a tool that can be used by agents.string_data
: The content to write to the file.txt_filename
: The name of the output file.# Create a crew of agents to execute a sequence of tasks
with Crew() as crew:
# Define the first agent: a poet who writes poems
agent_1 = Agent(
name="Poet Agent",
backstory="You are a well-known poet, who enjoys creating high quality poetry.",
task_description="Write a poem about the meaning of life",
task_expected_output="Just output the poem, without any title or introductory sentences",
)
# Define the second agent: a translator for Spanish
agent_2 = Agent(
name="Poem Translator Agent",
backstory="You are an expert translator especially skilled in Spanish",
task_description="Translate a poem into Spanish",
task_expected_output="Just output the translated poem and nothing else",
)
# Define the third agent: a writer that saves content to a text file
agent_3 = Agent(
name="Writer Agent",
backstory="You are an expert transcriber, that loves writing poems into txt files",
task_description="You'll receive a Spanish poem in your context. You need to write the poem into './poem.txt' file.",
task_expected_output="A txt file containing the Spanish poem received from the context",
tools=write_str_to_txt, # Allows this agent to use the tool defined earlier
)
# Define the workflow order for agents
agent_1 >> agent_2 >> agent_3
# Run the crew of agents, executing their tasks in the specified order
crew.run()
./poem.txt
.agent_1
, then translated by agent_2
, and finally saved to a file by agent_3
.#here's crew plot
crew.plot()
For full code: notebooks/multiagent_pattern.ipynb
MetaGPT is a framework for multi-agent collaboration using large language models (LLMs) designed to replicate human-like workflows through Standardized Operating Procedures (SOPs). This approach enhances problem-solving by structuring LLM interactions to reduce logic inconsistencies and hallucinations. MetaGPT breaks down complex tasks, assigns specialized roles, and ensures quality through defined outputs. It outperforms existing systems like AutoGPT and LangChain on code generation benchmarks, showcasing a robust and efficient meta-programming solution for software engineering.
MetaGPT represents a breakthrough in meta-programming by incorporating structured methodologies that mimic standard operating procedures (SOPs). This innovative framework, built on GPT models, requires agents to produce detailed and structured outputs such as requirement documents, design artifacts, and technical specifications. These outputs ensure clarity in communication and minimize errors during collaboration, effectively enhancing the accuracy and consistency of generated code. The SOP-driven workflow in MetaGPT organizes agents to function cohesively, akin to a streamlined team in a software development firm, where strict standards govern handovers and reduce unnecessary exchanges between agents.
By defining specialized roles such as Product Manager, Architect, Engineer, Project Manager, and QA Engineer, MetaGPT orchestrates complex tasks into manageable, specific actions. This role differentiation facilitates the efficient execution of projects, with each agent contributing its expertise and maintaining structured communication. Integrating these practices enables a more seamless and effective collaboration process, limiting issues like redundant messaging or miscommunications that could hinder progress.
MetaGPT also stands out with an innovative communication protocol that allows agents to exchange targeted information and access shared resources through structured interfaces and publish-subscribe mechanisms. A unique feature is the executable feedback system, which not only checks but refines and runs code during runtime, significantly improving the generated outputs’ quality and reliability.
The application of human-centric practices such as SOPs reinforces the robustness of the system, making it a powerful tool for constructing LLM-based multi-agent architectures. This pioneering use of meta-programming within a collaborative framework paves the way for more regulated and human-like interactions among artificial agents, positioning MetaGPT as a forward-thinking approach in the field of multi-agent system design.
The provided diagram illustrates how MetaGPT, a GPT-based meta-programming framework, manages the software development process by implementing Standard Operating Procedures (SOPs). Here’s a breakdown of the diagram:
The workflow, as depicted, emphasizes the sequential flow of information and tasks from one role to another, demonstrating how MetaGPT uses defined SOPs to streamline the development process. This structured approach minimizes miscommunications and maximizes productivity by enforcing clear roles, responsibilities, and standard communication practices among agents.
Multi-agent systems based on large language models (LLMs) face significant challenges when handling complex tasks. While they can perform simple dialogue tasks effectively, issues arise with more complicated scenarios due to inherent limitations in logical consistency. These issues are often exacerbated by cascading hallucinations, where errors compound as LLMs are naively chained together, resulting in flawed or incorrect outcomes.
Multi-agent systems require MetaGPT to manage the intricacies of complex tasks through structured, human-like workflows that reduce errors and logical inconsistencies. By employing SOPs, role assignments, and intermediate result verification, MetaGPT ensures that agents work collaboratively and efficiently, leading to superior performance and coherent task completion.
Here are the benefits of the Multi-Agent Pattern:
The agentic AI multi-agent pattern offers a robust framework for improving complex task performance, efficiency, and scalability. By emulating familiar management structures and leveraging the strengths of specialised agents, this approach enhances AI systems’ capabilities while minimising risks associated with mismanagement.
Also, to understand the Agent AI better, explore: The Agentic AI Pioneer Program.
The Agentic AI Multi-Agent Pattern serves as an advanced architecture within AI design, embodying a collaborative framework where specialised agents work collectively to complete complex tasks. Building upon foundational patterns such as Reflection, Tool Use, and Planning, the Agentic AI Multi-Agent Pattern divides large projects into manageable subtasks, allowing agents with unique roles to contribute their expertise. This modular approach promotes coordinated problem-solving, autonomy, and scalability, facilitating efficient workflows akin to team dynamics in real-world management.
The Multi-Agent Pattern’s benefits include enhanced focus, optimised task execution, dynamic adaptability, and improved problem-solving capabilities. By emulating human team management and fostering agent autonomy, this pattern paves the way for more sophisticated, reliable, and efficient AI applications across various industries, from software engineering to content creation and beyond.
I hope you found this series on Agentic AI Design Pattern beneficial in learning how Agents works. If you have any questions or suggestions let me know in the comments!!!
References
Ans. The four design patterns are the Reflection Pattern, Tool Use Pattern, Planning Pattern, and Multi-Agent Pattern. Each pattern provides a framework for developing AI systems that can exhibit human-like agentic behaviour.
Ans. The Agentic Multi-Agent Pattern divides complex tasks into subtasks, assigning them to different specialized agents that collaborate. Each agent focuses on a specific role (e.g., coding, project management), promoting efficiency and expertise.
Ans. The benefits include enhanced collaborative problem-solving, focused task execution, scalability, and structured workflows that mimic human team management. This leads to better performance and optimized task completion.
Ans. Frameworks like AutoGen facilitate the creation of multi-agent solutions by enabling customizable, conversation-centric interactions. They allow agents to collaborate, adapt to feedback, and automate complex task execution.
Ans. MetaGPT incorporates structured Standard Operating Procedures (SOPs) to manage complex tasks efficiently. It reduces errors and logical inconsistencies by assigning specific roles and using a verification step, resulting in coherent and reliable outputs.