<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Damilola Oyedunmade</title>
    <description>The latest articles on Forem by Damilola Oyedunmade (@damilola_oyedunmade).</description>
    <link>https://forem.com/damilola_oyedunmade</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2737133%2Fd050019b-9f65-4fa7-a3aa-d43a422ad5d0.png</url>
      <title>Forem: Damilola Oyedunmade</title>
      <link>https://forem.com/damilola_oyedunmade</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/damilola_oyedunmade"/>
    <language>en</language>
    <item>
      <title>A Beginner’s Guide to Handling Errors in LangGraph with Retry Policies</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Mon, 29 Dec 2025 09:36:38 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-handling-errors-in-langgraph-with-retry-policies-h22</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-handling-errors-in-langgraph-with-retry-policies-h22</guid>
      <description>&lt;p&gt;When you start building real applications with LangGraph, things will break. APIs time out. Tools fail. Models return unexpected outputs. Network calls behave unpredictably. This is not a sign that you built something wrong. It is the reality of production systems.&lt;/p&gt;

&lt;p&gt;The real problem is not that errors happen. It is what happens &lt;em&gt;after&lt;/em&gt; they do.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;br&gt;
Learn LangChain in a clear, concise, and practical way.&lt;br&gt;
Whether you’re just starting out or already building, LangCasts offers guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at &lt;a href="http://langcasts.com/" rel="noopener noreferrer"&gt;Langcasts.com&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without proper error handling, a single failed node can halt your entire graph, disrupt user experience, and leave you with little insight into what went wrong. In production environments, this is unacceptable. Your graph needs to be resilient, predictable, and capable of recovering from temporary failures on its own.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;LangGraph’s Retry Policies&lt;/strong&gt; come in. Instead of manually wrapping nodes in try–except blocks or rebuilding failed flows, LangGraph provides a structured, graph-native way to retry failed operations intelligently. You decide how many times a node should retry, how long it should wait, and when it should finally give up.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore how LangGraph treats errors at the graph level, how retry policies work, and how to use them to build systems that recover gracefully without complicating your code.&lt;/p&gt;

&lt;p&gt;By the end, you’ll understand how to let your graph handle failure intentionally, so your agents feel reliable instead of fragile.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How LangGraph Thinks About Errors&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In LangGraph, every node is an execution unit. A node receives state, performs work, and returns an update to that state. From the graph’s perspective, this is just another step in execution. There is no distinction between “safe” nodes and “risky” ones. Everything runs under the same model.&lt;/p&gt;

&lt;p&gt;By default, when a node fails, the graph stops. The error surfaces immediately, and execution halts. This behaviour is intentional. LangGraph does not guess how you want failures handled. It does not silently retry, skip steps, or recover on your behalf.&lt;/p&gt;

&lt;p&gt;This design makes failures explicit. Instead of patching errors later with scattered try–except blocks, LangGraph treats failure as a first-class part of the graph lifecycle. Nodes can fail for many valid reasons. A tool might time out. An API might return malformed data. A model might produce unexpected output. These are not edge cases. They are expected realities.&lt;/p&gt;

&lt;p&gt;Retry policies exist because LangGraph assumes that some failures are temporary and recoverable. Rather than hiding errors or reacting unpredictably, LangGraph gives you structured control over how the graph should respond. That mindset is what makes retry policies powerful and safe, not magical or dangerous.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding Retry Policies in LangGraph&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A retry policy defines how LangGraph should respond when a node fails. Instead of ending execution immediately, the policy tells the graph whether the node should try again and when to stop.&lt;/p&gt;

&lt;p&gt;At a high level, a retry policy controls how many retry attempts are allowed, under what conditions retries should occur, and when failure should be treated as final. This turns failure from a dead end into a managed process.&lt;/p&gt;

&lt;p&gt;Some failures are temporary. A network request might fail due to a timeout or a brief service outage. Retrying the same operation after a short delay often resolves the issue. Other failures, such as invalid input or logic errors, should not be retried endlessly. Retry policies help you draw that line clearly.&lt;/p&gt;

&lt;p&gt;What makes retry policies especially powerful in LangGraph is that they are part of the graph itself. Retry behaviour is not hidden inside node code or wrapped in custom logic. The graph understands that a node may fail, that retries may occur, and that there is a defined stopping point. This keeps execution predictable, debuggable, and intentional.&lt;/p&gt;

&lt;p&gt;In short, retry policies give your graph patience without sacrificing control.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adding a Retry Policy to a Node&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Retry policies are attached directly to nodes, which makes sense because nodes are the execution units of your graph. Reliability concerns stay close to where work happens, while node logic remains clean.&lt;/p&gt;

&lt;p&gt;Here’s a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;graphimport&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pregelimport&lt;/span&gt; &lt;span class="n"&gt;RetryPolicy&lt;/span&gt;

&lt;span class="nf"&gt;deffetch_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;retry_policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RetryPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fetch_data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fetch_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;retry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;retry_policy&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In plain English, this says:&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;fetch_data&lt;/code&gt; fails, LangGraph will retry it up to three times before giving up.&lt;/p&gt;

&lt;p&gt;There are no loops, no try–except blocks, and no manual counters. The retry behaviour lives in the graph configuration, not inside your node. This separation keeps your logic focused and your system easier to reason about as it grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A Simple Example: Retrying a Failing Tool Call&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine a node that calls an external API. Sometimes the API works. Sometimes it fails due to network issues, timeouts, or rate limits. You don’t want your entire graph to collapse because of a temporary hiccup.&lt;/p&gt;

&lt;p&gt;Here’s what that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;graphimport&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pregelimport&lt;/span&gt; &lt;span class="n"&gt;RetryPolicy&lt;/span&gt;

&lt;span class="nf"&gt;deffetch_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;unstable_api_call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;retry_policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RetryPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fetch_data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fetch_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;retry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;retry_policy&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the API fails, LangGraph retries the node automatically. If it succeeds on a later attempt, the graph continues normally. Your node does not change. Your flow remains clean.&lt;/p&gt;

&lt;p&gt;This is exactly how retries should work in agent systems. Invisible when things go right. Graceful when things go wrong.&lt;br&gt;


  &lt;iframe src="https://www.youtube.com/embed/m3edGzRlR5Y"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Happens When Retries Are Exhausted&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Retries do not continue forever. When a node exceeds its retry policy, LangGraph stops retrying and treats the failure as final.&lt;/p&gt;

&lt;p&gt;What happens next depends on your graph design. If there is no alternate path, execution halts, and the error is surfaced clearly. Nothing fails silently, and you are not left guessing what happened.&lt;/p&gt;

&lt;p&gt;If your graph includes fallback nodes, conditional routing, or recovery logic, execution can continue gracefully. You might return a helpful message to the user, route to a recovery node, or record an error state for inspection. The key idea is that failure is explicit and controlled.&lt;/p&gt;

&lt;p&gt;LangGraph does not encourage pretending failures will not happen. Instead, it gives you the tools to decide what should happen when they do.&lt;/p&gt;




&lt;p&gt;Errors are inevitable in real-world AI systems. Networks fail. Tools time out. APIs behave unpredictably. What matters is not avoiding failure, but handling it intentionally.&lt;/p&gt;

&lt;p&gt;LangGraph’s retry policies make reliability a first-class concern. Instead of crashing your graph or scattering error-handling logic everywhere, retries become part of the graph itself. Nodes can fail and recover. Temporary issues can resolve themselves. And when retries are exhausted, failure is clear and deliberate, not silent or confusing.&lt;/p&gt;

&lt;p&gt;Once you adopt this mindset, error handling stops being an afterthought and becomes part of your design. That is the difference between a demo graph and a production-ready one.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Dynamic Routing in LangGraph with Command()</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Mon, 22 Dec 2025 08:13:37 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-dynamic-routing-in-langgraph-with-command-2c5l</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-dynamic-routing-in-langgraph-with-command-2c5l</guid>
      <description>&lt;p&gt;When you build agents, not every request should follow the same path. Some inputs require tools, others require reasoning, and some simply need a quick response. Hard-coding all these paths quickly becomes messy. This is where &lt;strong&gt;dynamic routing&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;Dynamic routing means your graph decides &lt;strong&gt;what to do next at runtime&lt;/strong&gt;, based on the current state. Instead of fixed edges that always lead to the same node, the graph can change direction depending on user intent, tool results, or intermediate reasoning.&lt;/p&gt;

&lt;p&gt;LangGraph supports this kind of flexibility naturally, but the real enabler is the &lt;strong&gt;Command() API&lt;/strong&gt;. With Command(), a node can explicitly tell the graph which node to run next and, optionally, update the state at the same time. You’re no longer just returning data; you’re returning &lt;strong&gt;instructions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of Command() as giving your node a voice. Instead of silently handing off control, it can say, “Go here next,” “Stop now,” or “Route this to a different path.” That’s the foundation of dynamic routing in LangGraph, and once you understand it, your graphs become far more expressive and intelligent.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Is Dynamic Routing in LangGraph?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Dynamic routing is the idea that your graph does not have to follow a fixed path. Instead of always moving from Node A to Node B, the next step can change at runtime based on what just happened.&lt;/p&gt;

&lt;p&gt;In LangGraph, this means your agent can look at the current state, make a decision, and then choose where to go next. One user input might lead to a search node, another might trigger a tool call, and a third might end the conversation entirely. The flow adapts as it runs.&lt;/p&gt;

&lt;p&gt;This is different from static routing, where edges are defined upfront and the graph always follows the same structure. Static routing is predictable, but limited. Dynamic routing is flexible, expressive, and much closer to how real agents behave.&lt;/p&gt;

&lt;p&gt;LangGraph supports dynamic routing through the &lt;strong&gt;Command()&lt;/strong&gt; object. Instead of returning just state updates, a node can return instructions that tell the graph exactly what to do next. This is what allows your agent to branch, reroute, loop, or exit intelligently, all at runtime.&lt;/p&gt;

&lt;p&gt;Once you understand this concept, you stop thinking of LangGraph as a pipeline and start seeing it as a decision-making system.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Command() Enables Dynamic Routing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is where things get interesting.&lt;/p&gt;

&lt;p&gt;In LangGraph, &lt;strong&gt;Command()&lt;/strong&gt; is what allows a node to decide what happens next &lt;em&gt;at runtime&lt;/em&gt;. Instead of relying on predefined conditional edges, a node can return a Command that explicitly tells the graph which node to run next and what state updates to apply.&lt;/p&gt;

&lt;p&gt;Think of Command() as the node saying, “I’ve looked at the situation, and this is where we should go.”&lt;/p&gt;

&lt;p&gt;When a node returns a Command, it can specify two important things. First, the &lt;strong&gt;next node&lt;/strong&gt; to jump to. Second, any &lt;strong&gt;state updates&lt;/strong&gt; that should be applied before moving on. This makes routing flexible, expressive, and easy to reason about.&lt;/p&gt;

&lt;p&gt;What makes this powerful is that the decision logic lives &lt;em&gt;inside&lt;/em&gt; the node itself. The node can inspect user input, model output, tool results, or any part of the state, and then dynamically choose the next step. No extra edge definitions. No complex routing tables. Just clear intent.&lt;/p&gt;

&lt;p&gt;Dynamic routing with Command() shines when your agent needs to adapt on the fly. Maybe the user asks a follow-up question, maybe a tool call fails, or maybe the model decides it needs more information before continuing. Instead of forcing all possibilities into static edges, Command() lets your graph respond naturally.&lt;/p&gt;

&lt;p&gt;At this point, LangGraph stops feeling like a rigid workflow engine and starts behaving like a living system that can change direction when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Command(): The Engine Behind Dynamic Routing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In LangGraph, &lt;strong&gt;Command()&lt;/strong&gt; is what allows a node to decide what happens next at runtime. Instead of relying only on pre-defined edges, Command() lets a node return instructions that tell the graph both &lt;strong&gt;where to go next&lt;/strong&gt; and &lt;strong&gt;how to update state&lt;/strong&gt; in one move.&lt;/p&gt;

&lt;p&gt;At a high level, a &lt;code&gt;Command&lt;/code&gt; contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;next node&lt;/strong&gt; (or nodes) the graph should execute&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;state updates&lt;/strong&gt; that should be applied before moving forward&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means routing decisions are no longer fixed in the graph structure alone. They can be made dynamically, based on logic, tool results, or LLM output inside the node itself.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;How Command() Enables Dynamic Routing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With Command(), routing logic lives inside the node function. A node can inspect the current state, make a decision, and return a Command that tells the graph exactly what to do next.&lt;/p&gt;

&lt;p&gt;Here’s what happens when a node returns a Command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the node evaluates the current state&lt;/li&gt;
&lt;li&gt;It decides which node should run next&lt;/li&gt;
&lt;li&gt;It updates the state if needed&lt;/li&gt;
&lt;li&gt;The graph immediately follows the instruction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because state updates and routing happen together, the flow stays predictable and clean. There’s no need for extra router nodes or complex conditional edges.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A Simple Example: Routing Based on User Intent&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s make this real with a small example.&lt;/p&gt;

&lt;p&gt;We’ll build a router node that looks at user intent and decides where the graph should go next.&lt;/p&gt;

&lt;h3&gt;
  
  
  The idea
&lt;/h3&gt;

&lt;p&gt;A user sends a message.&lt;/p&gt;

&lt;p&gt;If the message looks like a question, we go to a &lt;strong&gt;question handler&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If it looks like a command, we go to a &lt;strong&gt;command handler&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The routing decision happens inside the node using &lt;code&gt;Command()&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Example Code&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Command&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;how&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;what&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;command_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;command&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;question_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This looks like a question.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;command_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This looks like a command.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;router&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;question_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;command_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;command_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_entry_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;router&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/5Wpsnw1olXE"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What’s happening here&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;router node&lt;/strong&gt; inspects the user input.&lt;/li&gt;
&lt;li&gt;Instead of returning plain state, it returns a &lt;code&gt;Command&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;goto&lt;/code&gt; field tells LangGraph which node to run next.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;update&lt;/code&gt; field safely updates the shared state at the same time.&lt;/li&gt;
&lt;li&gt;The graph follows the instruction immediately, no conditional edges needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is dynamic routing in its simplest form.&lt;/p&gt;

&lt;p&gt;The decision lives inside the node, and the graph just follows orders.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Why this matters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;Command()&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;routing logic stays close to the reasoning&lt;/li&gt;
&lt;li&gt;graphs become easier to read&lt;/li&gt;
&lt;li&gt;dynamic flows feel natural, not forced&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you understand this pattern, you can build agents that adapt on the fly without turning your graph into a maze of conditionals.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Best Practices for Dynamic Routing with Command()&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep routing logic simple and easy to reason about. A node should decide &lt;em&gt;where to go next&lt;/em&gt; based on clear signals, not complex chains of conditions.&lt;/li&gt;
&lt;li&gt;Separate decision-making from heavy computation. Let one node focus on choosing the route, and let downstream nodes do the actual work.&lt;/li&gt;
&lt;li&gt;Always update state intentionally. Only include the data the next node needs to continue correctly.&lt;/li&gt;
&lt;li&gt;Use meaningful node names. This makes your routing logic easier to read, debug, and visualize.&lt;/li&gt;
&lt;li&gt;Visualize your graph early. Dynamic routing becomes much clearer when you can see the possible paths your graph can take.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Dynamic routing is what turns a LangGraph app from a fixed pipeline into a truly intelligent system. With &lt;code&gt;Command()&lt;/code&gt;, a node can make decisions, update state, and choose the next step all at once — cleanly and explicitly.&lt;/p&gt;

&lt;p&gt;Instead of hardcoding paths or relying on fragile conditionals, you let each node say, &lt;em&gt;“Here’s what I learned, and here’s where we should go next.”&lt;/em&gt; That clarity is what makes LangGraph powerful, predictable, and scalable.&lt;/p&gt;

&lt;p&gt;Once you understand &lt;code&gt;Command()&lt;/code&gt;, you stop thinking in straight lines and start designing flows that adapt naturally to user intent and runtime context.&lt;/p&gt;

&lt;p&gt;And that’s when your graphs really come alive&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Map-Reduce with the Send() API in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Mon, 15 Dec 2025 09:50:52 +0000</pubDate>
      <link>https://forem.com/aiengineering/map-reduce-with-the-send-api-in-langgraph-1p5o</link>
      <guid>https://forem.com/aiengineering/map-reduce-with-the-send-api-in-langgraph-1p5o</guid>
      <description>&lt;p&gt;If you’ve ever looked at a big task and thought, “There has to be a faster way to do this,” you were already thinking in &lt;strong&gt;Map-Reduce&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;/p&gt;

&lt;p&gt;Learn LangChain in a clear, concise, and practical way.&lt;br&gt;
Whether you’re just starting out or already building, LangCasts offers guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at Langcasts.com.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Map-Reduce is a powerful pattern for processing large amounts of data efficiently. In essence, it breaks a big task into smaller chunks (the &lt;strong&gt;map&lt;/strong&gt; phase), processes them independently, and then combines the results (the &lt;strong&gt;reduce&lt;/strong&gt; phase). This approach is widely used in data analytics, machine learning, and large-scale computing.&lt;/p&gt;

&lt;p&gt;However, implementing Map-Reduce manually can be tricky. You often have to manage parallel execution, coordinate tasks, and handle intermediate results—all of which can become messy and error-prone.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;LangGraph&lt;/strong&gt; comes in. With its intuitive graph-based architecture and the &lt;strong&gt;&lt;code&gt;Send()&lt;/code&gt; API&lt;/strong&gt;, LangGraph makes Map-Reduce workflows cleaner, faster, and more maintainable. Nodes represent tasks, edges define data flow, and &lt;code&gt;Send()&lt;/code&gt; enables true parallel execution with minimal boilerplate.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore how to implement Map-Reduce in LangGraph using the &lt;code&gt;Send()&lt;/code&gt; API, from the basics to a practical example, showing how this modern approach simplifies one of the most important patterns in data processing.&lt;/p&gt;

&lt;p&gt;Before diving into Map-Reduce, it’s helpful to recall some core LangGraph concepts. At its heart, LangGraph organizes computations as a &lt;strong&gt;graph of nodes and edges&lt;/strong&gt;, with nodes performing tasks, edges defining data flow, and state storing intermediate results.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nodes&lt;/strong&gt; are the building blocks—each represents a discrete unit of work. If you missed it, check out our previous guide on &lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-with-nodes-in-langgraph-5g45"&gt;getting started with nodes in LangGraph&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edges&lt;/strong&gt; connect nodes and guide how data flows through your workflow. For a refresher, see &lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-on-edges-in-langgraph-59be"&gt;our article on edges&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-in-agent-state-in-langgraph-3bkj"&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/a&gt; lets nodes hold temporary results, which is especially handy in patterns like Map-Reduce.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send()&lt;/strong&gt; enables parallel execution, letting multiple tasks run simultaneously without manual thread management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, nodes, edges, state, and &lt;code&gt;Send()&lt;/code&gt; are the perfect toolkit for building scalable workflows. If you’re familiar with our previous beginner guides, this will feel like a natural next step toward implementing Map-Reduce in LangGraph.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where Map-Reduce Fits in LangGraph
&lt;/h3&gt;

&lt;p&gt;LangGraph’s design makes it a natural fit for the Map-Reduce pattern. By combining &lt;strong&gt;nodes, edges, state, and the &lt;code&gt;Send()&lt;/code&gt; API&lt;/strong&gt;, you can build scalable parallel workflows without the usual complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Map Phase – Nodes as Workers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each node can act as a mapper, processing a piece of data independently. Because nodes are isolated, multiple map tasks can run concurrently, producing intermediate results without interfering with each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. State – Storing Intermediate Results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As nodes process data, they can store outputs in their local state or shared runtime context. These intermediate results are what the reduce phase will later aggregate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Edges – Shuffling Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edges guide how intermediate outputs flow from map nodes to reducer nodes. You can fan out results to multiple reducers or aggregate them into a single node, replicating the “shuffle” step in traditional Map-Reduce.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Send() – Unlocking True Parallelism&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While nodes can run sequentially, the &lt;code&gt;Send()&lt;/code&gt; function allows a parent node to dispatch tasks to multiple child nodes at the same time. This is the missing piece that enables full parallel execution: all map tasks can run simultaneously, and their outputs are efficiently routed to reducer nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Summary:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nodes = map tasks&lt;/li&gt;
&lt;li&gt;State = intermediate storage&lt;/li&gt;
&lt;li&gt;Edges = data flow&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Send()&lt;/code&gt; = parallel execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these components, implementing Map-Reduce in LangGraph becomes straightforward, scalable, and easy to maintain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Example: Word Count with Send()
&lt;/h3&gt;

&lt;p&gt;Let’s bring Map-Reduce to life in LangGraph with a classic example: counting word frequencies in a set of documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Map Nodes – Processing Each Document&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each document is sent to a separate node using &lt;code&gt;Send()&lt;/code&gt;. Map nodes tokenize the text and emit key-value pairs like &lt;code&gt;("word", 1)&lt;/code&gt; for every word found. Because we’re using &lt;code&gt;Send()&lt;/code&gt;, multiple documents can be processed in parallel, making the workflow fast and efficient.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;map_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. State – Storing Intermediate Results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each map node can store its output in local state or a shared runtime context. These intermediate results are collected and passed to reducer nodes for aggregation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Reduce Nodes – Aggregating Results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reducer nodes take the intermediate key-value pairs and sum the counts for each unique word. This completes the “reduce” step of Map-Reduce.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reduce_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intermediate_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;word_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;intermediate_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;word_count&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Edges – Guiding Data Flow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edges connect map nodes to the reducer node(s), forming the shuffle stage. LangGraph handles the routing automatically, ensuring all intermediate results reach the correct reducer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Send() – Parallelizing the Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Send()&lt;/code&gt; API dispatches all map nodes simultaneously. Once all map nodes complete, the results flow to the reducer node(s) without blocking execution. This is how LangGraph achieves true parallel Map-Reduce.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/5iYV0q6eKbM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Send()&lt;/code&gt; enables parallel mapping across nodes.&lt;/li&gt;
&lt;li&gt;Node state holds intermediate outputs.&lt;/li&gt;
&lt;li&gt;Edges define how data moves to reducers.&lt;/li&gt;
&lt;li&gt;Reducer nodes aggregate results efficiently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages of Using Send() for Map-Reduce
&lt;/h3&gt;

&lt;p&gt;Using LangGraph with the &lt;code&gt;Send()&lt;/code&gt; API offers several key advantages over traditional Map-Reduce implementations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. True Parallelism Without Extra Complexity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Send()&lt;/code&gt; lets you dispatch multiple nodes simultaneously, so map tasks run in parallel without manually managing threads or processes. This reduces boilerplate code and potential errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Clean, Maintainable Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because each task is represented as a node and the data flow is handled by edges, your workflow is visual, easy to follow, and simple to maintain. There’s no need to juggle intermediate files or complicated coordination logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Scalability Made Easy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adding more tasks or processing larger datasets is straightforward. Just add more nodes or use &lt;code&gt;Send()&lt;/code&gt; to scale horizontally—LangGraph handles the routing and execution automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Built-In State Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Intermediate results are stored in node state or runtime context, making aggregation and reduction seamless. You don’t have to build custom storage or data collection mechanisms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Flexibility Across Workflows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Map-Reduce isn’t the only pattern supported. By combining nodes, edges, state, and &lt;code&gt;Send()&lt;/code&gt;, you can implement complex, parallel workflows beyond traditional Map-Reduce, all within the same graph structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tips &amp;amp; Best Practices
&lt;/h3&gt;

&lt;p&gt;To get the most out of Map-Reduce workflows in LangGraph with &lt;code&gt;Send()&lt;/code&gt;, keep these tips in mind:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Use Send() for True Parallelism&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only use &lt;code&gt;Send()&lt;/code&gt; when tasks can run independently. Sequential tasks don’t benefit from parallel execution and may introduce unnecessary complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Manage Large Intermediate States Carefully&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your map nodes produce a lot of intermediate data, consider splitting it across multiple reducer nodes or using streaming techniques to prevent memory overload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Handle Errors Gracefully&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Parallel execution means one failing node shouldn’t crash the entire workflow. Implement error handling or retries within nodes to make your pipeline robust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Keep Nodes Focused&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each node should perform a single, well-defined task. This makes debugging easier and allows &lt;code&gt;Send()&lt;/code&gt; to scale effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Plan Your Edges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edges determine how data moves from mappers to reducers. Keep the data flow clear and organized to avoid bottlenecks or unnecessary complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Reuse Nodes When Possible&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If multiple workflows share similar tasks, reuse nodes to reduce duplication and maintain consistency across your graphs.&lt;/p&gt;




&lt;p&gt;Map-Reduce is a powerful pattern for processing large datasets, and LangGraph makes it simpler, cleaner, and faster. By combining &lt;strong&gt;nodes, edges, state, and the &lt;code&gt;Send()&lt;/code&gt; API&lt;/strong&gt;, you can build parallel workflows without the usual headaches of manual coordination or threading.&lt;/p&gt;

&lt;p&gt;With nodes acting as mappers, edges guiding data flow, state holding intermediate results, and &lt;code&gt;Send()&lt;/code&gt; enabling true parallel execution, LangGraph turns complex data processing into a manageable, scalable, and maintainable graph.&lt;/p&gt;

&lt;p&gt;If you’ve followed along, you now know how to implement a Map-Reduce workflow—from mapping individual tasks to reducing aggregated results—while leveraging LangGraph’s parallelism capabilities.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Understanding the Runtime Context in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Mon, 08 Dec 2025 07:13:11 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-understanding-the-runtime-context-in-langgraph-4bip</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-understanding-the-runtime-context-in-langgraph-4bip</guid>
      <description>&lt;p&gt;Building agentic workflows sounds simple until you try to keep everything straight. Data jumps from one step to another. Tools fire at different times. Logic branches. Memory shifts. Before long, you find yourself juggling state by hand, passing oversized payloads between nodes, and trying to keep the whole thing from collapsing under its own weight.&lt;/p&gt;

&lt;p&gt;This is the core problem LangGraph set out to fix.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;/p&gt;

&lt;p&gt;Learn LangChain in a clear, concise, and practical way.&lt;/p&gt;

&lt;p&gt;Whether you’re just starting out or already building, LangCasts offers guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at Langcasts.com.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Runtime Context gives every part of the graph a shared, reliable place to read from and write to. Instead of pushing state through every node like a relay baton, each node taps into a common workspace. It can check what has happened so far, update what needs to change, and move on without breaking the flow.&lt;/p&gt;

&lt;p&gt;In practice, this removes a huge amount of friction. You are no longer wiring state across dozens of transitions or guarding against missing values. The graph becomes easier to reason about. Nodes behave like pieces of one system rather than scattered functions stitched together by duct tape.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Runtime Context Flows Through a Graph
&lt;/h2&gt;

&lt;p&gt;A LangGraph workflow runs step by step, but the Runtime Context travels with every node. Each node receives the same shared context. It is static, consistent, and read-only. Nothing inside it changes during a run. Nodes only read from it.&lt;/p&gt;

&lt;p&gt;Alongside it sits the Graph State, which is the opposite. It is dynamic and mutable. Nodes read it, modify it, and hand the updated version forward. This is how the graph keeps track of evolving data like model outputs, tool results, and decisions.&lt;/p&gt;

&lt;p&gt;Here is the core distinction:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Runtime Context&lt;/th&gt;
&lt;th&gt;Graph State&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Static dependencies needed for execution&lt;/td&gt;
&lt;td&gt;Live memory of the workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mutability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read-only&lt;/td&gt;
&lt;td&gt;Read/write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;user_id, API keys, DB connections, configs&lt;/td&gt;
&lt;td&gt;messages, intermediate results, flags, outputs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lifecycle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Set once at invocation&lt;/td&gt;
&lt;td&gt;Updated continuously across nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This split keeps the workflow predictable. Runtime Context gives nodes stable information they can trust. Graph State holds everything that changes.&lt;/p&gt;

&lt;p&gt;The flow is straightforward.&lt;/p&gt;

&lt;p&gt;A node runs. It reads from the Runtime Context and the current Graph State. It performs its job. It updates only the Graph State. Then the graph routes to the next node based on that updated state. The Runtime Context stays untouched throughout.&lt;/p&gt;

&lt;p&gt;Because of this separation, your workflow avoids the usual mess of passing dependencies manually, mixing secrets with state, or polluting memory with data that never changes. The graph stays easier to reason about, easier to test, and safer in multi-tenant environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features of the Runtime Context
&lt;/h2&gt;

&lt;p&gt;The Runtime Context is more than a bucket of variables. It gives your graph a structured environment to work in, with a few core features that make complex workflows manageable.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Shared State&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every node works from the same state. You can store user input, model outputs, intermediate decisions, or anything the workflow needs later. Because the state is shared, you avoid awkward data plumbing and inconsistent copies.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Memory Access&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The context connects directly to whatever memory system you attach to the graph. Nodes can read long term facts, update short term memory, or store conversation history without extra wiring. This is what lets agents feel consistent across turns.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Environmental Data&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can store configuration details, request metadata, external settings, or execution flags. Instead of scattering these across your code, you keep them in one place where the whole graph can reach them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;IO Channels&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The context gives nodes a simple way to emit messages, tool calls, or control signals. This keeps communication orderly inside the graph, avoids cross-talk, and helps nodes coordinate cleanly without hidden side effects.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Hooks and Middleware&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Because everything passes through the context, you can attach hooks to inspect, modify, or log state at different moments in a run. This is valuable when you want guardrails, analytics, or debugging visibility without touching every node.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Runtime Context in Your Own Graph
&lt;/h2&gt;

&lt;p&gt;Runtime Context gives each node access to the static data it needs without cluttering the mutable Graph State. You pass these values in at run time, and every node can read them directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passing Custom Data Into the Graph
&lt;/h3&gt;

&lt;p&gt;When invoking a graph, you inject static dependencies through the &lt;code&gt;context&lt;/code&gt; argument. These values stay fixed for the entire run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;runtime_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;abc123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sk-xyz&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;make_db_connection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;runtime_context&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps sensitive or unchanging data out of your state, which is critical for clean execution and safe multi-tenant setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing Runtime Context Inside a Node
&lt;/h3&gt;

&lt;p&gt;Inside a node, you read static values through &lt;code&gt;runtime.context&lt;/code&gt;. You never modify them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lookup_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;profile&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The node pulls what it needs, performs its work, updates the Graph State, and moves on.&lt;/p&gt;

&lt;p&gt;Runtime Context stays untouched.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visual Diagram
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     ┌───────────────────────────┐
                     │      Runtime Context       │
                     │  (user_id, api_key, db)    │
                     │  static • read-only        │
                     └───────────────┬───────────┘
                                     │
                                     ▼
                         ┌────────────────────┐
                         │       Node A       │
                         │ reads context      │
                         │ updates state      │
                         └─────────┬──────────┘
                                   │
                                   ▼
                         ┌────────────────────┐
                         │       Node B       │
                         │ reads context      │
                         │ updates state      │
                         └────────────────────┘

              Graph State (grows and changes across nodes)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Use This Pattern
&lt;/h3&gt;

&lt;p&gt;Keeping dependencies in Runtime Context does three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keeps Graph State focused on values that actually change.&lt;/li&gt;
&lt;li&gt;Makes nodes easier to test because you can inject fake runtime dependencies.&lt;/li&gt;
&lt;li&gt;Prevents leaks when running multiple tenants on the same graph.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each node becomes predictable. You know exactly what can change and what cannot.&lt;br&gt;


  &lt;iframe src="https://www.youtube.com/embed/Mnwqxd0udAU"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Use Cases
&lt;/h2&gt;

&lt;p&gt;The Runtime Context earns its keep when workflows go beyond simple linear steps. It gives your graph enough awareness to act intelligently, recover gracefully, and keep conversations coherent.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Multi Step Reasoning&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Reasoning chains work best when each step can see what came before. The context holds intermediate conclusions, scratch work, and decisions so later nodes don’t start from zero. This lets you build deeper, more dependable logic without manual state passing.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conversational Agents with Memory&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A good agent needs more than the last message. It needs history, facts, preferences, and anything the user shared earlier. The context surfaces all of that directly. Nodes don’t hunt through external stores or long prompts. They read from a single place and update memory in a controlled way.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Tool Orchestration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tool use quickly becomes messy if you juggle inputs and outputs by hand. With the context, tools feed their results straight into the shared state. Downstream nodes instantly get the updated information, which keeps chains tight and predictable.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Branching Based on State&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Graphs often need to change direction. Maybe a tool failed. Maybe the user asked something new. Maybe a policy guardrail triggered. Nodes can inspect the context, set a routing flag, and let the graph decide the next step. No tangled if-else sprawl.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Error Handling and Recovery&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When something breaks, the context holds enough information to recover. You can retry a node, fall back to a safer path, or log exactly what went wrong without losing the thread of the run. This makes complex graphs far more resilient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;p&gt;A workflow is only as clean as the way it handles state. LangGraph makes this easier, but you still need discipline. These best practices keep your graphs predictable, safe, and simple to maintain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Static Dependencies in Runtime Context, Not Graph State
&lt;/h3&gt;

&lt;p&gt;Static values like &lt;code&gt;user_id&lt;/code&gt;, API keys, database handles, configuration flags, or service clients belong in &lt;strong&gt;Runtime Context&lt;/strong&gt;. They do not belong in Graph State.&lt;/p&gt;

&lt;p&gt;Why this matters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem if stored in Graph State&lt;/th&gt;
&lt;th&gt;Why it hurts&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Static data becomes mutable&lt;/td&gt;
&lt;td&gt;Harder to debug and reason about&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State grows with every step&lt;/td&gt;
&lt;td&gt;Slows down execution and inflates logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test runs require fake state setup&lt;/td&gt;
&lt;td&gt;More boilerplate, less flexibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-tenant leakage risk&lt;/td&gt;
&lt;td&gt;One user’s secrets can bleed into another run&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Runtime Context solves all of this by giving each run a sealed, isolated environment for dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update Only What Your Node Owns
&lt;/h3&gt;

&lt;p&gt;Nodes should modify their own slice of state, nothing else. This avoids hidden interactions and makes each node’s behaviour easy to trace.&lt;/p&gt;

&lt;p&gt;Good:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random_mix_of_keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Keep State Focused
&lt;/h3&gt;

&lt;p&gt;Graph State should hold just the values that change as the workflow progresses: results, messages, flags, and intermediate outputs. Everything else belongs elsewhere.&lt;/p&gt;

&lt;p&gt;A light state is easier to debug and easier to replay.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validate Before Writing
&lt;/h3&gt;

&lt;p&gt;Never trust a model or tool blindly. Check the data. If it’s malformed, fix it or stop it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid tool output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Small guards prevent long debugging sessions later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Document Keys as You Build
&lt;/h3&gt;

&lt;p&gt;A short comment or a shared schema goes a long way. If your state has five or ten fields, define what they mean and which node owns them. Your future self will thank you.&lt;/p&gt;




&lt;p&gt;A solid workflow depends on clear boundaries. LangGraph’s Runtime Context gives you exactly that. Static, reliable data stays in one place. Dynamic, evolving state lives in another. Once you follow this split, graphs become easier to build, easier to test, and far safer to run in real environments.&lt;/p&gt;

&lt;p&gt;You spend less time managing state and more time shaping behavior. Nodes stay focused. Debugging gets simpler. Multi tenant setups become straightforward instead of stressful. Most importantly, the graph feels like a single system rather than scattered pieces taped together.&lt;/p&gt;

&lt;p&gt;If you keep your dependencies in Runtime Context and let Graph State track the story of each run, everything else falls into place.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Getting Started on Edges in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Mon, 01 Dec 2025 02:35:08 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-on-edges-in-langgraph-59be</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-on-edges-in-langgraph-59be</guid>
      <description>&lt;p&gt;If you’ve been following this LangGraph series, you already know we’ve covered a lot of ground: &lt;strong&gt;nodes&lt;/strong&gt;, &lt;strong&gt;state&lt;/strong&gt;, &lt;strong&gt;reducers&lt;/strong&gt;, &lt;strong&gt;graph messages&lt;/strong&gt;, &lt;strong&gt;MCP&lt;/strong&gt;, and most recently, &lt;strong&gt;getting started with nodes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now it’s time to talk about the part that &lt;em&gt;actually makes your graph move&lt;/em&gt;: &lt;strong&gt;Edges&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;br&gt;
Learn LangChain in a clear, concise, and practical way.&lt;br&gt;
Whether you’re just starting out or already building, Langcasts offers guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at Langcasts.com.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think of it this way: Nodes are the &lt;em&gt;rooms&lt;/em&gt; in your workflow, each room has its own job.&lt;/p&gt;

&lt;p&gt;But how do you move from one room to the next?&lt;/p&gt;

&lt;p&gt;How does LangGraph know which step should come after “validate_user” or “ask_llm”?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edges.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edges are the connectors, the “doors,” the “next step,” the “go here after this” instructions that give your graph direction and rhythm. Without edges, your nodes just sit there… smart, but useless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why should you care?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because edges turn your static setup into a dynamic, intelligent pipeline.&lt;/p&gt;

&lt;p&gt;They define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;execution flow&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;order of operations&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;branches&lt;/strong&gt; (this way if X, that way if Y)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;logic&lt;/strong&gt; behind your decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Edges are where your workflow stops being linear code and becomes a flexible graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Role of Edges in LangGraph&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In LangGraph, edges play &lt;strong&gt;two major roles&lt;/strong&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Edges Control Execution Flow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When one node finishes running, LangGraph needs to know:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Okay… where do we go now?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edges answer that question.&lt;/p&gt;

&lt;p&gt;They determine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;next&lt;/em&gt; node to run&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;order&lt;/em&gt; in which nodes fire&lt;/li&gt;
&lt;li&gt;Whether the graph moves forward, loops, or jumps to a new branch&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Edges Allow Smart Decisions (Branching)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Edges are not just straight lines, they can be &lt;strong&gt;conditional&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Meaning:&lt;/p&gt;

&lt;p&gt;You can tell LangGraph:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If the state looks like this, go to Node A.&lt;/p&gt;

&lt;p&gt;But if it looks like &lt;strong&gt;that&lt;/strong&gt;, go to Node B.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is how you build multi-step assistants, error-handling flows, approval or rejection paths, “If user says X → answer Y” logic and even Complex agent behaviours that still feel simple and natural&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Creating Your First Edge (The Basic Flow)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you understand what edges &lt;em&gt;do&lt;/em&gt;, let’s actually create one.&lt;/p&gt;

&lt;p&gt;This is the moment your graph stops being a collection of lonely nodes and starts behaving like a real workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Define Two Nodes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s assume we have two tiny nodes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello from Node A!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;We moved to Node B!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These nodes don’t mean much yet, they’re just two disconnected rooms.&lt;/p&gt;

&lt;p&gt;Let’s connect them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Set an Entry Point&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every graph needs a starting point. This is where the execution begins.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_entry_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;greet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells LangGraph:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Start the workflow at the greet node.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Add a Normal Edge (Node A → Node B)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here’s the magic line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;greet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reply&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;You’ve just created your first flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;greet  ───▶  reply

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;greet&lt;/code&gt; finishes running, LangGraph will automatically jump to &lt;code&gt;reply&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why This Matters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This tiny step unlocks everything else you’ll build.&lt;/p&gt;

&lt;p&gt;With a single edge, you’ve defined a &lt;strong&gt;sequence&lt;/strong&gt;, a &lt;strong&gt;direction&lt;/strong&gt;, a &lt;strong&gt;storyline&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From here, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extend your chain&lt;/li&gt;
&lt;li&gt;Add multiple branches&lt;/li&gt;
&lt;li&gt;Insert conditionals&lt;/li&gt;
&lt;li&gt;Loop backward&lt;/li&gt;
&lt;li&gt;Build multi-step assistants.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up: let’s talk about the fun part — &lt;strong&gt;conditional edges&lt;/strong&gt;, where things get smarter and more dynamic.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conditional Edges&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is where LangGraph stops being a linear pipeline and starts behaving like a decision-maker — choosing different next steps depending on what's happening in the &lt;strong&gt;state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;LangGraph evaluates your state after a node runs and routes the flow accordingly.&lt;/p&gt;

&lt;p&gt;It’s the same way you make decisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the user said “yes,” continue the process&lt;/li&gt;
&lt;li&gt;If they said “no,” return an error&lt;/li&gt;
&lt;li&gt;If the data is incomplete, ask for clarification&lt;/li&gt;
&lt;li&gt;If the model is confused, send outputs to a fallback node&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Conditional edges are the &lt;em&gt;branching logic&lt;/em&gt; of your graph.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How to Add a Conditional Edge&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You use this method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;condition_function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;condition_value_1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;next_node_1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;condition_value_2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;next_node_2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s make that real.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example: Yes or No Routing&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Write a node that updates state&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ask_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# maybe this came from an LLM or user input
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Write a condition function&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The function receives the current state and returns a label.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;go_ahead&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Add the conditional edges&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ask_user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;check_answer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;go_ahead&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proceed_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exit_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                ───▶ proceed_node
ask_user ───┤
                ───▶ exit_node

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Why Conditional Edges Matter&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;They help you build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smart assistants&lt;/li&gt;
&lt;li&gt;Decision trees&lt;/li&gt;
&lt;li&gt;Error handling flows&lt;/li&gt;
&lt;li&gt;Multi-path LLM reasoning&lt;/li&gt;
&lt;li&gt;Tool-based routing&lt;/li&gt;
&lt;li&gt;Real-world applications where one answer never fits all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up: you’ll see how edges look visually and why graph visualization is your best friend when debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Visualizing Edges&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you know how to connect nodes with edges — both normal and conditional — it’s time to actually &lt;em&gt;see&lt;/em&gt; what your graph looks like.&lt;/p&gt;

&lt;p&gt;Because here’s the truth:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visualizing your graph is the fastest way to understand, debug, and trust your workflow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LangGraph gives you a built-in way to do this, and it’s &lt;em&gt;super&lt;/em&gt; beginner-friendly.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why Visualization Matters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you visualize your graph, you can instantly spot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your entry point&lt;/li&gt;
&lt;li&gt;All node connections&lt;/li&gt;
&lt;li&gt;Branching paths&lt;/li&gt;
&lt;li&gt;Loops&lt;/li&gt;
&lt;li&gt;Missing edges&lt;/li&gt;
&lt;li&gt;Incorrect routing&lt;/li&gt;
&lt;li&gt;Accidental “dead ends”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of guessing how your graph flows, you can literally &lt;em&gt;see its structure&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Perfect for beginners. Perfect for debugging.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How to Visualize Your Graph&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;After defining your nodes + edges, just call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hit &lt;strong&gt;graph.display()&lt;/strong&gt;, and LangGraph will render a clean diagram showing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;greet ───▶ reply
           │
           └──▶ fallback (if conditional)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conditional paths are especially clear — you’ll see branches labeled with the condition values your function returns.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;A Quick Example Diagram&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here’s a simple mental model of what you’ll see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          [ ask_user ]
                │
     ┌──────────┴──────────┐
     ▼                     ▼
[ proceed_node ]     [ exit_node ]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s readable, friendly, and instantly shows how your edges direct the flow.&lt;/p&gt;

&lt;p&gt;This one move — calling &lt;code&gt;graph.display()&lt;/code&gt; — saves hours of confusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Common Edge Patterns You’ll Use Every Day&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Edges in LangGraph are the rules that shape how your agent thinks and moves. As you start building real apps, you’ll find that a few edge patterns show up over and over again:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Linear Edges (Straight-Line Flow)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is the “do A, then B, then C” pattern.&lt;/p&gt;

&lt;p&gt;Perfect for simple pipelines like: &lt;strong&gt;parse → validate → respond&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Conditional Edges (Decision-Making Flow)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Edges choose the next node based on some condition.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;If the user asks a weather question → go to WeatherNode.&lt;/p&gt;

&lt;p&gt;Otherwise → go to DefaultNode.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Looping Edges (Iterative Flow)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;These edges send the graph back to the same node.&lt;/p&gt;

&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrying a failed step&lt;/li&gt;
&lt;li&gt;gathering more user input&lt;/li&gt;
&lt;li&gt;iterative refinement (e.g., rewriting until satisfied)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Termination Edges (End the Flow)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Some edges simply stop the execution.&lt;/p&gt;

&lt;p&gt;Great for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;finishing a response&lt;/li&gt;
&lt;li&gt;returning a final value&lt;/li&gt;
&lt;li&gt;clean agent shutdown&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Tool-Driven Edges (Flow Depends on Tool Output)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Sometimes a tool's result determines the next step.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;If the API returns “not found” → go to ErrorNode.&lt;/p&gt;

&lt;p&gt;Otherwise → continue to ProcessNode.&lt;/p&gt;

&lt;p&gt;These patterns form the backbone of almost every LangGraph app, and once you spot them, you’ll begin to design graphs more intentionally.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to Add Edges in LangGraph (Plus a Full Working Example)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Edges are how you tell LangGraph what should happen &lt;em&gt;next&lt;/em&gt;. Adding them is simple, you connect one node to another, and LangGraph takes care of the flow.&lt;/p&gt;

&lt;p&gt;Here’s the basic pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node_a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node_b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;p&gt;After &lt;strong&gt;node_a&lt;/strong&gt; runs → go to &lt;strong&gt;node_b&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Need decisions instead of straight lines? Use conditional edges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;router_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WeatherNode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;news&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NewsNode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fallback&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FallbackNode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want the graph to stop? Point to &lt;code&gt;END&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.constants&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;final_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s put this into a full, runnable example so you can see edges in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello from the user!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;processed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Final Output:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;processed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UserInput&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Process&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Finish&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Connect everything
&lt;/span&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UserInput&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Process&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Process&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Finish&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Finish&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tiny graph flows cleanly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UserInput → Process → Finish → END&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nothing fancy, just nodes doing their jobs, and edges telling LangGraph how to move from one step to the next.&lt;/p&gt;

&lt;p&gt;This is the heart of edges: simple rules that shape your entire agent flow.&lt;/p&gt;




&lt;p&gt;Nodes may be the “brains” of your LangGraph app, but edges are the &lt;strong&gt;glue, the direction, and the heartbeat&lt;/strong&gt; of your agent’s flow. They tell your system &lt;em&gt;what happens next&lt;/em&gt;, shaping raw logic into a smooth, functional pipeline.&lt;/p&gt;

&lt;p&gt;With just a few lines of code, edges let you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build linear flows&lt;/li&gt;
&lt;li&gt;branch into decisions&lt;/li&gt;
&lt;li&gt;create loops and retries&lt;/li&gt;
&lt;li&gt;terminate cleanly&lt;/li&gt;
&lt;li&gt;design complex agent behavior with simplicity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the best part?&lt;/p&gt;

&lt;p&gt;Once you understand edges, your graphs stop being random blocks of code and start becoming &lt;strong&gt;clear stories&lt;/strong&gt; your agent can follow.&lt;/p&gt;

&lt;p&gt;You’ve already explored nodes, reducers, state, and messages in previous parts of your LangGraph series, and now with edges in your toolkit, you’re equipped to build real, flexible, intelligent agent flows.&lt;/p&gt;

&lt;p&gt;Go on and experiment. Connect a few nodes. Visualize your graph.&lt;/p&gt;

&lt;p&gt;Soon, you’ll be designing flows that feel effortless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Onward to the next part of the series. You’re getting really good at this.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Getting Started with Nodes in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Mon, 24 Nov 2025 15:39:02 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-with-nodes-in-langgraph-5g45</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-with-nodes-in-langgraph-5g45</guid>
      <description>&lt;p&gt;If you’ve been following our LangGraph series so far, where we’ve toured the basics of LangGraph, peeked into agent state, reducers, add_reducers, graph messages, and even discussed  MCP in LangGraph—you’re probably starting to see a pattern:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything in LangGraph feels modular… almost like LEGO blocks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, today we finally meet the LEGO block itself: &lt;strong&gt;the Node.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;/p&gt;

&lt;p&gt;Learn LangChain in a clear, concise, and practical way.&lt;br&gt;
Whether you’re just starting out or already building, Langcasts gives you guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at Langcasts.com.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think of nodes as the &lt;em&gt;tiny brains&lt;/em&gt; of your graph. Each node is a single step, a decision point, a task, a “do-this-next” moment in your workflow. They just do one job really cleanly, and then pass the baton.&lt;/p&gt;

&lt;p&gt;Whether you’re building a simple two-step agent, a multi-branching “choose-your-own-adventure” assistant, or a full-blown workflow that feels like it should have a boarding pass…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nodes are the building blocks that make your agent predictable, traceable, and honestly… sane.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But here’s the best part: Once you understand what nodes are and how they behave, the rest of your LangGraph journey becomes way clearer.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you’ll be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;spot a node in the wild,&lt;/li&gt;
&lt;li&gt;create your own nodes (yes, you),&lt;/li&gt;
&lt;li&gt;chain them together like a pro,&lt;/li&gt;
&lt;li&gt;and build simple flows that actually make sense.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Exactly Is a Node in LangGraph?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A node is just a function or an LLM call that transforms your &lt;strong&gt;state&lt;/strong&gt; and moves your graph forward.&lt;/p&gt;

&lt;p&gt;Let’s break that down.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Nodes vs Edges vs State&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Node → *Where something happens&lt;/strong&gt;*&lt;/p&gt;

&lt;p&gt;A function runs. An LLM thinks. A check is made.&lt;/p&gt;

&lt;p&gt;This is the action.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Edge → *How you move to the next thing&lt;/strong&gt;*&lt;/p&gt;

&lt;p&gt;It’s the arrow that says:&lt;/p&gt;

&lt;p&gt;“After this… go there.”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;State → *The backpack your agent carries around&lt;/strong&gt;*&lt;/p&gt;

&lt;p&gt;Everything your workflow needs to remember — user messages, results, flags, decisions, whatever.&lt;/p&gt;

&lt;p&gt;Each node can update this backpack or use what’s already inside.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've read the earlier guide on &lt;strong&gt;agent state&lt;/strong&gt; then you already know how state behaves. Nodes are simply the actors that read the state, use it, update it, and pass it along.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;So What Makes LangGraph Nodes Special?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Well… &lt;strong&gt;they’re predictable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every node knows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What comes in (state).&lt;/li&gt;
&lt;li&gt;What it’s supposed to do (your logic).&lt;/li&gt;
&lt;li&gt;What comes out (updated state).&lt;/li&gt;
&lt;li&gt;Where to go next (edges).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes your workflow easier to debug, visualize, maintain, and way easier to extend as your agents get smarter.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Types of Nodes You’ll Encounter&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you know what a node &lt;em&gt;is&lt;/em&gt;, let’s talk about the different types you’ll meet in LangGraph.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Callable Nodes (a.k.a. Your Normal Functions)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;These are the simplest, most predictable nodes.&lt;/p&gt;

&lt;p&gt;A callable node is basically:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Hey LangGraph, when the workflow gets here, run this function.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It could be formatting a message, fetching data, doing a calculation, or updating state in a very specific way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use these when:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You want clear, deterministic logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Agent Nodes (LLM Nodes)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;These are the “thinkers” in your workflow — the nodes where the LLM gets to reason, respond, or decide what happens next.&lt;/p&gt;

&lt;p&gt;Think of an LLM node as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“You handle the thinking; I’ll handle the routing.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An agent node usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reads the current state (like messages),&lt;/li&gt;
&lt;li&gt;calls the LLM,&lt;/li&gt;
&lt;li&gt;returns the next message/state update.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’ve read my earlier article on &lt;strong&gt;graph messages&lt;/strong&gt;, this is where that knowledge becomes super useful. LLM nodes depend heavily on message formatting and understanding how messages flow through the graph.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use these when:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You want natural language reasoning or model-based decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Conditional Nodes (Branching Logic)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;These nodes decide &lt;em&gt;which&lt;/em&gt; next node to jump to based on the state.&lt;/p&gt;

&lt;p&gt;Imagine you're building a customer support bot. The conditional node might ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Is the user asking about billing?” → go to billing flow&lt;/li&gt;
&lt;li&gt;“Is the user asking about refunds?” → go to refund flow&lt;/li&gt;
&lt;li&gt;“Is the user confused?” → send a human-friendly clarification node&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These nodes make your workflow smart — not everything has to be linear.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use these when:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your agent needs to choose between multiple paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Parallel Nodes (Fan-Out / Fan-In)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;These are the “multitaskers”. They allow you to split your workflow into multiple branches that run side by side before merging the results.&lt;/p&gt;

&lt;p&gt;For example, they can help you &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyze text&lt;/li&gt;
&lt;li&gt;Fetch related documents&lt;/li&gt;
&lt;li&gt;Generate summaries&lt;/li&gt;
&lt;li&gt;…and then combine everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of parallel nodes as LangGraph saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why do this one by one when we can do them all at once?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Use these when:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You want speed, efficiency, or multiple data sources combined.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;A Quick Recap (Like a Cheat Sheet)&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Node Type&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;th&gt;When to Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Callable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runs a normal Python function&lt;/td&gt;
&lt;td&gt;Pure logic, utilities, transforms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent / LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lets the model think or respond&lt;/td&gt;
&lt;td&gt;Reasoning, writing, decisions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Conditional&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Branches workflow based on state&lt;/td&gt;
&lt;td&gt;Routing, decision trees&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Parallel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runs multiple branches at once&lt;/td&gt;
&lt;td&gt;Multi-source workflows, speed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;Once you understand the role of each, designing robust workflows becomes a breeze.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Anatomy of a Node&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before we start creating nodes and connecting them, let’s zoom in and look at what actually makes up a node.&lt;/p&gt;

&lt;p&gt;A node in LangGraph is made of &lt;strong&gt;three core ingredients&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Input (State Coming In)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Logic (What the node does)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Output (State Going Out)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;…and then a little “map” that tells LangGraph where to go next.&lt;/p&gt;

&lt;p&gt;Let’s break that down.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Input: What the Node Receives&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every time your workflow enters a node, LangGraph passes in the current &lt;strong&gt;state&lt;/strong&gt;. It holds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user messages,&lt;/li&gt;
&lt;li&gt;previous results,&lt;/li&gt;
&lt;li&gt;flags,&lt;/li&gt;
&lt;li&gt;memory,&lt;/li&gt;
&lt;li&gt;whatever your agent needs to make decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A node doesn’t need to use everything; it just pulls out the item(s) it cares about.&lt;/p&gt;

&lt;p&gt;Think of it like opening your fridge — you're not using all the food, you’re just grabbing what you need for this step.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Logic: The Heart of the Node&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The logic is the &lt;strong&gt;function&lt;/strong&gt;, &lt;strong&gt;LLM call&lt;/strong&gt;, or &lt;strong&gt;branching rule&lt;/strong&gt; that defines what the node actually &lt;em&gt;does&lt;/em&gt;. This could be, calling OpenAI or Anthropic, looking something up, updating messages, deciding which route to take, or merging results.&lt;/p&gt;

&lt;p&gt;This logic is the “why” of the node — its purpose.&lt;/p&gt;

&lt;p&gt;If you read my earlier pieces on &lt;strong&gt;reducers&lt;/strong&gt; and &lt;strong&gt;state updates&lt;/strong&gt;, you’ll notice that node logic often results in new data being produced, which your reducers then merge into the global state.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Output: What the Node Produces&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;After the logic runs, the node spits out something new — usually part of the state. LangGraph takes this result, merges it into the state (thanks to reducers), and carries the updated backpack forward to the next node.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Edges: The Next Step&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is the part beginners often overlook.&lt;/p&gt;

&lt;p&gt;A node doesn’t live alone in the void — it needs edges to tell LangGraph:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Where to go next?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Which node should follow this one?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Is this a normal transition or a conditional one?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Are we branching or looping?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of edges as the arrows in a flowchart.&lt;/p&gt;

&lt;p&gt;Without edges, even the smartest node has nowhere to send its results.&lt;/p&gt;

&lt;p&gt;Nodes &lt;strong&gt;do the work&lt;/strong&gt;, Edges &lt;strong&gt;define the journey&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Simple Diagram Showing How a Node Works in LangGraph&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;           ┌─────────────────────────┐
           │        STATE IN          │
           │   (Your agent's memory)  │
           └─────────────┬───────────┘
                         │
                         ▼
               ┌───────────────────┐
               │      NODE         │
               │  (One Step/Task)  │
               │                   │
               │ • Reads State     │
               │ • Runs Logic      │
               │ • Produces Output │
               └───────────┬───────┘
                           │
                           ▼
           ┌─────────────────────────┐
           │       STATE OUT         │
           │ (Updated by Reducers)   │
           └─────────────┬───────────┘
                         │
                         ▼
                ┌─────────────────┐
                │     NEXT NODE   │
                └─────────────────┘

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And once you understand this anatomy, designing workflows becomes almost addictive.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Creating and Connecting Your First Nodes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you understand what nodes &lt;em&gt;are&lt;/em&gt;, it’s time to actually &lt;strong&gt;build&lt;/strong&gt; them — and then &lt;strong&gt;connect&lt;/strong&gt; them to create a real workflow.&lt;/p&gt;

&lt;p&gt;Let’s walk through it step by step.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Start With a Simple Function&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every node begins life as a small Python function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;! Welcome to LangGraph.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reads something from state&lt;/li&gt;
&lt;li&gt;returns something new&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Turn That Function Into a Node&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next, we register it inside a graph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Graph&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Graph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;greet_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have your &lt;strong&gt;first node&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;LangGraph knows: “When the workflow hits &lt;code&gt;greet_node&lt;/code&gt;, run the &lt;code&gt;greet&lt;/code&gt; function.”&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Add Another Node (Optional)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s add a second node that transforms the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;shout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shouted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shout_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4: Connect the Nodes Together&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Nodes aren’t useful in isolation, they’re meant to flow.&lt;/p&gt;

&lt;p&gt;Connecting them is just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;greet_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shout_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your workflow looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[greet_node] → [shout_node]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LangGraph now understands:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“After greeting, jump to shouting.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is called &lt;strong&gt;a linear workflow&lt;/strong&gt;, and it’s the foundation of everything else you’ll build.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 5: Run Your Mini-Workflow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s try it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;input_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dami&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sample output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dami&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, Dami! Welcome to LangGraph.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shouted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HELLO, DAMI! WELCOME TO LANGGRAPH.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations — you just built a functioning LangGraph pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Connecting Nodes in Interesting Ways&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Linear flows are great, but LangGraph becomes powerful when you start using different connection patterns. Let’s explore the essentials.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;1. Linear Chains (The Classic Flow)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A → B → C → D

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;format_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;format_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llm_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llm_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;save_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;save_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect for simple pipelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Conditional Routing (Decision-Based Workflow)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s say your agent detects user intent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                   billing_flow
                 ↗
[intent_node] —──┤
                 ↘
                   refund_flow

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intent_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;billing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;billing_flow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;refund&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;refund_flow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;other&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fallback_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One node → multiple possible next steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Loops (Repeating a Step Until Ready)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Yes, you can loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;refine_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;refine_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Loops are super useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLM refinement&lt;/li&gt;
&lt;li&gt;multi-turn reasoning&lt;/li&gt;
&lt;li&gt;repeated checking&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Parallel Branching (Fan-Out + Merge)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Split work into multiple paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             ┌──→ branch_A
start_node ──┤
             └──→ branch_B

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And merge later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;branch_A
        ↘
         merge_node
        ↗
branch_B

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;branch_A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;branch_B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;branch_A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merge_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;branch_B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merge_node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect for tasks that can run simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/QbSPbILWIPw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why This Matters&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Once you know how to &lt;strong&gt;create&lt;/strong&gt; and &lt;strong&gt;connect&lt;/strong&gt; nodes, you unlock the ability to design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chatbots with reasoning flows&lt;/li&gt;
&lt;li&gt;structured workflows&lt;/li&gt;
&lt;li&gt;agentic pipelines&lt;/li&gt;
&lt;li&gt;tool-calling systems&lt;/li&gt;
&lt;li&gt;data processing chains&lt;/li&gt;
&lt;li&gt;multi-agent multi-step applications&lt;/li&gt;
&lt;li&gt;anything that benefits from clarity and controlled execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LangGraph doesn’t force you into one pattern, it hands you LEGO blocks and says: &lt;strong&gt;Build whatever you want — cleanly.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running and Visualizing Your Node Chain
&lt;/h2&gt;

&lt;p&gt;You’ve built your nodes. You’ve connected them. Now it’s time for the part everyone loves: &lt;strong&gt;running the graph and actually seeing how everything flows.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Running the Graph (The “Just Hit Play” Moment)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once your graph is compiled, running it is as easy as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;runnable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;runnable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dami&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, LangGraph walks your flow step-by-step, updates the state after each node, and hands you the final result.&lt;/p&gt;

&lt;p&gt;If you’ve chained multiple nodes, you’ll see all the accumulated state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;validated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello Dami! Welcome to LangGraph 🎉&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Visualizing Your Graph (Your Workflow, but as a Map)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;LangGraph comes with built-in visualization, which is perfect when your graph starts growing beyond a few nodes.&lt;/p&gt;

&lt;p&gt;Just call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll get a neat diagram showing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each node in your flow&lt;/li&gt;
&lt;li&gt;How they connect&lt;/li&gt;
&lt;li&gt;The direction of execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s like going from “I hope this works” to “Ah, now I see how everything fits.”&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Why Visualization Matters (Especially for Beginners)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you’re new to LangGraph, diagrams help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spot mistakes early (hello, missing edges 👀)&lt;/li&gt;
&lt;li&gt;Understand your flow at a glance&lt;/li&gt;
&lt;li&gt;Explain your graph to teammates—or future you&lt;/li&gt;
&lt;li&gt;Keep your mental model tight as the workflow grows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LangGraph’s visualization is especially helpful once you start mixing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conditionals&lt;/li&gt;
&lt;li&gt;Tool nodes&lt;/li&gt;
&lt;li&gt;LLM calls&lt;/li&gt;
&lt;li&gt;Multiple branching paths&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But even with a simple 2–3 node chain, seeing it makes a world of difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up: You’ve Just Built Your First LangGraph Node Flow
&lt;/h2&gt;

&lt;p&gt;And that’s a solid win.&lt;/p&gt;

&lt;p&gt;You came in knowing nodes were “a thing in LangGraph,” and you’re leaving with an understanding of what they are, how to create them, how to chain them, and how to visualize your workflow. That’s the core of almost every LangGraph project—whether you’re building a simple helper bot or a multi-agent system with branching logic and tools flying everywhere.&lt;/p&gt;

&lt;p&gt;At this point in the LangGraph series, you should be feeling more confident about the building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;State&lt;/strong&gt; (covered earlier in the series)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reducers&lt;/strong&gt; (your quiet state-updating heroes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Messages &amp;amp; MCP&lt;/strong&gt; (communication superpowers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;And now—Nodes&lt;/strong&gt; (the actions that make everything move)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they form the foundation for more advanced patterns we’ll explore next.&lt;/p&gt;

&lt;p&gt;If this clicked for you, amazing.&lt;/p&gt;

&lt;p&gt;If it sparked new ideas, even better.&lt;/p&gt;

&lt;p&gt;Keep experimenting, keep connecting nodes, and keep building smarter graphs.&lt;/p&gt;

&lt;p&gt;Your next workflow is just a node away.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Using MCP with LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Sun, 16 Nov 2025 23:28:22 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-using-mcp-with-langgraph-2fg5</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-using-mcp-with-langgraph-2fg5</guid>
      <description>&lt;p&gt;If you’ve been following along with the LangGraph series, you already know how powerful structured, stateful workflows can be for building real AI agents. But there’s one question every developer eventually runs into:&lt;/p&gt;

&lt;p&gt;“How do I let my agent interact with real-world tools and data?”&lt;/p&gt;

&lt;p&gt;That’s where MCP — Model Context Protocol — steps in.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;/p&gt;

&lt;p&gt;Learn LangChain in a clear, concise, and practical way.&lt;br&gt;
Whether you’re just starting out or already building, Langcasts gives you guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at Langcasts.com.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;MCP is a new open standard that gives AI models a clean, safe, predictable way to access external tools, APIs, files, and more. Instead of writing custom integrations for every single tool, MCP gives you one universal format that everything can plug into.&lt;/p&gt;

&lt;p&gt;And here’s the best part:&lt;br&gt;
LangGraph supports MCP natively.&lt;br&gt;
This means your graph nodes can call MCP tools as easily as they call other functions.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll walk through the basics of MCP inside LangGraph.&lt;br&gt;
We’ll keep things simple.&lt;br&gt;
We’ll build something small.&lt;br&gt;
And by the end, you’ll understand how to use MCP to make your LangGraph agents more capable, more useful, and much more practical.&lt;br&gt;
Ready? Let’s get into it.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Core Concepts You Need to Know&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before wiring LangGraph and MCP together, there are a few core ideas you need to understand. &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. Graphs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A &lt;em&gt;graph&lt;/em&gt; in LangGraph is simply the map your agent follows.&lt;/p&gt;

&lt;p&gt;It defines &lt;em&gt;how&lt;/em&gt; your agent moves from one step to the next, similar to a workflow, but more intelligent.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;2. Nodes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Nodes are the “stations” in your graph.&lt;/p&gt;

&lt;p&gt;Each node does one thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call an LLM&lt;/li&gt;
&lt;li&gt;Perform logic&lt;/li&gt;
&lt;li&gt;Trigger a tool&lt;/li&gt;
&lt;li&gt;Transform state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the graph is the map, nodes are the stops on the journey.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;3. State&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;State is your agent’s memory.&lt;/p&gt;

&lt;p&gt;It carries everything from messages to tool results to custom variables.&lt;/p&gt;

&lt;p&gt;In LangGraph, state updates automatically flow from node to node, so every part of your agent always sees the latest context.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;4. Actions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Actions are how nodes &lt;em&gt;do&lt;/em&gt; things.&lt;/p&gt;

&lt;p&gt;They’re the outputs that tell LangGraph what happens next, like: “Call this tool”, “Move to that node”, “Update the state”.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;5. MCP Tools&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;MCP tools are capabilities your agent can use, defined outside your code in a separate MCP server.&lt;/p&gt;

&lt;p&gt;These tools come with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structured schemas&lt;/li&gt;
&lt;li&gt;Validated inputs&lt;/li&gt;
&lt;li&gt;Typed responses&lt;/li&gt;
&lt;li&gt;Secure execution rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You expose tools, MCP handles the plumbing, and LangGraph uses them cleanly.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;6. How LangGraph treats MCP tools as callable actions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When a LangGraph node wants to use an MCP tool, it doesn’t “guess” what to do.&lt;/p&gt;

&lt;p&gt;It returns a &lt;strong&gt;tool invocation action&lt;/strong&gt;, and LangGraph knows exactly how to route that call through MCP.&lt;/p&gt;

&lt;p&gt;Your node just says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Please call this tool with this data.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;LangGraph and MCP handle everything else.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;7. How MCP fits into the graph execution model&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here’s the smooth relationship:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LangGraph runs your workflow step-by-step.&lt;/li&gt;
&lt;li&gt;When a node needs external capabilities, it triggers an MCP tool action.&lt;/li&gt;
&lt;li&gt;MCP executes the tool and returns structured data.&lt;/li&gt;
&lt;li&gt;LangGraph folds that result back into the state and continues the graph.
## &lt;strong&gt;Setting Up Your First MCP Environment&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before LangGraph can call MCP tools, you need an MCP environment running. &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. Install the MCP CLI&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You’ll need the official MCP command-line tool to run and test your MCP servers locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @modelcontextprotocol/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you the &lt;code&gt;mcp&lt;/code&gt; command, which you’ll use to run your tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Create a Simple MCP Server&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;An MCP server is just a small program that exposes tools.&lt;/p&gt;

&lt;p&gt;You can start with the basic template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mcp init my-mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates a folder with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A sample tool&lt;/li&gt;
&lt;li&gt;JSON schema files&lt;/li&gt;
&lt;li&gt;Server boilerplate&lt;/li&gt;
&lt;li&gt;A clean structure to build on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open the folder and you’ll already see how tools are defined and validated.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Start Your MCP Server&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Run the development server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mcp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this starts successfully, your MCP environment is live.&lt;/p&gt;

&lt;p&gt;You’ll see logs showing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Available tools&lt;/li&gt;
&lt;li&gt;Their schemas&lt;/li&gt;
&lt;li&gt;When the server receives calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where LangGraph will eventually connect.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Add Your First Tool (Optional for Now)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tools in MCP are just functions wrapped with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input schema (what data they accept)&lt;/li&gt;
&lt;li&gt;Output schema (what they return)&lt;/li&gt;
&lt;li&gt;Execution logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a simple “get-time” tool might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"get_time"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inputSchema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputSchema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"iso"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll later reference these tools by name inside LangGraph.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Connect LangGraph to Your MCP Server&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once your MCP server is running, LangGraph can connect by simply pointing to it in your graph configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPClient&lt;/span&gt;

&lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MCPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom, now your agent can call any tool served by MCP.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Writing Your First LangGraph Node That Calls an MCP Tool&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that your MCP server is up and running, let’s hook it into LangGraph. This is the moment where your agent stops “talking about things” and starts &lt;strong&gt;doing things&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We’ll walk through a simple example: calling an MCP tool from a LangGraph node and feeding the result back into the state.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Import the Essentials&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You only need a few LangGraph and MCP utilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mcp_tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.prebuilt&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MessagesState&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Connect Your LangGraph Project to MCP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Create a client pointing to your running MCP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MCPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives your graph access to every tool the server exposes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Wrap an MCP Tool for LangGraph&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s say your MCP server exposes a tool called &lt;code&gt;"get_time"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You make it callable inside LangGraph like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;get_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mcp_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;get_time&lt;/code&gt; is now a tool action you can call inside any node.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Write a Node That Calls the Tool&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A node just needs to return a tool invocation action.&lt;/p&gt;

&lt;p&gt;Here’s a minimal example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ask_for_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MessagesState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;get_time&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things are happening here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The node receives the current state (messages, history, etc.)&lt;/li&gt;
&lt;li&gt;It doesn’t need extra input for this tool, so we pass an empty dict&lt;/li&gt;
&lt;li&gt;It returns an MCP tool call&lt;/li&gt;
&lt;li&gt;LangGraph takes over from there&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Consume the Tool Result in the Next Node&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;After the tool runs, MCP sends the response back to LangGraph.&lt;/p&gt;

&lt;p&gt;So you create another node to process it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MessagesState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The time is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;iso&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This node reads the last message (the tool’s result) and formats it into a clean assistant reply.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;6. Build the Graph&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now wire everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MessagesState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ask_for_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ask_for_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;show_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;show_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_entry_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ask_for_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ask_for_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;show_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;7. Run It&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What time is it?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your LangGraph agent will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the user’s message&lt;/li&gt;
&lt;li&gt;Run the &lt;code&gt;ask_for_time&lt;/code&gt; node&lt;/li&gt;
&lt;li&gt;Trigger the &lt;code&gt;"get_time"&lt;/code&gt; MCP tool&lt;/li&gt;
&lt;li&gt;Get the structured result&lt;/li&gt;
&lt;li&gt;Pass it into &lt;code&gt;show_time&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Respond with the actual time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/bDaD8YycWjs"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;




&lt;p&gt;You’ve just walked through the essentials of using MCP with LangGraph. From the core concepts, to wiring up tools, to building a real working agent. Even if the details felt new at first, you now understand the big picture: LangGraph handles the workflow, MCP handles the tools, and together they give your agent real capabilities without chaos or guesswork.&lt;/p&gt;

&lt;p&gt;The best part?&lt;br&gt;
You’ve barely scratched the surface.&lt;/p&gt;

&lt;p&gt;Once you’re comfortable with simple tools like file readers or API calls, you can scale up to full workflows, multi-step reasoning, chained tools, or even entire application backends powered by MCP. LangGraph keeps everything structured. MCP keeps everything safe and predictable. The combination gives you a foundation you can build on confidently.&lt;/p&gt;

&lt;p&gt;So take your time, experiment, break things, fix them, and keep going.&lt;br&gt;
This is all part of the fun.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Getting Started with Graph Messages in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Fri, 07 Nov 2025 15:06:43 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-with-graph-messages-in-langgraph-20l9</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-with-graph-messages-in-langgraph-20l9</guid>
      <description>&lt;p&gt;If you’ve been following this LangGraph series, you’ve already learned how to &lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-in-agents-in-langgraph-1gfd"&gt;build agents&lt;/a&gt;, &lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-in-agent-state-in-langgraph-3bkj"&gt;manage their state&lt;/a&gt;, and &lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-with-reducers-in-langgraph-38ii"&gt;use reducers&lt;/a&gt; to control how data flows through your graph. We’ve laid a foundation. But there’s one piece we haven’t zoomed in on yet, the actual &lt;em&gt;messages&lt;/em&gt; moving through your graph.&lt;/p&gt;

&lt;p&gt;Think about it: when you build a chatbot or any conversational agent, what really travels between nodes? It’s not just text, it’s structured data, context, and intent wrapped up as messages. These messages are what keep your graph alive, what make your AI remember what was said before, and what let it respond intelligently the next time around.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Graph Messages&lt;/strong&gt; come in. They’re the glue that connects everything, the courier that carries meaning from one node to another, the thread that ties state and logic together. Without understanding Graph Messages, you’re only scratching the surface of what LangGraph can do.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;/p&gt;

&lt;p&gt;Learn LangChain in a clear, concise, and practical way.&lt;/p&gt;

&lt;p&gt;Whether you’re just starting out or already building, Langcasts gives you guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at &lt;a href="https://www.langcasts.com/" rel="noopener noreferrer"&gt;Langcasts.com.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this guide, we’ll take a beginner-friendly look at how Graph Messages work inside LangGraph. You’ll see how they fit into the bigger picture you’ve already built in this series, and how mastering them will make your conversational agents smarter, more reliable, and a lot easier to reason about.&lt;/p&gt;

&lt;p&gt;Ready to see how messages actually move through your LangGraph? Let’s break it down.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Core Concept — What Are Graph Messages?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before we get into the code, let’s strip the concept down to its essence.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Graph Message&lt;/strong&gt; in LangGraph is simply how information moves between nodes in your graph. Each node in your LangGraph setup does something, maybe it generates text, analyzes sentiment, or calls an API. But nodes don’t exist in isolation. They need a way to talk to each other. That’s what messages are for.&lt;/p&gt;

&lt;p&gt;It might contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user’s input (HumanMessage)&lt;/li&gt;
&lt;li&gt;The model’s response (AIMessage)&lt;/li&gt;
&lt;li&gt;The current context or memory (ToolMessage)&lt;/li&gt;
&lt;li&gt;Or any other info that your next node needs to do its job (SystemMessage)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In LangGraph, these messages aren’t just free-floating text strings; they’re &lt;strong&gt;typed objects&lt;/strong&gt; that keep your workflow organized and predictable. Each message carries both content and metadata, so your graph knows &lt;em&gt;what kind of data&lt;/em&gt; it’s handling and &lt;em&gt;where it came from.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here’s a simple mental model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Nodes process. Edges are the routes. Messages move.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why does this matter? Because when you start building more advanced graphs, like chatbots that remember past turns, the way you handle and store these messages determines how well your system holds context over time. Mismanage messages, and your agent forgets its own history. Handle them right, and you get smooth, intelligent, multi-turn conversations. Now that we seem to have got the hang of Messages in Graph State, let's set up our LangGraph.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Setting Up Your First LangGraph Project&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you’ve got a handle on what Graph Messages are, let’s get your hands dirty with a simple example.&lt;/p&gt;

&lt;p&gt;Before we start, make sure you’ve got LangGraph installed. If not, just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langgraph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LangGraph projects usually follow a simple pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define your state&lt;/strong&gt; — this is the shared data that moves through the graph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create your nodes&lt;/strong&gt; — each node is just a Python function that does something with that state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect the nodes with edges&lt;/strong&gt; — these determine how the workflow moves from one node to the next.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compile and run your graph&lt;/strong&gt; — this “wires” everything together so LangGraph can handle message passing behind the scenes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s the smallest possible working example to see message flow in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing_extensions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Define the state
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GraphState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Create nodes
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;collect_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GraphState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Node: collect_input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, LangGraph!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GraphState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Node: generate_response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; Nice to meet you.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Build and connect the graph
&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GraphState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;collect_input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;collect_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generate_response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generate_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;collect_input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;collect_input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generate_response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generate_response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Compile and run
&lt;/span&gt;&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What’s happening here?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;collect_input&lt;/strong&gt; node sends out a message containing the &lt;code&gt;user_input&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;That message travels along the edge to the &lt;strong&gt;generate_response&lt;/strong&gt; node.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;generate_response&lt;/strong&gt; node reads the incoming message, updates the &lt;code&gt;response&lt;/code&gt;, and sends its message forward.&lt;/li&gt;
&lt;li&gt;Once there are no more messages to deliver, the graph stops, and you get your result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even in this small demo, you can see how the data (or message) moves between nodes and evolves along the way.&lt;/p&gt;

&lt;p&gt;Behind the scenes, LangGraph handles the message-passing logic automatically. You just define what each node should do and how they connect, and LangGraph does the rest.&lt;/p&gt;

&lt;p&gt;Next, we’ll dive into how you can &lt;strong&gt;create and manage messages&lt;/strong&gt; yourself, including how to store message history and keep your chatbot’s memory intact.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Creating and Passing Graph Messages&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;So far, we’ve seen messages move quietly behind the scenes, nodes sending and receiving state as the graph runs.&lt;/p&gt;

&lt;p&gt;But when you’re building a &lt;strong&gt;chatbot&lt;/strong&gt; or any agent that needs memory, you’ll often need to &lt;strong&gt;create, store, and manage those messages&lt;/strong&gt; yourself.&lt;/p&gt;

&lt;p&gt;That’s where LangGraph’s message system really shines.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Messages Are the Memory Backbone&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every turn in a conversation — user input, AI response, or system message — becomes part of the graph’s evolving state.&lt;/p&gt;

&lt;p&gt;If you don’t manage those properly, your chatbot loses context with every new message.&lt;/p&gt;

&lt;p&gt;LangGraph solves this neatly with two built-in tools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;add_messages&lt;/code&gt; reducer&lt;/strong&gt; – for appending new messages to your state without overwriting old ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;MessagesState&lt;/code&gt; helper class&lt;/strong&gt; – a shortcut for setting up message storage in your graph automatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Using &lt;code&gt;MessagesState&lt;/code&gt; — The Quick Way&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If your project is all about managing chat history, the easiest path is to use &lt;code&gt;MessagesState&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It sets up your graph state with a &lt;code&gt;messages&lt;/code&gt; key and automatically configures the &lt;code&gt;add_messages&lt;/code&gt; reducer for you.&lt;/p&gt;

&lt;p&gt;Here’s a minimal example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MessagesState&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.reducers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chat_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MessagesState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;last_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You said: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;last_message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MessagesState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chat_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]})&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s what’s going on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user sends a message — LangGraph wraps it as part of the graph’s state.&lt;/li&gt;
&lt;li&gt;The node reads that message, builds a response, and returns a new message.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;add_messages&lt;/code&gt; reducer kicks in automatically, &lt;strong&gt;appending&lt;/strong&gt; the new message to the conversation history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now your chatbot remembers previous messages — no custom memory logic, no manual state juggling.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When You Need Custom State&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you want to include extra fields (like user data or conversation mode), you can define your own state and annotate it with the &lt;code&gt;add_messages&lt;/code&gt; reducer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing_extensions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.reducers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="n"&gt;ChatState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChatState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets you mix chat history with other useful data, and still keep message updates automatic and reliable.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/TpgQlRsQPG8"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Debugging and Inspecting Messages&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When your graph starts to grow beyond a few nodes, things can get fuzzy fast.&lt;/p&gt;

&lt;p&gt;Messages fly around, reducers run quietly, and before you know it, your chatbot starts “forgetting” things or producing strange responses.&lt;/p&gt;

&lt;p&gt;That’s your cue to &lt;strong&gt;inspect what’s actually happening&lt;/strong&gt; inside your graph.&lt;/p&gt;

&lt;p&gt;Fortunately, LangGraph gives you a few simple ways to peek inside and trace message flow step by step.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Printing Message State (the Quick Way)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The easiest way to understand what’s going on is to just &lt;strong&gt;print the state&lt;/strong&gt; your nodes receive and return.&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chat_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MessagesState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;--- Incoming State ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;last_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You said: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;last_message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;--- Outgoing State ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;}]})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might feel basic, but when you’re just starting out, it’s often the most revealing approach.&lt;/p&gt;

&lt;p&gt;You can literally watch your graph evolve message by message.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Using &lt;code&gt;graph.inspect()&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;LangGraph includes a handy inspection feature that lets you &lt;strong&gt;run your graph interactively&lt;/strong&gt; and see the flow between nodes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This displays how your graph processes input, which nodes get activated, and how messages change as they pass through the system.&lt;/p&gt;

&lt;p&gt;It’s a quick sanity check when your state isn’t updating the way you expect.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Common Gotchas and Fixes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here are a few message-related bugs you’ll probably run into — and how to fix them fast:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Likely Cause&lt;/th&gt;
&lt;th&gt;Quick Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Your chatbot “forgets” the conversation&lt;/td&gt;
&lt;td&gt;You overwrote &lt;code&gt;messages&lt;/code&gt; instead of appending&lt;/td&gt;
&lt;td&gt;Use the &lt;code&gt;add_messages&lt;/code&gt; reducer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graph stops after one node&lt;/td&gt;
&lt;td&gt;Missing edge or wrong node name&lt;/td&gt;
&lt;td&gt;Double-check your edge definitions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Messages are duplicated&lt;/td&gt;
&lt;td&gt;Returning full state instead of partial update&lt;/td&gt;
&lt;td&gt;Return only the fields you changed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node never runs&lt;/td&gt;
&lt;td&gt;No incoming message&lt;/td&gt;
&lt;td&gt;Make sure a previous node actually returns something&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Verify Message Flow Early&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When your graph is still small, trace message flow early and often.&lt;/p&gt;

&lt;p&gt;Print your state, run &lt;code&gt;inspect()&lt;/code&gt;, and verify that each node gets the right data.&lt;/p&gt;

&lt;p&gt;Catching issues at this stage saves you from debugging a tangle of nodes later.&lt;/p&gt;




&lt;p&gt;At the end of the day, &lt;strong&gt;debugging in LangGraph is about visibility&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you can see how messages move, you can reason about your graph.&lt;/p&gt;

&lt;p&gt;Once you understand your message flow, fixing bugs and scaling up become much simpler.&lt;/p&gt;




&lt;p&gt;If you’ve been following this LangGraph series from the start, you’ve now connected all the dots, from &lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-in-agents-in-langgraph-1gfd"&gt;agents&lt;/a&gt; to &lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-in-agent-state-in-langgraph-3bkj"&gt;state&lt;/a&gt; to &lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-with-reducers-in-langgraph-38ii"&gt;reducers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But here’s the key takeaway: &lt;strong&gt;Graph Messages are the lifeblood of it all.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They’re what connect your nodes, carry your state, and bring your AI workflows to life.&lt;/p&gt;

&lt;p&gt;LangGraph’s message-passing system, powered by the &lt;code&gt;add_messages&lt;/code&gt; reducer and the &lt;code&gt;MessagesState&lt;/code&gt; helper, gives you a simple way to manage complexity.&lt;/p&gt;

&lt;p&gt;If you haven’t already, watch the &lt;a href="https://youtu.be/TpgQlRsQPG8?si=phAUs8dVJcLLYSf9" rel="noopener noreferrer"&gt;YouTube demo&lt;/a&gt; to see messages in action, then try adding them to your next LangGraph project.&lt;/p&gt;

&lt;p&gt;Ready to start your AI journey? Don’t wait — join a class at &lt;a href="http://langcasts.com/" rel="noopener noreferrer"&gt;Langcasts.com&lt;/a&gt; and start building smarter today.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Getting Started with add_messages Reducer in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Fri, 31 Oct 2025 08:35:32 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-with-addmessages-reducer-in-langgraph-4gk0</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-with-addmessages-reducer-in-langgraph-4gk0</guid>
      <description>&lt;p&gt;If you’ve already spent some time exploring &lt;strong&gt;LangGraph&lt;/strong&gt; and how &lt;strong&gt;reducers&lt;/strong&gt; manage state, you’re probably starting to see how everything fits together.&lt;/p&gt;

&lt;p&gt;But there’s one reducer you’ll use more than any other, &lt;code&gt;add_messages&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This one is the workhorse behind your agent’s memory. Every time your AI sends or receives a message, &lt;code&gt;add_messages&lt;/code&gt; quietly steps in to update the conversation history and keep everything in sync.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;/p&gt;

&lt;p&gt;Learn LangChain the clear, concise, and practical way.&lt;br&gt;
Whether you’re just starting out or already building, Langcasts gives you guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at &lt;a href="https://www.langcasts.com/" rel="noopener noreferrer"&gt;Langcasts.com.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this quick guide, we’ll walk through what &lt;code&gt;add_messages&lt;/code&gt; does, how it works, and how to use it to manage message flow in your LangGraph projects.&lt;/p&gt;

&lt;p&gt;If you’re totally new to LangGraph or reducers, check out these two quick reads first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/aiengineering/introduction-to-langgraph-505f"&gt;Introduction to LangGraph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-with-reducers-in-langgraph-38ii"&gt;A Beginner’s Guide to Reducers in LangGraph&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Otherwise, let’s jump right into how &lt;code&gt;add_messages&lt;/code&gt; actually keeps your agent’s conversations alive.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;add_messages&lt;/code&gt; Does
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;add_messages&lt;/code&gt;&lt;/strong&gt; is a built-in &lt;strong&gt;LangGraph reducer&lt;/strong&gt; that updates your agent’s message history by adding new messages to the existing state.&lt;/p&gt;

&lt;p&gt;That’s it. No magic, just a clean way to keep track of every message in a conversation so your agent remembers what’s already happened.&lt;/p&gt;

&lt;p&gt;You can think of it as your agent’s note-taker.&lt;/p&gt;

&lt;p&gt;Every time someone speaks — whether it’s the user, the assistant, or a system message,  &lt;code&gt;add_messages&lt;/code&gt; records that message in order so the context stays consistent.&lt;/p&gt;

&lt;p&gt;In LangGraph, a message is just a small dictionary that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you use &lt;code&gt;add_messages&lt;/code&gt;, it takes your current list of messages and appends the new one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Before&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="n"&gt;After&lt;/span&gt; &lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How are you?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How are you?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This small reducer is what helps your LangGraph agent maintain the flow of a conversation. Without it, each new message would feel like starting from scratch.&lt;/p&gt;

&lt;p&gt;Next, we’ll look at &lt;strong&gt;how &lt;code&gt;add_messages&lt;/code&gt; actually works&lt;/strong&gt; and what happens behind the scenes when it updates your graph’s state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Under the Hood: How It Works
&lt;/h2&gt;

&lt;p&gt;Now that you know what &lt;code&gt;add_messages&lt;/code&gt; does, let’s see how it works behind the scenes.&lt;/p&gt;

&lt;p&gt;When you call &lt;code&gt;add_messages&lt;/code&gt;, two things happen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It looks at the current state of your LangGraph agent.&lt;/li&gt;
&lt;li&gt;It appends new messages to the existing message list.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You give it a state and a message or list of messages, and it returns a new state with those messages added in.&lt;/p&gt;

&lt;p&gt;Nothing fancy, just clean state management that makes conversation tracking reliable.&lt;/p&gt;

&lt;p&gt;Here’s a quick example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.reducers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;

&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]}&lt;/span&gt;

&lt;span class="n"&gt;new_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, AI!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hello, AI!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you add another message, it simply builds on the previous one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;next_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;new_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi there! How can I help you?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hello, AI!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hi there! How can I help you?&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;add_messages&lt;/code&gt;&lt;/strong&gt; always appends new entries while keeping the existing conversation intact.&lt;/p&gt;

&lt;p&gt;This makes it perfect for agents that need to remember context across multiple turns.&lt;/p&gt;

&lt;p&gt;Next, we’ll walk through how to &lt;strong&gt;use &lt;code&gt;add_messages&lt;/code&gt; in a real LangGraph workflow&lt;/strong&gt; and see where it fits in when building an agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using &lt;code&gt;add_messages&lt;/code&gt; in Your LangGraph Workflow
&lt;/h2&gt;

&lt;p&gt;You’ve seen what &lt;code&gt;add_messages&lt;/code&gt; does in isolation. Now let’s see how it fits inside a typical LangGraph setup.&lt;/p&gt;

&lt;p&gt;In most cases, you use &lt;code&gt;add_messages&lt;/code&gt; inside a workflow or node that handles interactions between the user and the model. Each time a message is generated or received, the reducer updates the agent’s state to include the new message.&lt;/p&gt;

&lt;p&gt;Here’s a simple example that shows how it comes together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.reducers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;

&lt;span class="c1"&gt;# Step 1: Create a simple state graph
&lt;/span&gt;&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Step 2: Define the initial state
&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]}&lt;/span&gt;

&lt;span class="c1"&gt;# Step 3: Add a user message
&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tell me a joke.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Step 4: Add the assistant's reply
&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Why did the scarecrow win an award? Because he was outstanding in his field!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tell me a joke.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Why did the scarecrow win an award? Because he was outstanding in his field!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example shows how &lt;code&gt;add_messages&lt;/code&gt; quietly keeps your agent’s conversation up to date. Each new message builds on the previous state, which allows LangGraph to maintain context between turns.&lt;/p&gt;

&lt;p&gt;You can also use &lt;code&gt;add_messages&lt;/code&gt; in custom nodes, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_user_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Add the user's message
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By including &lt;code&gt;add_messages&lt;/code&gt; inside a node or after each model response, you ensure that your agent always has a complete record of the conversation to work with.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/AgcVn5hVtIU"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;Next, we’ll look at &lt;strong&gt;where &lt;code&gt;add_messages&lt;/code&gt; shines&lt;/strong&gt; and the kinds of problems it solves best in LangGraph workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where &lt;code&gt;add_messages&lt;/code&gt; Shines
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;add_messages&lt;/code&gt; might look simple, but it’s one of the most useful reducers in LangGraph. It plays a key role in keeping your agent’s state consistent and your conversations coherent.&lt;/p&gt;

&lt;p&gt;Here are a few places where it really shines:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Conversation Tracking&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every message that comes in or goes out needs to be stored somewhere. &lt;code&gt;add_messages&lt;/code&gt; handles that automatically, keeping a running log of the entire exchange.&lt;/p&gt;

&lt;p&gt;This allows your agent to access past messages and use them for context when generating a response.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Memory Management&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When paired with memory systems or message filters, &lt;code&gt;add_messages&lt;/code&gt; becomes the foundation for long-term conversation handling.&lt;/p&gt;

&lt;p&gt;It helps your agent “remember” earlier parts of a chat without you having to manually manage lists or indexes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Multi-Node Workflows&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In larger LangGraph setups with several nodes (for example, separate reasoning, planning, and responding nodes), &lt;code&gt;add_messages&lt;/code&gt; keeps all message history synchronized.&lt;/p&gt;

&lt;p&gt;No matter which node adds a message, the full state stays aligned across the graph.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Debugging and Transparency&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Since all messages are stored in a structured list, it’s easy to inspect your agent’s message history at any point.&lt;/p&gt;

&lt;p&gt;That makes debugging and tracing behavior much simpler, especially in complex workflows.&lt;/p&gt;




&lt;p&gt;Next, we’ll cover a few &lt;strong&gt;common mistakes and best practices&lt;/strong&gt; so you can use &lt;code&gt;add_messages&lt;/code&gt; effectively without running into problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes and Best Practices
&lt;/h2&gt;

&lt;p&gt;Even though &lt;code&gt;add_messages&lt;/code&gt; is simple to use, a few small mistakes can cause big headaches if you’re not careful. Here are some common pitfalls to watch for, along with a few best practices to keep your message handling clean and reliable.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ &lt;strong&gt;Mistake 1: Overwriting Messages Instead of Appending&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Some beginners accidentally replace the entire message list instead of adding to it.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# Wrong
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wipes out your message history.&lt;/p&gt;

&lt;p&gt;Always let &lt;code&gt;add_messages&lt;/code&gt; handle updates for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;  &lt;span class="c1"&gt;# Correct
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ❌ &lt;strong&gt;Mistake 2: Using the Wrong Message Format&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;LangGraph expects messages to follow a simple structure with &lt;code&gt;role&lt;/code&gt; and &lt;code&gt;content&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you forget one of these keys, the reducer might not behave as expected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Wrong
&lt;/span&gt;&lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Correct
&lt;/span&gt;&lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ✅ &lt;strong&gt;Best Practice 1: Add Multiple Messages at Once When Needed&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re adding several messages, pass them as a list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello there!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps your updates efficient and tidy.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ &lt;strong&gt;Best Practice 2: Keep Message History Manageable&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Over time, long conversations can grow large.&lt;/p&gt;

&lt;p&gt;If your agent doesn’t need all previous messages, consider trimming or summarizing the history before adding new ones. This helps keep performance smooth.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ &lt;strong&gt;Best Practice 3: Use &lt;code&gt;add_messages&lt;/code&gt; Consistently&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Make &lt;code&gt;add_messages&lt;/code&gt; your single source of truth for message updates.&lt;/p&gt;

&lt;p&gt;That consistency prevents bugs and ensures every node or function in your workflow is working from the same conversation record.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;add_messages&lt;/code&gt; might seem small, but it’s a core part of what makes LangGraph conversations work. It quietly keeps your agent’s message history up to date, preserving context and giving your AI the ability to respond naturally across turns.&lt;/p&gt;

&lt;p&gt;You’ve seen how it works, how to use it in a workflow, and how to avoid common mistakes. With this reducer in your toolkit, you can manage conversation flow cleanly and focus on building smarter, more context-aware agents.&lt;/p&gt;

&lt;p&gt;If you’d like to explore further, check out other reducers like &lt;code&gt;set_messages&lt;/code&gt; and &lt;code&gt;clear_messages&lt;/code&gt;, or try creating your own custom reducers for more advanced state control.&lt;/p&gt;

&lt;p&gt;And if you’re just starting your LangGraph journey, these two guides will help fill in any gaps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/aiengineering/introduction-to-langgraph-505f"&gt;Introduction to LangGraph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/aiengineering/a-beginners-guide-to-getting-started-with-reducers-in-langgraph-38ii"&gt;A Beginner’s Guide to Reducers in LangGraph&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that, you’re ready to start using &lt;code&gt;add_messages&lt;/code&gt; in your own LangGraph projects and see your agents come to life one message at a time.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Getting Started with Reducers in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Fri, 24 Oct 2025 12:42:03 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-with-reducers-in-langgraph-38ii</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-with-reducers-in-langgraph-38ii</guid>
      <description>&lt;p&gt;If you’ve been exploring &lt;strong&gt;LangGraph articles series&lt;/strong&gt; lately, you’ve probably noticed that it’s more than just a fancy way to wire up agents and tools. It’s a framework built for control, helping you manage how data, messages, and states flow across your AI system.&lt;/p&gt;

&lt;p&gt;But as your graphs grow, so does the complexity. You might find yourself wondering:&lt;/p&gt;

&lt;p&gt;“How do I combine multiple outputs or keep track of what’s happening across different nodes?”&lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;Reducers&lt;/strong&gt; come in.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we dive in, here’s something you’ll love:&lt;/p&gt;

&lt;p&gt;Learn LangChain the clear, concise, and practical way.&lt;br&gt;
Whether you’re just starting out or already building, Langcasts gives you guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at Langcasts.com.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reducers are the quiet organizers in your LangGraph workflows. They help you take multiple pieces of information,  from agents, nodes, or even message streams, and neatly &lt;em&gt;combine&lt;/em&gt; them into a single, meaningful result. &lt;/p&gt;

&lt;p&gt;In this beginner’s guide, we’ll break down what Reducers are, why they matter, and how to start using them in your LangGraph projects. No complex math, no jargon, just clear explanations and simple examples you can try out right away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Reducers: The Core Idea
&lt;/h2&gt;

&lt;p&gt;Before we jump into code, let’s first get the &lt;em&gt;idea&lt;/em&gt; right.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Reducer&lt;/strong&gt; in LangGraph is a function that takes in multiple inputs, like messages, states, or results from different parts of your graph, and &lt;em&gt;reduces&lt;/em&gt; them into a single, unified output.&lt;/p&gt;

&lt;p&gt;If that sounds abstract, think of it like this:&lt;/p&gt;

&lt;p&gt;“You have three agents each giving different answers to the same question. Instead of picking one randomly, you can use a &lt;strong&gt;Reducer&lt;/strong&gt; to combine their responses into a single, well-rounded answer.”&lt;/p&gt;

&lt;p&gt;In programming terms, Reducers are similar to the &lt;code&gt;reduce()&lt;/code&gt; function you may have seen in JavaScript or Python. They take a list of things and boil them down into one. In LangGraph, this means they can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Merge messages from multiple nodes.&lt;/li&gt;
&lt;li&gt;Summarize outputs from different agents.&lt;/li&gt;
&lt;li&gt;Keep your graph’s state clean and consistent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why does this matter? Because as your workflow grows, you’ll often have multiple branches running at once — and eventually, you’ll need a way to bring everything back together. Reducers make that process simple and predictable.&lt;/p&gt;

&lt;p&gt;So, in short:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Reducer helps your LangGraph workflow make sense of many outputs by turning them into one clear, useful result.&lt;/p&gt;

&lt;p&gt;Up next, let’s see &lt;strong&gt;where Reducers fit&lt;/strong&gt; inside a LangGraph workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where Reducers Fit in LangGraph
&lt;/h2&gt;

&lt;p&gt;So, where exactly do Reducers come into play?&lt;/p&gt;

&lt;p&gt;Think of your LangGraph workflow as a map, data flows from one node to another, sometimes branching into different paths. But at some point, those paths need to come back together. That’s where a &lt;strong&gt;Reducer&lt;/strong&gt; steps in.&lt;/p&gt;

&lt;p&gt;Reducers usually sit &lt;strong&gt;after multiple nodes&lt;/strong&gt; to collect and merge their outputs into one result. You might use one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After several agents respond to the same query.&lt;/li&gt;
&lt;li&gt;To combine outputs from different tools or branches.&lt;/li&gt;
&lt;li&gt;To keep track of the evolving state in looping workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Visually, it’s like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inputs → Node A / Node B / Node C → Reducer → Final Output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short, Reducers are the “glue” that helps your graph stay organized when things start branching out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Your First Reducer
&lt;/h2&gt;

&lt;p&gt;Let’s make this real with a quick example.&lt;/p&gt;

&lt;p&gt;Let's say you have a LangGraph where two nodes (or agents) each return a short response. You want to combine both into one final message. That’s the perfect job for a &lt;strong&gt;Reducer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here’s what that might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Graph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Reducer&lt;/span&gt;

&lt;span class="c1"&gt;# Step 1: Define your reducer function
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;combine_responses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# 'responses' is a list of outputs from previous nodes
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; | &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Step 2: Add it to your graph
&lt;/span&gt;&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Graph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello from agent 1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi from agent 2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Step 3: Use the reducer to merge their outputs
&lt;/span&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Reducer&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;combine_responses&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Step 4: Run the graph
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What’s happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each agent (or node) produces a response.&lt;/li&gt;
&lt;li&gt;The Reducer collects those responses as a list (&lt;code&gt;["Hello from agent 1", "Hi from agent 2"]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Then it merges them using our &lt;code&gt;combine_responses&lt;/code&gt; function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello from agent 1 | Hi from agent 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, right? You can replace that logic with anything, summarizing text, averaging numbers, or combining structured data. The key is that your Reducer takes &lt;strong&gt;many inputs&lt;/strong&gt; and produces &lt;strong&gt;one clean output&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/50goNYRhxFw"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips &amp;amp; Best Practices
&lt;/h2&gt;

&lt;p&gt;Here are a few quick pointers to keep your Reducers clean and effective:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep them simple.&lt;/strong&gt;&lt;br&gt;
A Reducer should do one thing — combine inputs clearly. Don’t overload it with logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use clear names.&lt;/strong&gt;&lt;br&gt;
Functions like &lt;code&gt;merge_answers()&lt;/code&gt; or &lt;code&gt;summarize_history()&lt;/code&gt; make your graphs easier to read and maintain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test Reducers independently.&lt;/strong&gt;&lt;br&gt;
Run them outside the graph first to be sure they handle lists, empty inputs, or unexpected data gracefully.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid hidden state.&lt;/strong&gt;&lt;br&gt;
Let your Reducer depend only on what it receives. This keeps your workflow predictable and easier to debug.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Think of the “why.”&lt;/strong&gt;&lt;br&gt;
Only add a Reducer if it genuinely helps simplify or unify your outputs not just because you can.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Reducers might seem like a small piece of the LangGraph puzzle, but they play a big role in keeping your workflows clean, organized, and efficient. They help your graphs “think clearly”,  by merging scattered outputs into one cohesive result.&lt;/p&gt;

&lt;p&gt;Once you get the hang of Reducers, you’ll find it easier to manage complexity, especially as your projects grow beyond simple, single-path flows.&lt;/p&gt;

&lt;p&gt;So go ahead, try building one, experiment with how it combines data, and see how it transforms your LangGraph workflows.&lt;/p&gt;

&lt;p&gt;Small concept. Big impact.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A Beginner's Guide to Getting Started in Agent State in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Mon, 20 Oct 2025 12:58:45 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-in-agent-state-in-langgraph-3bkj</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-in-agent-state-in-langgraph-3bkj</guid>
      <description>&lt;p&gt;If you’ve been exploring &lt;strong&gt;LangChain&lt;/strong&gt; lately or following our article thread, you’ve probably come across &lt;strong&gt;LangGraph&lt;/strong&gt;. It’s a new framework that lets you build agents that think in steps, follow logical paths, and keep track of what they’ve already done. Instead of chaining prompts together and hoping things work out, LangGraph gives your agent a structure — a clear map of how information moves and changes as it works.&lt;/p&gt;

&lt;p&gt;We’ve already covered the basics of &lt;strong&gt;LangGraph Agents&lt;/strong&gt; in a previous article, where we explained how agents can reason through tasks and coordinate tools. In this piece, we’re going one layer deeper to talk about something that makes those agents truly capable: &lt;strong&gt;state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before we dive in, here’s something you’ll love:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Learn LangChain the clear, concise, and practical way.&lt;/p&gt;

&lt;p&gt;Whether you’re just starting out or already building, Langcasts gives you guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at &lt;a href="https://langcasts.com/" rel="noopener noreferrer"&gt;Langcasts.com&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think of state as your agent’s short-term memory. It’s what keeps track of what has been said, what’s been done, and what comes next. Without it, your agent would forget everything the moment a step finishes. With it, your agent can carry context, recall information, and act with purpose.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll learn what state is, why it matters, and how to use it to build your first stateful agent. We’ll start simple, walk through a hands-on example, and share tips to help you avoid common mistakes. If you prefer to learn visually, you can also check out the LangGraph team’s video on this topic &lt;a href="https://www.youtube.com/watch?v=-kzFiQS2zkQ" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By the end, you’ll know how to make your agent not just respond, but remember and reason through its work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is “State” in LangGraph?
&lt;/h2&gt;

&lt;p&gt;In simple terms, &lt;strong&gt;state is the data your agent keeps track of as it runs&lt;/strong&gt;. It’s everything your agent knows at a given moment — the current input, the tools it has used, what it has said, and what it still needs to do.&lt;/p&gt;

&lt;p&gt;Imagine your agent as a person solving a problem step by step. Each time they finish a task, they make a quick note before moving on — that note is the state. It helps them remember what just happened so they can make the next move intelligently.&lt;/p&gt;

&lt;p&gt;LangGraph uses this same idea. Every time your agent completes an action, the state gets updated. That update becomes the foundation for whatever comes next. Without it, your agent would start every step as if it had no history, no context, and no clue what it was doing before.&lt;/p&gt;

&lt;p&gt;In LangGraph, state is a &lt;strong&gt;structured object&lt;/strong&gt;. You define it yourself, usually as a simple Python class or dictionary. This makes it flexible and transparent. You decide what to store: maybe it’s the conversation history, a running summary, or a few key variables. LangGraph then passes that state between nodes in your workflow, keeping everything connected and consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Concepts You Should Know
&lt;/h2&gt;

&lt;p&gt;A few core ideas that make LangGraph work. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;State Schema&lt;/strong&gt;
The state schema is the blueprint for your agent’s memory. It defines what kind of data your state holds, things like user messages, results from tools, or progress markers. You can create this schema using Python’s &lt;code&gt;TypedDict&lt;/code&gt;, &lt;code&gt;dataclass&lt;/code&gt;, or Pydantic models. Keeping it structured helps you stay organized and makes debugging easier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Reducer:&lt;/strong&gt;The reducer is a function that dictates &lt;strong&gt;how&lt;/strong&gt; a new piece of data returned by a node combines with the existing data in the state. For example, for a conversation history, the reducer ensures new messages are &lt;strong&gt;appended&lt;/strong&gt; to the list, not overwritten. If you don't define one, the old data is simply replaced by the new data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nodes&lt;/strong&gt;
A node is a single step in your agent’s workflow. Each node takes the current state as input, performs some logic, like calling an LLM, running a tool, or making a decision, and then &lt;strong&gt;returns an updated dictionary of the state&lt;/strong&gt;. You can think of nodes as the individual actions your agent takes while moving through its process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edges&lt;/strong&gt;
Edges connect the nodes. They define how the workflow moves from one node to another. Sometimes this path is simple—one node always leads to the next. Other times it’s conditional, where the agent decides which branch to follow based on what’s inside the state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph Execution&lt;/strong&gt;
When you put nodes and edges together, you get a graph. The graph defines the logic of your workflow—what happens first, what comes next, and what conditions guide the flow. LangGraph takes care of running this graph step by step, passing the state through each node and updating it as it goes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence and Memory&lt;/strong&gt;
Sometimes, you’ll want your agent to remember information even after it finishes a run. That’s where persistence comes in. LangGraph lets you save and reload the state so your agent can pick up where it left off. This is what allows long-running agents, ongoing conversations, or workflows that span multiple sessions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools and Agent State&lt;/strong&gt;
LangGraph also gives you the flexibility to connect tools—like APIs, databases, or custom functions—that can read and update the state directly. This is powerful because it lets your agent not just think but act. For example, a research agent might store search results in the state, or a support bot might log each response for later analysis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you understand these building blocks, the rest of LangGraph starts to make sense. Everything revolves around how state flows through nodes and edges. In the next section, we’ll build a simple agent with state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step-by-Step Walkthrough: Build a Simple Agent with State
&lt;/h2&gt;

&lt;p&gt;Now that you know what state is, let’s build a small example to see how it actually works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install LangGraph
&lt;/h3&gt;

&lt;p&gt;First, make sure you have LangGraph and LangChain installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langgraph langchain openai

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you the tools you need to create and run your first graph.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Define the State
&lt;/h3&gt;

&lt;p&gt;Your state is just a Python structure that stores information as your agent runs. Let’s create a simple one that holds a list of messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the state has a single key — &lt;code&gt;messages&lt;/code&gt; — that will keep track of the conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create the Nodes
&lt;/h3&gt;

&lt;p&gt;Each node is a step in your workflow. Let’s make one node that receives user input and another that simulates the agent’s response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;user_input_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ChatState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ChatState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;user_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Return the state dictionary with the new message
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; 

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;agent_response_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ChatState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ChatState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;last_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I see, you said: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;last_message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)[1]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Return the state dictionary with the agent's reply
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first node records what the user says. The second reads that message and creates a response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Build the Graph
&lt;/h3&gt;

&lt;p&gt;Now you connect the nodes so LangGraph knows the order of execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChatState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_input_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;respond&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_response_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;respond&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_entry_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ve just built a tiny graph where “input” leads to “respond.”&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Run It
&lt;/h3&gt;

&lt;p&gt;Finally, compile and run your graph.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this in your terminal, and you’ll see a simple back-and-forth between you and the agent. Each time, the state updates with new messages, so the agent remembers what’s been said.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Inspect the State
&lt;/h3&gt;

&lt;p&gt;After running it, print the state to see what’s stored:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{'messages': ['User: Hello', "Agent: I see, you said: 'Hello'", ...]}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s your agent’s memory — the state — keeping track of the conversation as it unfolds.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/-kzFiQS2zkQ"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;Even with this tiny example, you’ve learned the core idea: the state moves through each step, carrying the information your agent needs to work intelligently. Once you understand that, you can build far more advanced agents that plan, loop, or collaborate across tasks, all powered by the same simple principle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Examples of Using State
&lt;/h2&gt;

&lt;p&gt;Now that you’ve seen how state works in a simple example, let’s look at how it powers real agent workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. A Chatbot That Remembers
&lt;/h3&gt;

&lt;p&gt;Most chatbots forget everything as soon as you hit enter. With state, your chatbot can remember past questions, user preferences, and even previous answers. This makes conversations smoother and more natural. For example, when a user says, &lt;em&gt;“Remind me to buy groceries later,”&lt;/em&gt; the agent can store that request in the state and recall it when needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. A Research Assistant
&lt;/h3&gt;

&lt;p&gt;Imagine a research agent that gathers information from multiple sources. Each time it finds new data, it adds it to the state. Later steps in the graph can summarize, organize, or compare those results. &lt;strong&gt;The state might contain keys like &lt;code&gt;raw_search_results&lt;/code&gt; and &lt;code&gt;research_summary&lt;/code&gt;&lt;/strong&gt;. The state becomes the shared workspace where all the research lives.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. A Task Planner
&lt;/h3&gt;

&lt;p&gt;A planning agent can track progress through the state. It might start with a to-do list, then update each item as it completes a step. For example, if the goal is to &lt;em&gt;“plan a trip to Japan,”&lt;/em&gt; the agent can store flight options, hotel picks, and itineraries inside the state, keeping everything in sync across steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Multi-Agent Collaboration
&lt;/h3&gt;

&lt;p&gt;LangGraph also supports multiple agents working together. They can share a single state, passing updates as they complete tasks. One agent might handle data gathering, another analysis, and another reporting, all reading and writing to the same shared memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Support and Feedback Systems
&lt;/h3&gt;

&lt;p&gt;In customer support scenarios, state can track the full history of a conversation. This allows the agent to stay consistent, avoid repeating questions, and escalate problems with full context. It can even store feedback to improve responses over time.&lt;/p&gt;




&lt;p&gt;These examples show why state is so valuable. Whether it’s chatting, planning, researching, or collaborating, the same idea applies: &lt;strong&gt;the state is where your agent’s understanding lives.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Do I always need to use state?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. If your agent only handles single, simple requests, you can skip it. But once your workflow involves multiple steps, memory, or decisions, state becomes essential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Is state the same as memory?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not exactly. Memory is a part of the state — it’s what keeps track of conversations or events. The state, on the other hand, can hold anything your workflow needs, like results, flags, or user data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Can I update the state manually?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. You can modify the state directly in your nodes or through tools. This gives you full control over what your agent remembers or forgets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. What happens if a node fails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LangGraph allows you to inspect the state and retry. Because the state is stored between steps, you don’t lose your progress when something goes wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;State is what makes LangGraph agents feel alive. It gives them the ability to remember, reason, and stay consistent across every step of their workflow. Once you understand it, you’re no longer just connecting prompts; you’re building systems that think and adapt.&lt;/p&gt;

&lt;p&gt;We’ve already explored what LangGraph agents are in our earlier article, and now you’ve learned what makes them truly capable. Start small, experiment with your own state designs, and watch how your agents grow from simple responders into thoughtful problem-solvers.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>A Beginner's Guide to Getting Started in Agents in LangGraph</title>
      <dc:creator>Damilola Oyedunmade</dc:creator>
      <pubDate>Sat, 18 Oct 2025 10:00:18 +0000</pubDate>
      <link>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-in-agents-in-langgraph-1gfd</link>
      <guid>https://forem.com/aiengineering/a-beginners-guide-to-getting-started-in-agents-in-langgraph-1gfd</guid>
      <description>&lt;p&gt;The world of AI is moving beyond simple question-and-answer chatbots. The new frontier is the &lt;strong&gt;AI Agent,&lt;/strong&gt; a sophisticated system that can reason, plan, use tools, and autonomously tackle complex, multi-step tasks. Imagine an AI that doesn't just answer your question, but actively goes through a research process: searching the web, analyzing data, and summarizing the findings, all on its own.&lt;/p&gt;

&lt;p&gt;Now, when it comes to building such intelligent, goal-driven systems, &lt;strong&gt;LangGraph&lt;/strong&gt; has emerged as a practical and structured way to do it.&lt;/p&gt;

&lt;p&gt;LangGraph is part of the &lt;strong&gt;LangChain ecosystem&lt;/strong&gt;, designed specifically for building &lt;strong&gt;stateful, graph-based AI workflows&lt;/strong&gt;. In simpler terms, it allows you to represent your AI logic as a graph, where each &lt;strong&gt;node&lt;/strong&gt; represents a task or tool, and the &lt;strong&gt;edges&lt;/strong&gt; define how your agent moves between tasks based on what’s happening in the conversation or computation.&lt;/p&gt;

&lt;p&gt;This is powerful because real-world applications rarely follow a straight line of thinking. They branch, loop, and depend on context. LangGraph captures that complexity naturally, without forcing you to hard-code every possible path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before we dive in, here’s something you’ll love:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Learn LangChain the clear, concise, and practical way.&lt;/p&gt;

&lt;p&gt;Whether you’re just starting out or already building, Langcasts gives you guides, tips, hands-on walkthroughs, and in-depth classes to help you master every piece of the AI puzzle. No fluff, just actionable learning to get you building smarter and faster. Start your AI journey today at &lt;a href="https://langcasts.com/" rel="noopener noreferrer"&gt;Langcasts.com&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By the end of this guide, you’ll understand the core ideas behind agents in LangGraph, learn how to build your first one, and see how to extend it into something truly useful—like a research assistant or problem-solving bot.&lt;/p&gt;

&lt;p&gt;Next, let’s unwrap the concept a bit deeper by understanding &lt;strong&gt;how agents work in LangGraph&lt;/strong&gt; and what makes them different from traditional AI workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Understanding the Core Concept of Agents in LangGraph&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before diving into code, it’s important to understand what “agents” really mean in the context of &lt;strong&gt;LangGraph&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At a high level, an &lt;strong&gt;agent&lt;/strong&gt; in LangGraph is an intelligent component that can make decisions, take actions, and use tools to complete a goal. It doesn’t just follow a fixed script; it evaluates what to do next based on inputs, outputs, or the current state of a conversation or workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Key Building Blocks&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To understand how agents operate, it helps to break LangGraph into its three main parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Nodes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A node represents a single operation or step in your workflow. This could be a function call, an LLM (Large Language Model) response, or even an external API call.&lt;/p&gt;

&lt;p&gt;For example, one node might retrieve data, while another node analyzes it or decides the next step.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Edges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edges are the links that connect nodes. They define how information flows from one node to another. In traditional programming, you might use if-else statements to control flow. In LangGraph, edges perform this function visually and logically by connecting decision points and actions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Graph State&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The graph state keeps track of everything happening as your agent runs. It holds the memory of past interactions, results, or decisions. This state allows agents to remember what has already been done, making them smarter and more context-aware.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;How LangGraph Differs from Standard LangChain Agents&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;LangChain introduced the idea of “agents” that can use tools dynamically. LangGraph takes this concept further by letting you represent an agent’s logic as a &lt;strong&gt;graph structure&lt;/strong&gt; instead of a sequence of steps.&lt;/p&gt;

&lt;p&gt;In a standard LangChain setup, an agent might decide, “I need to use a calculator” and then call that tool. With LangGraph, you can define this decision-making flow as a series of connected nodes, giving you more visibility and control over how the agent operates.&lt;/p&gt;

&lt;p&gt;This approach makes complex agent systems easier to design, debug, and expand. It also allows multiple agents or tools to work together seamlessly within one structured workflow.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;A Simple Analogy&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you think of a LangChain agent as a single worker that figures out what to do next, then LangGraph is like giving that worker a well-labeled map. The worker can still make decisions, but the map defines all possible routes and ensures no step is missed or repeated unnecessarily.&lt;/p&gt;




&lt;p&gt;By now, you should have a clear picture of what an agent is in LangGraph and how it differs from traditional agents. In the next section, we’ll set up your environment and get ready to build your very first agent graph.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hands-On: Building Your First Simple Graph
&lt;/h3&gt;

&lt;p&gt;Now that we understand the core components, let's translate them into code by building the simplest possible LangGraph workflow. This graph will take a message, process it through two steps, and finish.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Installation and Environment Setup
&lt;/h3&gt;

&lt;p&gt;First, let's ensure you have the necessary libraries installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langgraph langchain-core langchain-openai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, for any LangChain/LangGraph application, you'll need an API key for your chosen Large Language Model (LLM). For this example, we'll use OpenAI, but the structure works with any model integrated via LangChain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="c1"&gt;# Set your API key as an environment variable
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY" 
# NOTE: It's best practice to use a .env file or a secret manager.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Define the Graph State
&lt;/h3&gt;

&lt;p&gt;We'll start by defining the central data structure that will hold all our information. For simplicity, our state will just be a list of messages. We use &lt;code&gt;TypedDict&lt;/code&gt; for a clear, type-hinted structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.messages&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AIMessage&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;

&lt;span class="c1"&gt;# The State is the data structure that flows through the graph.
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    A dictionary to pass along the chain.
    - messages: A list of all conversation messages (memory).
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BaseMessage&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key piece here is &lt;code&gt;Annotated[list[BaseMessage], operator.add]&lt;/code&gt;. This tells LangGraph that when any node returns a new list of messages, it should &lt;strong&gt;append&lt;/strong&gt; them to the existing list in the state, rather than overwriting the entire history. This is how the agent maintains &lt;strong&gt;memory&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Define the Nodes (The Functions)
&lt;/h3&gt;

&lt;p&gt;Our graph will have two simple functional nodes. Each node takes the current &lt;code&gt;AgentState&lt;/code&gt; as input and returns an update to the state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initial_greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;The first node: processes the initial user message and sets the stage.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Read the last message from the state
&lt;/span&gt;    &lt;span class="n"&gt;user_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;

    &lt;span class="c1"&gt;# Generate a simple greeting based on the input
&lt;/span&gt;    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AIMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello! I received your message: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Return an update to the state (appending the AI's response)
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;final_wrap_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;The second node: adds a concluding message.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;wrap_up_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AIMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;✅ Task complete. That was a successful two-step workflow.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Return an update to the state (appending the wrap-up message)
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;wrap_up_message&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Construct the Graph
&lt;/h3&gt;

&lt;p&gt;Now we use the &lt;code&gt;StateGraph&lt;/code&gt; builder to tie the nodes together with edges.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 1. Initialize the graph builder
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Add the nodes
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;step_1_greeting&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;initial_greeting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;step_2_wrap_up&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;final_wrap_up&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Define the flow (Edges)
# Set the entry point (the first node to run)
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_entry_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;step_1_greeting&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="c1"&gt;# Add a Simple Edge: after step_1, always go to step_2
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;step_1_greeting&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;step_2_wrap_up&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Add a Simple Edge: after step_2, the workflow ends
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;step_2_wrap_up&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Compile the graph into an executable Runnable
&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Invoke the Graph and See the Result
&lt;/h3&gt;

&lt;p&gt;We run the compiled graph by passing in the initial state, which must contain the user's message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="c1"&gt;# Initial state with the user's input
&lt;/span&gt;&lt;span class="n"&gt;initial_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I need help getting started with graph structures.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]}&lt;/span&gt;

&lt;span class="c1"&gt;# Run the graph
&lt;/span&gt;&lt;span class="n"&gt;final_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initial_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Print the full conversation history
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--- Final Agent Conversation History ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;final_state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will clearly show the sequential execution, with the initial user input, followed by the greeting from "step_1_greeting", and finally the wrap-up from "step_2_wrap_up". This simple example demonstrates the fundamental flow: &lt;strong&gt;State → Node → Edge → Node → State Update.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  

  &lt;iframe src="https://www.youtube.com/embed/Lv7Kr2Rc9KI"&gt;
  &lt;/iframe&gt;



&lt;/h2&gt;

&lt;h3&gt;
  
  
  Conclusion: Beyond the First Graph
&lt;/h3&gt;

&lt;p&gt;You have now successfully built, defined, and run your first stateful agent workflow in LangGraph. You’ve moved beyond simple linear chains and created a dynamic system capable of memory, conditional decision-making, and looping.&lt;/p&gt;

&lt;p&gt;Here’s a quick recap of what you accomplished:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;LangGraph Component&lt;/th&gt;
&lt;th&gt;The Breakthrough&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AgentState&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The agent maintains a persistent record of the conversation and intermediate results across all steps.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Modularity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Nodes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The workflow is broken down into simple, reusable Python functions that are easy to test and debug.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Intelligence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Conditional Edges&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The agent’s &lt;em&gt;brain&lt;/em&gt; (the LLM) decides its own path, enabling complex behaviors like tool-use and self-correction (the &lt;strong&gt;ReAct pattern&lt;/strong&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;While a single-agent graph is powerful, LangGraph truly shines when you scale your system. Your next steps in mastering the framework should focus on these advanced, production-ready features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Agent Systems:&lt;/strong&gt; Instead of one large, general-purpose agent, you can connect multiple &lt;strong&gt;specialized agents&lt;/strong&gt; in your graph. Imagine a "Researcher Agent" feeding data to a "Summarizer Agent," all coordinated by a central "Supervisor Agent." LangGraph provides the perfect framework for managing this collaboration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human-in-the-Loop (HITL):&lt;/strong&gt; For critical or sensitive tasks, you can set a conditional edge to pause the workflow and wait for human input or approval before the agent continues. This is crucial for real-world reliability and safety.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence and Checkpointing:&lt;/strong&gt; LangGraph lets you save the &lt;strong&gt;AgentState&lt;/strong&gt; after every step to a database. This means you can resume a long-running workflow or conversation days later, or recover gracefully from errors without losing any context.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;LangGraph is the essential toolkit for building reliable, accountable, and complex AI agents. By understanding the flow of the &lt;strong&gt;State&lt;/strong&gt;, the function of the &lt;strong&gt;Nodes&lt;/strong&gt;, and the power of the &lt;strong&gt;Conditional Edges&lt;/strong&gt;, you have taken the biggest step toward becoming a master architect of agentic AI.&lt;/p&gt;

&lt;p&gt;Now go forth and build something amazing!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
