Welcome to this LangGraph Beginner to Advance series. LangGraph has is one of the most popular frameworks for building Agentic AI applications. With Agentic AI, the application has a lot more scope and tasks to accomplish by navigating various flows and autonomously invoking various agents to fulfill a task completely. LangGraph is built within the LangChain system to act as an orchestration framework to build a multi-step flow for each task execution. Unlike a linear chain of events that you build with LangChain, with a multi-step flow, the orchestration can have logical conditions which decide which agent to invoke, it can make decisions, use various tools and maintain the state of the conversation throughout the flow. LangGraph Beginner to Advance series If you’ve ever wanted to build AI agents and design graph-based conversational workflows, this course-style blog series is for you. AI agents graph-based conversational workflows LangGraph is a powerful Python library designed for building advanced conversational AI workflows. By the end of this series, you will be equipped to create robust, scalable conversational applications that leverage the full potential of Large Language Models (LLMs). powerful Python library robust, scalable conversational applications 👋 Hey, my name is Talib and I’m an AI Engineer. In this series, we’re going to walk through LangGraph step by step — from fundamentals to coding real AI agents. fundamentals coding real AI agents Before diving into the complex stuff, let’s get started with some basic concepts: basic concepts 📌 Prerequisites Before continuing, you should have: Basic knowledge of Python Understanding of dictionaries, classes, and functions Familiarity with type annotations (optional but helpful) Basic knowledge of Python Python Understanding of dictionaries, classes, and functions dictionaries, classes, and functions Familiarity with type annotations (optional but helpful) type annotations Why Type Annotations? When we eventually start coding AI agents and graphs in LangGraph, type annotations will appear everywhere. If you’ve never worked with them before, they might look confusing. That’s why we’ll go through them first. type annotations Dictionaries in Python movie = { "name": "Avengers Endgame", "year": 2019 } movie = { "name": "Avengers Endgame", "year": 2019 } Dictionaries are powerful and flexible. But there’s a problem that they don’t enforce structure. You could mistakenly pass wrong data types, and in large projects, this creates logical errors that are painful to debug. logical errors Type Dictionaries A type dictionary enforces structure. In Python, you can define this using a class: type dictionary from typing import TypedDict from typing import TypedDict class Movie(TypedDict): name: str year: int class Movie(TypedDict): name: str year: int movie: Movie = { "name": "Avengers Endgame", "year": 2019 } movie: Movie = { "name": "Avengers Endgame", "year": 2019 } ✅ Benefits: Type safety → fewer runtime errors Readability → easier debugging Scalability → used extensively in LangGraph to define states Type safety → fewer runtime errors Type safety Readability → easier debugging Readability Scalability → used extensively in LangGraph to define states Scalability states Union The Union type lets you define multiple acceptable data types. from typing import Union from typing import Union def square(x: Union[int, float]) -> float: return x * x def square(x: Union[int, float]) -> float: return x * x ✔️ square(5) → works ✔️ square(1.23) → works ❌ square(“hello”) → fails LangChain and LangGraph both use Union extensively. Union extensively Optional The Optional type means a value can either be of a type OR None. from typing import Optional from typing import Optional def nice_message(name: Optional[str]) -> str: if name: return f"Hi there {name}" else: return "Hey random person" def nice_message(name: Optional[str]) -> str: if name: return f"Hi there {name}" else: return "Hey random person" ✅ Works with “Bob” ✅ Works with None ❌ Doesn’t allow integers or booleans ✅ Works with “Bob” ✅ Works with None ❌ Doesn’t allow integers or booleans Any The Any type allows literally anything. literally anything from typing import Any from typing import Any def print_value(x: Any): print(x) def print_value(x: Any): print(x) print_value("Hello") print_value(123) print_value([1, 2, 3]) print_value("Hello") print_value(123) print_value([1, 2, 3]) Lambda Functions Lambda functions are small, anonymous functions. small, anonymous functions Example 1: Squaring a number square = lambda x: x * x print(square(10)) # 100 square = lambda x: x * x print(square(10)) # 100 Example 2: Mapping over a list nums = [1, 2, 3, 4] squared = list(map(lambda x: x * x, nums)) print(squared) # [1, 4, 9, 16] nums = [1, 2, 3, 4] squared = list(map(lambda x: x * x, nums)) print(squared) # [1, 4, 9, 16] 💡 Advanced programmers often use lambdas + map() for efficiency instead of writing full loops. Advanced programmers These will keep showing up in LangGraph, so having a good grasp now will save you from confusion later. keep showing up Now it’s time to dive deeper into the building blocks of LangGraph: building blocks of LangGraph States (memory) Nodes (tasks) Graphs & Edges (workflow connections) Start & End points Tools & Tool Nodes State Graph (blueprint) Runnables (building blocks) Messages (communication between humans, AI, and tools) States (memory) States Nodes (tasks) Nodes Graphs & Edges (workflow connections) Graphs & Edges Start & End points Start & End points Tools & Tool Nodes Tools & Tool Nodes State Graph (blueprint) State Graph Runnables (building blocks) Runnables Messages (communication between humans, AI, and tools) Messages To make this easier to follow, let’s understand with a factory assembly line analogy. factory assembly line analogy Think of LangGraph as a smart automated factory where: smart automated factory The state = the shared whiteboard of the factory (tracking progress) The nodes = workstations (each does one specific job) The edges = conveyor belts between stations (deciding flow) The tools = machines used at workstations The tool nodes = operators controlling the machines The graph = blueprint of the entire factory The runnables = modular Lego-like parts for assembling workflows The messages = conversations between workers, machines, and managers The state = the shared whiteboard of the factory (tracking progress) state The nodes = workstations (each does one specific job) nodes The edges = conveyor belts between stations (deciding flow) edges The tools = machines used at workstations tools The tool nodes = operators controlling the machines tool nodes The graph = blueprint of the entire factory graph The runnables = modular Lego-like parts for assembling workflows runnables The messages = conversations between workers, machines, and managers messages Let’s break this down step by step. State — The Factory’s Memory A state is a shared data structure that holds the current information of your application. state shared data structure Imagine a whiteboard at the entrance of a factory. Every time something is updated — like materials arriving, work being done, or outputs ready — it’s recorded here. whiteboard at the entrance of a factory This ensures every worker (node) knows the latest status. latest status from typing import TypedDict from typing import TypedDict class FactoryState(TypedDict): item: str progress: str class FactoryState(TypedDict): item: str progress: str Here, FactoryState defines what information our factory tracks: the item being worked on, and its progress. Nodes — The Workstations Nodes are individual functions that perform one specific job. individual functions one specific job In a car factory, one station might install the wheels, another paints the body, and another inspects quality. Each station = a node. a node def paint_node(state: FactoryState) -> FactoryState: state["progress"] = f"Painting {state['item']}" return state def paint_node(state: FactoryState) -> FactoryState: state["progress"] = f"Painting {state['item']}" return state Each node: Takes the current state as input Does its job (e.g., painting) Updates the state Returns the updated state Takes the current state as input current state Does its job (e.g., painting) Updates the state state Returns the updated state Graph — The Blueprint of the Factory A graph is the overarching structure — the blueprint of the workflow. graph blueprint of the workflow Just like an architect draws a factory floor plan, a graph maps out which workstation (node) connects to which, and in what sequence. factory floor plan from langgraph.graph import StateGraph from langgraph.graph import StateGraph graph = StateGraph(FactoryState) graph = StateGraph(FactoryState) This creates a workflow blueprint for how tasks will flow through the factory. workflow blueprint Edges — The Conveyor Belts Edges are the connections between nodes. They define the flow of execution. connections between nodes flow of execution Conveyor belts carry car parts from one workstation to another. Without belts, workers would be isolated. graph.add_edge("painting", "inspection") graph.add_edge("painting", "inspection") This means once painting is done, the item automatically moves to inspection. Conditional Edges Some conveyor belts have switches that decide where an item should go. Think of a railway track switch. Depending on the condition, a car may go left (to polishing) or right (to repairs). switches railway track switch if state["progress"] == "damaged": next_node = "repair" else: next_node = "finish" if state["progress"] == "damaged": next_node = "repair" else: next_node = "finish" This is like a traffic light deciding the next move. traffic light Start and End Points Start Point = the factory entrance (where raw materials arrive) End Point = the exit gate (finished product shipped out) Start Point = the factory entrance (where raw materials arrive) Start Point factory entrance End Point = the exit gate (finished product shipped out) End Point exit gate graph.set_entry_point("painting") graph.set_finish_point("inspection") graph.set_entry_point("painting") graph.set_finish_point("inspection") The start point doesn’t do any work itself — it just marks where execution begins. where execution begins Tools — The Machines Tools are specialised utilities that nodes can use. A workstation worker might use a drill, paint gun, or screwdriver to complete their task. These are tools. specialised utilities drill paint gun screwdriver tools For example: A fetch_data tool → gets information from an API A calculator tool → performs math operations A fetch_data tool → gets information from an API fetch_data tool A calculator tool → performs math operations calculator tool Tool Nodes — The Operators A tool node is a node whose only job is to run a tool. The operator at the paint station doesn’t paint by hand — they just control the painting machine. tool node only job control the painting machine def api_tool_node(state: FactoryState) -> FactoryState: data = fetch_from_api() state["progress"] = f"Fetched data: {data}" return state def api_tool_node(state: FactoryState) -> FactoryState: data = fetch_from_api() state["progress"] = f"Fetched data: {data}" return state The operator (tool node) runs the machine (tool), then updates the whiteboard (state). State Graph — The Factory’s Master Blueprint The state graph manages all: state graph Nodes (workstations) Edges (conveyor belts) State (the whiteboard) Nodes (workstations) Edges (conveyor belts) State (the whiteboard) Think of it as the master blueprint of a skyscraper. It doesn’t do the work but defines structure and flow. master blueprint defines structure and flow graph = StateGraph(FactoryState) graph.add_node("paint", paint_node) graph.add_node("inspect", inspection_node) graph = StateGraph(FactoryState) graph.add_node("paint", paint_node) graph.add_node("inspect", inspection_node) Runnables — Lego Blocks Runnables are modular, standardised components. Think of Lego bricks. Each brick is small, but they can be snapped together to build castles, cars, or spaceships. Similarly, runnables let you assemble sophisticated AI workflows. modular, standardised components Lego bricks sophisticated AI workflows Messages — The Conversations Messages are how humans, AI, and tools communicate in LangGraph. In our factory, workers shout instructions, machines beep when done, and managers give guidelines. These are messages. humans, AI, and tools communicate messages Types of messages: Human Message → input from the user (e.g., “Build a red car”) AI Message → response from the AI (e.g., “Okay, painting car red”) System Message → manager’s instruction (e.g., “Always ensure safety first”) Tool Message → output from a tool (e.g., “Wheels attached”) Function Message → result of a function call Human Message → input from the user (e.g., “Build a red car”) Human Message AI Message → response from the AI (e.g., “Okay, painting car red”) AI Message System Message → manager’s instruction (e.g., “Always ensure safety first”) System Message Tool Message → output from a tool (e.g., “Wheels attached”) Tool Message Function Message → result of a function call Function Message Example: from langchain.schema import HumanMessage, AIMessage, SystemMessage from langchain.schema import HumanMessage, AIMessage, SystemMessage conversation = [ SystemMessage(content="You are a helpful assistant."), HumanMessage(content="Build me a chatbot"), AIMessage(content="Sure, I’ll design the workflow.") ] conversation = [ SystemMessage(content="You are a helpful assistant."), HumanMessage(content="Build me a chatbot"), AIMessage(content="Sure, I’ll design the workflow.") ] Summary of Core Elements State → Whiteboard (memory of the app) Node → Workstation (specific task) Graph → Blueprint (overall structure) Edge → Conveyor belt (flow of execution) Conditional Edge → Railway switch (if/else flow) Start/End → Factory entrance and exit Tool → Machine at the workstation Tool Node → Operator who runs the machine State Graph → Master blueprint of factory workflow Runnable → Lego brick (modular execution unit) Messages → Communication between human, AI, and tools\ State → Whiteboard (memory of the app) State Node → Workstation (specific task) Node Graph → Blueprint (overall structure) Graph Edge → Conveyor belt (flow of execution) Edge Conditional Edge → Railway switch (if/else flow) Conditional Edge Start/End → Factory entrance and exit Start/End Tool → Machine at the workstation Tool Tool Node → Operator who runs the machine Tool Node State Graph → Master blueprint of factory workflow State Graph Runnable → Lego brick (modular execution unit) Runnable Messages → Communication between human, AI, and tools\ Messages Now that you understand the core elements of LangGraph, you’re ready to move from theory to practice. core elements of LangGraph With these concepts mastered, you are now ready to build actual AI workflows. build actual AI workflows Catch the whole LangGraph Series here: LangGraph Reading List LangGraph Reading List Thank you for reading!