Hello readers! In this blog post, I’ll walk you through completing and running a basic project using LangGraph, a library for building stateful workflows (often used in AI applications like agents or chatbots). The code provided creates a simple graph with nodes that update a state (a message string) and includes random routing for dynamic behavior. This can simulate real-time decision-making, like routing tasks in a system.
We’ll treat this as a “real-time” project by adding execution logic that runs the graph multiple times, showing variability due to randomness—mimicking dynamic, live systems. I’ll guide you step by step, including installation, setup in a Jupyter Notebook, explanations, and enhancements. By the end, you’ll have a fully executable notebook you can share or expand.
This is based on Python 3.x, and we’ll use Jupyter Notebook for interactive visualization and execution. Let’s dive in!
Step 1: Understand the Project
- What it does: The code defines a stateful graph:
- State: A dictionary with graph_msg (a string that gets appended as the graph runs).
- Nodes: Three functions (node_01, node_02, node_03) that print the current state and update graph_msg.
- Routing: After node_01, it randomly chooses node_02 or node_03.
- Visualization: Uses Mermaid to draw the graph as an image.
- Why “real-time”?: The random selection makes each run different, like real-time routing in apps (e.g., A/B testing or load balancing). We’ll add timestamps and multiple runs to emphasize this.
- Goal: Complete the code by adding invocation (running the graph), make it runnable in Jupyter, and add explanations.
Step 2: Installation and Setup
To run this, you need Python and Jupyter Notebook. Install via Anaconda (recommended for beginners) or pip.
2.1: Install Jupyter Notebook
- If you don’t have it:text
pip install notebook - Launch Jupyter: Run jupyter notebook in your terminal. This opens a browser interface where you can create a new notebook (e.g., langgraph_project.ipynb).
2.2: Install Required Libraries
The code uses langgraph, langsmith (for tracing, optional here), langchain_anthropic (not used, so optional), random (built-in), and IPython (for display in notebooks).
In your Jupyter Notebook, add this as the first cell and run it:
%%capture –no-stderr
%pip install -U langgraph langsmith langchain_anthropic
- Explanation:
- %%capture –no-stderr: Hides installation output (clean for blogs).
- %pip install: Installs/updates packages inside the notebook.
- If you get errors, restart the kernel (Kernel > Restart in Jupyter menu).
- No internet? These are standard PyPI packages; ensure your environment has access.
Note: langsmith requires an API key for full tracing (sign up at langsmith.com), but we won’t use it here. Set os.environ[“LANGCHAIN_TRACING_V2”] = “true” and your key if you want tracing.
Step 3: Import Libraries and Define the State/Nodes
In your notebook, add a new cell below the installation:
python
from typing import TypedDict
import random
from typing import Literal
from langgraph.graph import StateGraph, END, START
from IPython.display import display, Image
from datetime import datetime # We'll add this for real-time timestamps
Then, define the state and nodes (copy from the provided code, with minor enhancements for timestamps):
python
class State(TypedDict):
graph_msg: str
def node_01(state: State):
timestamp = datetime.now().isoformat()
print(f"[{timestamp}] Node 01: {state['graph_msg']}")
return {"graph_msg": state['graph_msg'] + " node_01"}
def node_02(state: State):
timestamp = datetime.now().isoformat()
print(f"[{timestamp}] Node 02: {state['graph_msg']}")
return {"graph_msg": state['graph_msg'] + " node_02"}
def node_03(state: State):
timestamp = datetime.now().isoformat()
print(f"[{timestamp}] Node 03: {state['graph_msg']}")
return {"graph_msg": state['graph_msg'] + " node_03"}
- Enhancement: Added timestamps to make it feel “real-time” (shows when each node runs).
Next cell: Define the conditional router:
python
def select_next_node(state: State) -> Literal["node_02", "node_03"]:
next_node = random.choice(["node_02", "node_03"])
timestamp = datetime.now().isoformat()
print(f"[{timestamp}] Selected node: {next_node}")
return next_node
Step 4: Build and Compile the Graph
In the next cell:
python
# Create builder
builder = StateGraph(State)
# Add nodes
builder.add_node("node_01", node_01)
builder.add_node("node_02", node_02)
builder.add_node("node_03", node_03)
# Add edges
builder.add_edge(START, "node_01")
builder.add_conditional_edges("node_01", select_next_node)
builder.add_edge("node_02", END)
builder.add_edge("node_03", END)
# Compile the graph
graph = builder.compile()
- How it works:
- StateGraph: Manages the state across nodes.
- Edges: Define flow—starts at node_01, then branches randomly, then ends.
- Conditional edges: Use a function to decide the next node dynamically.
Step 5: Visualize the Graph
Add this cell to display the graph inline (great for notebooks/blogs):
python
# Display the graph visualization
display(Image(graph.get_graph().draw_mermaid_png()))
- Output: You’ll see a flowchart image: START → node_01 → (branch to node_02 or node_03) → END.
- Tip for Blog: Screenshot this output and embed it in your post with a caption like “Graph Visualization”.
To save it as a file (for sharing):
python
# Save visualization to file
graph.get_graph().draw_mermaid_png(output_file_path="graph_visualization.png")
print("Graph saved as 'graph_visualization.png'")
Step 6: Run the Graph (Complete the Project)
The original code builds but doesn’t run the graph. Add this to invoke it multiple times, demonstrating real-time randomness:
python
# Function to run the graph multiple times
def run_graph(num_runs=5, initial_msg="start"):
for i in range(num_runs):
print(f"\n--- Run {i+1} ---")
initial_state = {"graph_msg": initial_msg}
result = graph.invoke(initial_state)
print(f"Final state: {result['graph_msg']}")
# Run it!
run_graph(num_runs=3, initial_msg="Initial message: ")
- How it works:
- graph.invoke(state): Executes the graph with the given initial state.
- Runs multiple times: Shows different paths due to random.choice (e.g., sometimes ends with “node_02”, sometimes “node_03”).
- Timestamps: Highlight real-time execution.
- Sample Output (varies each time):text
--- Run 1 --- [2025-11-10T16:00:00.123456] Node 01: Initial message: [2025-11-10T16:00:00.123456] Selected node: node_02 [2025-11-10T16:00:00.123456] Node 02: Initial message: node_01 Final state: Initial message: node_01 node_02 --- Run 2 --- ... (might go to node_03 this time) - Real-time Feel: Each run is quick, but in a production app, this could integrate with live data (e.g., user input deciding the route instead of random).
Step 7: Test and Debug in Jupyter
- Run cells one by one (Shift+Enter).
- If errors: Check imports, restart kernel if packages were just installed.
- Experiment: Change initial_msg or add more nodes (e.g., builder.add_node(“node_04”, …)).
- For blogging: Use Markdown cells in Jupyter to add explanations between code cells. Export as HTML/PDF via File > Download as.
Step 8: Enhancements for a Full Project
- Add User Input: Make it interactive:python
initial_msg = input("Enter initial message: ") run_graph(num_runs=1, initial_msg=initial_msg) - Integrate Tracing: Add import os; os.environ[“LANGCHAIN_TRACING_V2”] = “true”; os.environ[“LANGSMITH_API_KEY”] = “your_key”. Then view runs on LangSmith.
