When designing workflows or AI pipelines, sometimes we need to loop through certain steps multiple times before reaching an endpoint. Cycles and conditional edges in LangGraph
allow us to control the flow of execution dynamically.
In this article, we’ll explore how to implement looping behavior and conditional branching using LangGraph
. We'll modify the graph dynamically based on conditions to create an adaptive workflow.
Understanding Cycles and Conditional Edges
🔁 Cycles in a Graph
A cycle occurs when a node can lead back to a previous node, creating a loop. This allows repeated execution of a process until a condition is met.
🛤 Conditional Edges
Unlike standard edges, conditional edges allow dynamic routing based on input values. Instead of following a fixed path, a function determines the next node based on the current state.
Implementing Cycles and Conditional Transitions
Let’s define a state structure using TypedDict
:
from typing import TypedDict
from langgraph.graph import END, StateGraph
class InputState(TypedDict):
string_value: str
numeric_value: int
This state includes:
-
string_value
: A string that gets modified each cycle. -
numeric_value
: An integer that determines when to exit the loop.
Defining the State Modifier Node
Each time a node is visited, it updates the state:
def modify_state(input: InputState):
input["string_value"] += "a" # Append "a" to the string
input["numeric_value"] += 1 # Increment the number
return input
This function modifies the input every time it is executed.
Adding Conditional Routing
We define a router function to decide whether to continue looping or end execution:
def router(input: InputState):
if input["numeric_value"] < 5: # If the number is less than 5, loop back
return "branch_a"
else: # Otherwise, exit the graph
return "__end__"
Building the Graph with Cycles
Now, let’s construct the state graph:
graph = StateGraph(InputState)
# Define nodes
graph.add_node("branch_a", modify_state)
graph.add_node("branch_b", modify_state)
# Define edges
graph.add_edge("branch_a", "branch_b") # A → B
# Conditional routing from B
graph.add_conditional_edges(
"branch_b", router, {"branch_a": "branch_a", "__end__": END}
)
graph.set_entry_point("branch_a") # Start from A
runnable = graph.compile()
How the Graph Works
-
Execution starts at
branch_a
. -
State is modified, and control moves to
branch_b
. -
The router function checks
numeric_value
:- If less than 5, execution loops back to
branch_a
. - If 5 or more, execution ends.
- If less than 5, execution loops back to
Visualizing the Graph
To understand the structure, we can visualize it using Mermaid diagrams:
from IPython.display import Image, display
from langchain_core.runnables.graph import MermaidDrawMethod
display(
Image(
runnable.get_graph().draw_mermaid_png(
draw_method=MermaidDrawMethod.API,
)
)
)
This will generate a flowchart showing the looping behavior.
Why Use Cycles and Conditional Edges?
✅ Efficient looping without manually repeating code.
✅ Dynamic decision-making based on input conditions.
✅ Adaptive workflows for AI pipelines and automation.
✅ Prevents infinite loops by setting clear exit conditions.
Conclusion
In this tutorial, we explored how cycles and conditional edges enable dynamic workflow control. This is particularly useful for iterative tasks like data processing, AI feedback loops, and task automation.
Next steps? Try modifying the loop condition or adding more decision points to see how the graph behavior changes! 🚀
Top comments (0)