Welcome to the final lesson of the Agentic Patterns series! By now, you’re already familiar with the Reflection Agent, Tools, and the ReAct Technique. But I know you’re probably curious about frameworks like CrewAI, AutoGen, or OpenAI Swarm - those nice tools for building multiagent applications.
These frameworks are just different takes on the Multiagent Pattern, where tasks are broken into smaller subtasks and handled by agents with specific roles - like a software engineer, a project manager, etc.
In this lesson, we’re taking it to the next level by building a minimalistic multiagent framework from the ground up.
Sounds fun? Let’s get started! 🚀
This is the fourth lesson of the Agentic Patterns from Scratch course. This lesson builds on the theory and code covered in the previous ones, so be sure to check them out if you haven’t already!
A Minimalistic Multiagent Framework
The framework we’re about to develop is inspired by two fundamental concepts from CrewAI: the Crew and the Agent.
In CrewAI, a Crew represents a collaborative group of agents working in unison to accomplish a set of tasks. An Agent, on the other hand, represents the autonomous unit responsible for executing specific tasks.
I’ve also drawn inspiration from Apache Airflow’s design philosophy, particularly the use of the >> and << operators to establish dependencies between agents. In this micro-CrewAI framework, agents are anologous to Airflow Tasks, while the Crew corresponds to an Airflow DAG.
Let’s begin with the Agent class 👇
The Agent Class
First of all, we need an Agent Class. This class will represent an Agent, incorporating the ReAct technique internally (check Lesson 3 if you want to see this technique in detail!). To view the complete implementation, feel free to check out the repository.
Let’s create an example agent to demonstrate how it works.
You can also equip the agent with tools, like we did in Lesson 2. As a simple example, let’s build a tool that writes text into a CSV file.
As you can imagine, running this Tool Agent will create a new file named tool_agent_example.txt in the current directory, which will contain the text "“This is a Tool Agent”.
Now that we know how the Agent class works, let’s see how to define Agent dependencies.
Defining Agent Dependencies
Suppose we want to define two agents, where the second agent depends on the first agent.
We can define the agent dependencies using the >> operator.
agent_1 >> agent_2
This means agent_2 depends on agent_1. We can check the dependencies and dependents of both agents.
Now, if we run agent_1, the results will be added to agent_2's context. Then, when we run agent_2, it will use the context received from agent_1 to generate its output.
The Crew
Having defined the Agents and their dependencies, the only missing piece is the Crew, that is, the session object that will enable us to orchestrate the Agents. To view the complete implementation, feel free to check out the repository.
Our Crew will take care of running the Agents in the correct order, applying an algorithm called Topological Sorting. It also provides a way to visualize the graph of dependencies, as we’ll see below.
Let’s see the Crew in action.
If we want to see the dependency graph, we can simple run crew.plot(). This command will generate a diagram like the following.
After that, we just need to run the crew and wait for th results!
crew.run()
You should see an output like the following, where the Poet Agent will generate a poem about life, the Poem Translator Agent will translate the poem into Spanish (yes, I’m from Spain 😛) and finally, the Writer Agent will write the translated poem into a poem.txt file!
And that’s it! We actually got a multiagent framework up and running! I’d say this definitely calls for a meme … 🤣
If you prefer video lectures, I also have a YouTube video covering the Multiagent Pattern! 👇
Merry Christmas! 🎅
Thanks! Now I have something to do during the Holidays 😁
Can you also do this with LlamaIndex?