{"slug": "from-chains-to-graphs-an-intro-to-langgraph", "title": "From Chains to Graphs: An Intro to LangGraph", "summary": "LangGraph is a framework for building agentic workflows and LLM applications that addresses the looping, branching, retry, routing, and state-persistence patterns LangChain struggles to handle natively. The framework treats state as a first-class concept, supports human-in-the-loop pauses that can last minutes to days, and can persist and resume execution context, as illustrated by an essay-reviewer agent that grades, revises, and escalates to a human after a maximum number of attempts.", "body_md": "LangGraph is a framework for building agentic workflows and LLM applications. Now you might argue that LangChain already lets you build AI applications and workflows, and you’re almost right.\n\nLangChain works great as long as your workflow follows a sequence: input → LLM → parser → output, maybe with a few parallel chains thrown in. But the moment your application needs to loop, branch, retry, route between paths, or hold onto state across steps, LangChain starts to struggle. You can hack together workarounds, sure, but you end up writing a lot of glue code, and as complexity grows, that glue code becomes genuinely painful to manage without native support for these patterns.\n\nThis is exactly the gap LangGraph fills.\n\nA running example\n\nTo keep things concrete, I’ll use one example for the rest of this post: an essay-reviewer agent.\n\nThe workflow: take a student’s essay, have an LLM grade it, and if the score is below a threshold, send it back for revision and keep looping until it passes or hits a max number of attempts, at which point a human reviewer steps in.\n\nTry building that in LangChain. The “loop back and revise” part is exactly the kind of thing that breaks a linear chain; there’s no clean, native way to say “go back a few steps if this condition is met.” This is a small enough example to hold in your head, but it touches every core LangGraph concept: state, branching, looping, and human-in-the-loop. I’ll keep coming back to it.\n\nLangChain vs LangGraph\n\nStructure\n\nLangChain builds linear chains — a sequence of steps with, at best, a few parallel branches that eventually merge back.\n\nLangGraph builds graphs nodes connected by edges, so loops and branches aren’t a workaround they’re the default way the system is structured. For our essay reviewer, “loop back to revise” is just an edge pointing backwards in the graph.\n\nState management\n\nLangChain has no built-in way to track evolving state across a workflow, each step mostly just passes its output to the next.\n\nLangGraph, state is a first-class concept, a single structured object (like our {essay, score, feedback, attempts}) that’s passed to every node and updated as it moves through the graph, so nothing has to be recomputed or re-fetched.\n\nExecution style\n\nLangChain runs a chain start to finish, in one direction, one time.\n\nLangGraph is event/step-driven; execution moves from node to node based on the graph’s edges and conditions, which is exactly what lets the essay reviewer keep cycling through grade_essay → revise_essay until the score clears the bar.\n\nHuman-in-the-loop\n\nLangChain has no native support for this, pausing mid-chain for a person to weigh in means building it yourself.\n\nLangGraph can pause execution indefinitely minutes, hours, even days until a human provides input, which is what lets our escalate_to_human node actually wait for a real reviewer instead of timing out or failing.\n\nPersistence\n\nLangChain has no native way to save and resume a run.\n\nLangGraph can persist execution context and resume a workflow later, exactly where it left off, so if the essay reviewer pauses for human review on a Friday, it can pick back up the following Monday with the full state (essay, score history, attempt count) still intact.\n\nIn short: LangChain is great for straightforward pipelines. LangGraph is built for workflows that need memory, control flow, human in the loop and the ability to pause and resume — which is most real agentic systems.\n\nThe Basic Building Blocks\n\nBefore writing any LangGraph code, it will help if we are comfortable with five core concepts of LangGraph -\n\nGraph: The graph is the overall structure of your application. Instead of a straight line of steps, you define your workflow as a graph, which includes a network of steps (nodes) connected by paths (edges), which naturally supports branching and looping. For the essay reviewer, the graph looks roughly like: grade → (pass → finalize) or (fail → revise → grade again), with an exit to a human after too many failed attempts.\n\nNode: A node is a single unit of work, usually a Python function. It could call an LLM, run a tool, transform data, or do anything else you’d normally put inside a step of a chain. Each node receives the current state, does its job, and returns an update to that state. Our graph would have nodes like grade_essay, revise_essay, finalize, and escalate_to_human.\n\nEdges: Edges connect nodes and define what happens next. A normal edge just says “after node A, go to node B” like revise_essay → grade_essay, always. A conditional edge is where things get interesting — based on the current state, it decides which node to go to next. After grade_essay, a conditional edge checks the score: pass → go to finalize, fail and attempts remaining → go to revise_essay, fail and out of attempts → go to escalate_to_human. This one conditional edge is what gives us branching, looping, and retry logic, all at once.\n\nState: State is the shared data structure that flows through the entire graph. Every node reads from it and writes updates back to it. For the essay reviewer, the state would carry things like the essay text, the current score, the feedback from the last review, and an attempts counter so every node knows exactly where things stand without needing to re-fetch or re-derive it. This is what LangChain fundamentally lacks: a persistent, structured way to track “what has happened so far” as your application moves through multiple steps.\n\nStateGraph: StateGraph is the actual class you use to build a LangGraph application. You define a schema for your state (usually with a TypedDict or Pydantic model for us, something like {essay: str, score: int, feedback: str, attempts: int}), then add your nodes and edges to this StateGraph object. It’s the container that ties the graph structure and the state together.\n\nLangGraph’s Execution Model\n\nAny workflow built using LangGraph follows the execution model below:\n\nGraph Definition: You define your state schema (essay, score, feedback, attempts), create your nodes (grade_essay, revise_essay, finalize, escalate_to_human), and wire them together with edges — including the conditional edge after grade_essay that checks the score and attempt count. At this point, nothing has run yet — you’re just describing the shape of the workflow.\n\nCompilation: You call .compile() on your StateGraph. This validates the graph structure — checking that every node is reachable and every conditional edge routes somewhere valid and turns your definition into a runnable object. This is also where you’d plug in a checkpointer, which is what would let the essay reviewer pause at escalate_to_human and wait for hours or days if needed until a human actually reviews it.\n\nInvocation: You call the compiled graph with an initial state typically .with invoke() and passing in the first draft of the essay with score: None and attempts: 0. This is you saying “start the workflow with this input.”\n\nExecution: The graph engine takes over: it runs grade_essay, checks the score via the conditional edge, and either moves to finalize or loops back through revise_essay → grade_essay again incrementing attempts each time until the essay passes or the attempt limit is hit, and it hands off to escalate_to_human. If a checkpointer is configured, execution can pause right there and resume later without losing any of the state built up so far.\n\nWhat’s Next\n\nIn the next post, I’ll get hands-on and build out the core workflow patterns in LangGraph, which will include sequential, parallel, conditional, and iterative graphs — with actual code for each.", "url": "https://wpnews.pro/news/from-chains-to-graphs-an-intro-to-langgraph", "canonical_source": "https://pub.towardsai.net/from-chains-to-graphs-an-intro-to-langgraph-c56638cc9e3a?source=rss----98111c9905da---4", "published_at": "2026-09-14 14:01:04+00:00", "updated_at": "2026-09-14 14:19:35.598758+00:00", "lang": "en", "topics": ["ai-agents", "large-language-models", "ai-tools", "developer-tools", "artificial-intelligence"], "entities": ["LangGraph", "LangChain"], "alternates": {"html": "https://wpnews.pro/news/from-chains-to-graphs-an-intro-to-langgraph", "markdown": "https://wpnews.pro/news/from-chains-to-graphs-an-intro-to-langgraph.md", "text": "https://wpnews.pro/news/from-chains-to-graphs-an-intro-to-langgraph.txt", "jsonld": "https://wpnews.pro/news/from-chains-to-graphs-an-intro-to-langgraph.jsonld"}}