Let's build an AI Agent with LangGraph

February 09, 2025

In this blog, we delve into the exciting world of multi-agent workflows using LangGraph, a powerful library designed for constructing dynamic agent-like workflows as graphs. We will explore three distinct examples of these workflows, demonstrating how agents can collaborate, operate independently, or function within hierarchical teams.

Introduction to LangGraph

LangGraph is a transformative library that facilitates the creation of dynamic workflows resembling agent-like structures. At its core, LangGraph enables users to define workflows as graphs, where nodes represent agents and edges illustrate their interactions. This approach not only enhances the modularity of workflows but also allows for intricate cycles and states, akin to state machines. The versatility of LangGraph makes it an invaluable tool for developers looking to implement sophisticated multi-agent systems.

Key Features of LangGraph

  • Dynamic Graph Structures: Create and modify workflows on-the-fly, adapting to changing requirements.
  • Agent Representation: Each node can represent a distinct agent, enabling independent or collaborative operations.
  • State Management: Track and manage the state of each agent effectively, ensuring smooth transitions and interactions.
  • Tool Integration: Seamlessly integrate various tools and functions into agent workflows, enhancing their capabilities.

Understanding Agent-like Workflows

Agent-like workflows leverage the capabilities of language models to perform tasks iteratively, often in a loop. This dynamic interaction allows agents to communicate, share states, and collaborate towards a common goal. The structure of these workflows can vary significantly, depending on the desired outcome and the nature of the tasks being performed.

Types of Workflows

  • Collaborative Workflows: Multiple agents work on the same set of messages, sharing state and information.
  • Independent Workflows: Agents operate autonomously, each with its own context, only sharing final outcomes.
  • Hierarchical Workflows: Agents are structured in a hierarchy, allowing for complex task management and delegation.

Defining Multi-Agent Collaboration

In multi-agent collaboration, agents actively share their state and messages, leading to a more cohesive workflow. This approach allows agents to build upon each other's inputs, resulting in enriched outcomes. The collaboration can either be direct, where agents communicate frequently, or indirect, where they share a common state but operate semi-independently.

Example of Multi-Agent Collaboration

Consider an example where two agents—a researcher and a chart generator—work together. The researcher collects data and may call tools for additional information, while the chart generator visualises the data. This collaboration can be structured as follows:

def create_agent(agent_name, llm, tools, system_message):
    # Define an agent with specified parameters
    return Agent(agent_name, llm, tools, system_message)

researcher = create_agent("Researcher", llm_instance, [search_tool], "You are a data researcher.")
chart_generator = create_agent("Chart Generator", llm_instance, [chart_tool], "You are a chart visualizer.")

Setting Up the Environment

Before diving into the implementation of our multi-agent workflow, it is essential to set up the environment properly. This includes installing necessary libraries, configuring tools, and ensuring that all components are accessible.

Installation of Required Libraries

To get started with LangGraph, ensure you have the following libraries installed:

pip install langgraph langchain

Configuring Tools

Next, we need to define the tools that our agents will utilize. For instance:

search_tool = Tool(name="Search", function=search_function)
chart_tool = Tool(name="Chart", function=chart_function)

Creating Agent Nodes

With the environment set up and tools ready, we can start creating agent nodes. These nodes will encapsulate the behaviour and capabilities of each agent in our workflow.

Defining Agent Nodes

Each agent node can be created using a helper function that sets up the parameters and state management:

def create_agent_node(agent, state):
    # Create an agent node and manage its state
    return AgentNode(agent, state)

researcher_node = create_agent_node(researcher, initial_state)
chart_node = create_agent_node(chart_generator, initial_state)

Implementing Tool Nodes

Tool nodes are crucial for executing specific tasks within the workflow. They act as intermediaries that trigger external functions or tools based on the agents' requests.

Defining Tool Logic

Below is an example of how to implement a tool node that executes a function and updates the workflow state accordingly:

def tool_node(tool, input_data):
    result = tool.execute(input_data)
    update_state(result)
    return result

Routing Logic and Conditional Edges

Routing logic determines how messages and requests flow between agent nodes. Conditional edges define the pathways based on specific criteria, enabling dynamic decision-making.

Implementing Conditional Routing

To implement routing logic, we can define conditions that check the last message from an agent and direct the flow accordingly:

def routing_logic(last_message):
    if "function call" in last_message:
        return "call_tool"
    elif "final answer" in last_message:
        return "end"
    else:
        return "continue"

By structuring the workflow in this manner, agents can effectively manage their interactions, leading to a smooth and efficient collaborative experience.

Invoking the Multi-Agent Collaboration

To invoke the multi-agent collaboration, we first need to set up our agents and their respective tools. The collaboration involves multiple agents working on a shared state of messages, allowing them to build on each other's progress.

Creating the Agents

We will create two agents: a researcher and a chart generator. Each agent will have access to specific tools to perform their tasks effectively.

researcher = create_agent("Researcher", llm_instance, [search_tool], "You are a data researcher.")
chart_generator = create_agent("Chart Generator", llm_instance, [chart_tool], "You are a chart visualizer.")

Defining the Collaboration Workflow

Next, we need to define the workflow that dictates how these agents interact. The workflow will include conditions for tool calls and the final responses.

def collaboration_workflow():
    messages = []
    current_agent = researcher

    while True:
        response = current_agent(messages)
        messages.append(response)

        if "final answer" in response:
            break
        elif "call function" in response:
            tool_node(response)
        else:
            current_agent = chart_generator

Exploring the Multi-Agent Supervisor

The multi-agent supervisor is responsible for coordinating independent agents, each of which operates autonomously. This structure allows each agent to handle its tasks and return only the final outcome to the supervisor.

Setting Up the Supervisor

We will define a supervisor agent that manages the interactions between the independent agents, ensuring that they complete their tasks without interference.

supervisor = create_agent("Supervisor", llm_instance, [], "You are the supervisor managing independent agents.")

Defining Independent Agent Workflows

Each independent agent will have its own workflow, and the supervisor will route tasks based on the responses received. This allows for greater flexibility and autonomy.

def independent_workflow(agent):
    result = agent.process()
    return result

Connecting the Supervisor to Agents

We will now connect the supervisor to the independent agents, allowing it to make decisions based on their outputs.

def supervisor_logic():
    response = supervisor.call()
    if response == "call researcher":
        return independent_workflow(researcher)
    elif response == "call coder":
        return independent_workflow(coder)
    else:
        return "Task completed!"

Creating Independent Agent Workflows

Independent agent workflows allow agents to operate in isolation, returning only their final results to the supervisor. This structure promotes efficiency and clarity in task execution.

Defining the Independent Agent Logic

We will define the logic for each independent agent, specifying how they process their tasks and return results.

def researcher_logic():
    # Researcher logic to gather data and return results
    data = search_tool.execute()
    return f"Research completed with data: {data}"

def coder_logic():
    # Coder logic to process data and generate outputs
    output = python_tool.execute("print('Hello World')")
    return f"Coding task completed: {output}"

Routing Between Agents

The supervisor will route tasks to the appropriate agent based on the current requirements. The routing logic ensures efficient task management.

def route_task(task):
    if task == "research":
        return researcher_logic()
    elif task == "code":
        return coder_logic()
    else:
        return "Unknown task!"

Understanding the Hierarchical Agent Team

The hierarchical agent team structure allows for complex task management by organizing agents into sub-teams, each with specific responsibilities. This model enhances collaboration and efficiency.

Defining the Hierarchical Structure

We will create a hierarchy where each team member has a distinct role, contributing to a common goal.

class HierarchicalTeam:
    def __init__(self):
        self.research_team = ResearchTeam()
        self.writing_team = WritingTeam()
    
    def execute(self, task):
        if task in self.research_team.tasks:
            return self.research_team.perform_task(task)
        elif task in self.writing_team.tasks:
            return self.writing_team.perform_task(task)
        else:
            return "Task not recognized!"

Creating Team Members

Each team member will be an agent with specific roles, and we will define their tasks accordingly.

class ResearchTeam:
    def __init__(self):
        self.tasks = ["search", "analyze"]
    
    def perform_task(self, task):
        if task == "search":
            return researcher_logic()
        elif task == "analyze":
            return "Analysis completed!"
        else:
            return "Unknown research task!"

class WritingTeam:
    def __init__(self):
        self.tasks = ["write", "edit"]
    
    def perform_task(self, task):
        if task == "write":
            return "Writing completed!"
        elif task == "edit":
            return "Editing completed!"
        else:
            return "Unknown writing task!"

Building the Document Authoring Team

The document authoring team will focus on creating content based on research data. This team will consist of agents responsible for writing, editing, and formatting documents.

Setting Up the Authoring Agents

We will define agents that specialize in different aspects of document creation, ensuring a smooth workflow.

document_writer = create_agent("Document Writer", llm_instance, [writing_tool], "You are a document writer.")
editor = create_agent("Editor", llm_instance, [editing_tool], "You are an editor.")

Defining the Authoring Workflow

The authoring workflow will manage the interactions between the writing and editing agents, ensuring that documents are created and refined efficiently.

def document_workflow():
    writing_result = document_writer.call()
    editing_result = editor.call(writing_result)
    return editing_result

Final Thoughts on Multi-Agent Workflows

Multi-agent workflows offer a powerful framework for organizing complex tasks into manageable components. By leveraging independent and collaborative agents, we can streamline processes and enhance productivity.

As we explored various models—from collaborative teams to hierarchical structures—we saw how each approach serves unique needs. The flexibility of LangGraph allows developers to tailor workflows to their specific requirements, maximizing efficiency and clarity.

Moving forward, embracing a multi-agent perspective can significantly improve how we tackle intricate projects, ensuring that each agent operates within its strengths while contributing to a unified goal.

Follow my journey

Get my latest thoughts, posts and project updates in your inbox. No spam, I promise.