<?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>DEV Community: M TOQEER ZIA</title>
    <description>The latest articles on DEV Community by M TOQEER ZIA (@m_toqeer).</description>
    <link>https://dev.to/m_toqeer</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%2F3529850%2Fe40fd658-6577-41f6-b787-c57b8c4d9530.jpg</url>
      <title>DEV Community: M TOQEER ZIA</title>
      <link>https://dev.to/m_toqeer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/m_toqeer"/>
    <language>en</language>
    <item>
      <title>Building AI Agents with LangGraph: A Complete Beginner's Guide</title>
      <dc:creator>M TOQEER ZIA</dc:creator>
      <pubDate>Fri, 08 May 2026 13:54:58 +0000</pubDate>
      <link>https://dev.to/m_toqeer/building-ai-agents-with-langgraph-a-complete-beginners-guide-fed</link>
      <guid>https://dev.to/m_toqeer/building-ai-agents-with-langgraph-a-complete-beginners-guide-fed</guid>
      <description>&lt;h2&gt;
  
  
  1. What Is This Project About?
&lt;/h2&gt;

&lt;p&gt;Your project is learning how to build &lt;strong&gt;intelligent AI agents&lt;/strong&gt; using LangGraph and LangChain. These agents can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have conversations that remember context&lt;/li&gt;
&lt;li&gt;Use tools (like looking up stock prices)&lt;/li&gt;
&lt;li&gt;Make decisions based on what they're asked&lt;/li&gt;
&lt;li&gt;Process information step-by-step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of an AI agent like a &lt;strong&gt;smart assistant that can think through problems&lt;/strong&gt;. It doesn't just give you an answer; it can break down the problem, call functions when needed, and adjust based on the results.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem It Solves
&lt;/h3&gt;

&lt;p&gt;Without AI agents, an AI model like ChatGPT can only respond based on what it's trained on. It can't look up real-time information or use external tools. &lt;strong&gt;AI agents solve this&lt;/strong&gt; by letting the model decide when and how to use tools, then incorporating the results into its response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why LangGraph?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LangChain&lt;/strong&gt; is a framework for building AI applications (good for simple tasks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LangGraph&lt;/strong&gt; adds the ability to create &lt;strong&gt;workflows&lt;/strong&gt; - sequences of steps that the AI can navigate intelligently&lt;/li&gt;
&lt;li&gt;Think of it as: LangChain = building blocks, LangGraph = blueprint for arranging those blocks&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Core Concepts Explained (Simple Language)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is Agentic AI?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Agentic AI&lt;/strong&gt; is AI that can &lt;strong&gt;make decisions and take actions&lt;/strong&gt; on its own, not just answer questions.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Regular AI: You ask "What's the weather?" → It gives a generic response based on training data&lt;/li&gt;
&lt;li&gt;Agentic AI: You ask "What's the weather?" → It calls a weather tool → It gets real data → It gives you today's specific weather&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key trait:&lt;/strong&gt; An agent can choose what to do next based on the situation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is LangChain?
&lt;/h3&gt;

&lt;p&gt;LangChain is a &lt;strong&gt;toolkit for building AI applications&lt;/strong&gt;. It helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connecting to different AI models (OpenAI, Google, etc.)&lt;/li&gt;
&lt;li&gt;Managing prompts and messages&lt;/li&gt;
&lt;li&gt;Creating functions that AI can call&lt;/li&gt;
&lt;li&gt;Chaining operations together&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as &lt;strong&gt;LEGO blocks&lt;/strong&gt; for AI - basic pieces you can connect.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is LangGraph?
&lt;/h3&gt;

&lt;p&gt;LangGraph is a &lt;strong&gt;workflow engine&lt;/strong&gt; built on top of LangChain. It lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create &lt;strong&gt;nodes&lt;/strong&gt; (steps/actions)&lt;/li&gt;
&lt;li&gt;Connect nodes with &lt;strong&gt;edges&lt;/strong&gt; (paths between steps)&lt;/li&gt;
&lt;li&gt;Make &lt;strong&gt;decisions&lt;/strong&gt; about which path to take&lt;/li&gt;
&lt;li&gt;Build &lt;strong&gt;complex workflows&lt;/strong&gt; that agents can navigate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as a &lt;strong&gt;flowchart that AI can follow and make decisions within&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Difference: LangChain vs LangGraph
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;LangChain&lt;/th&gt;
&lt;th&gt;LangGraph&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;Building AI applications&lt;/td&gt;
&lt;td&gt;Creating AI workflows/graphs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Structure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Linear chains&lt;/td&gt;
&lt;td&gt;Non-linear graphs with decisions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple Q&amp;amp;A, text processing&lt;/td&gt;
&lt;td&gt;Agents with tools, multi-step tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Control Flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sequential&lt;/td&gt;
&lt;td&gt;Decision-based (if-else paths)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Basic conversation history&lt;/td&gt;
&lt;td&gt;Built-in state management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher, more powerful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple chatbot&lt;/td&gt;
&lt;td&gt;Chatbot that uses tools and decides&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;In simple terms:&lt;/strong&gt; LangChain is like a recipe, LangGraph is like a flowchart the AI follows.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is a Graph (In This Context)?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;graph&lt;/strong&gt; is a way to show connections between things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Circles&lt;/strong&gt; = nodes (actions/steps)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arrows&lt;/strong&gt; = edges (connections between steps)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decisions&lt;/strong&gt; = conditional edges (if-else paths)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START → Node1 → Node2 → END
          ↓
        Decision
          ↓
        Node3 → END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Are Nodes?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;node&lt;/strong&gt; is a function that does something. In your 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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chatbot&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;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;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;llm_with_tools&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a node. It receives the current state, processes it, and returns an updated state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nodes are like workers in a factory - each does a specific job.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Are Edges?
&lt;/h3&gt;

&lt;p&gt;An &lt;strong&gt;edge&lt;/strong&gt; is a connection between nodes. It defines the path the data takes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Types of edges:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regular edge&lt;/strong&gt;: Always goes from Node A to Node B&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditional edge&lt;/strong&gt;: Chooses which node to go to based on a decision
&lt;/li&gt;
&lt;/ul&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="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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Regular edge
&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_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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools_condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Conditional edge
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  State Management
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt; is the data that flows through your graph. Think of it as a &lt;strong&gt;backpack&lt;/strong&gt; that each node can look at and modify.&lt;/p&gt;

&lt;p&gt;Your state definition:&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;class&lt;/span&gt; &lt;span class="nc"&gt;State&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;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;add_messages&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: "We're carrying messages with us. When we add new messages, append them to the list (don't replace)."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why &lt;code&gt;Annotated[list, add_messages]&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;list&lt;/code&gt; = the type of data (a list)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add_messages&lt;/code&gt; = how to update it (append instead of replace)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is important because with conversations, you want to &lt;strong&gt;keep all previous messages&lt;/strong&gt;, not discard them.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Step-by-Step Code Explanation
&lt;/h2&gt;

&lt;p&gt;Let me walk through your most complete example: &lt;strong&gt;tools_memory_langsmith_trace.ipynb&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Part 1: Imports and Setup
&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;langchain.chat_models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;init_chat_model&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;Annotated&lt;/span&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph.message&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;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;ToolNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools_condition&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.checkpoint.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MemorySaver&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What each import does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;init_chat_model&lt;/code&gt; - Initialize an AI model (Gemini, ChatGPT, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Annotated&lt;/code&gt; - Let us add extra information to types&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TypedDict&lt;/code&gt; - Define what data we're carrying (the "backpack")&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;StateGraph&lt;/code&gt; - The workflow builder&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;START&lt;/code&gt;, &lt;code&gt;END&lt;/code&gt; - Special nodes marking beginning and end&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add_messages&lt;/code&gt; - How to merge messages in our state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tool&lt;/code&gt; - Decorator to make functions callable by AI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ToolNode&lt;/code&gt; - Special node that runs tools&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tools_condition&lt;/code&gt; - Built-in decision: "Does the AI want to use tools?"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MemorySaver&lt;/code&gt; - Save conversation history between runs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why needed:&lt;/strong&gt; These give us everything we need to build an AI agent with tools and memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Part 2: Memory Setup
&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;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MemorySaver&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 this does:&lt;/strong&gt; Creates a memory storage object that saves conversation history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it's needed:&lt;/strong&gt; Without memory, each conversation starts fresh. With it, the AI remembers previous messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Part 3: Load Environment Variables
&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;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="nf"&gt;load_dotenv&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 this does:&lt;/strong&gt; Loads API keys from a &lt;code&gt;.env&lt;/code&gt; file (like your OpenAI or Google API key).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it's needed:&lt;/strong&gt; Don't hardcode secret keys in your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Part 4: Define the State (The Backpack)
&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;class&lt;/span&gt; &lt;span class="nc"&gt;State&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;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;add_messages&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 this means:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We're creating a data structure called &lt;code&gt;State&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;It has one piece of data: &lt;code&gt;messages&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;messages&lt;/code&gt; is a list&lt;/li&gt;
&lt;li&gt;When we add messages, use &lt;code&gt;add_messages&lt;/code&gt; (which appends, not replaces)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's structured this way:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keeps conversation history&lt;/strong&gt; - All messages stay in the list&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type-safe&lt;/strong&gt; - Python knows what we expect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensible&lt;/strong&gt; - Can add more fields like &lt;code&gt;user_id&lt;/code&gt;, &lt;code&gt;timestamp&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Part 5: Define a Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_stock_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbol&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;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return the current price of a stock given the stock symbol

    :param symbol: stock symbol
    :return: current price of the stock
    &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;MSFT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;200.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;100.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMZN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;150.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RIL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;87.6&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;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&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 this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@tool&lt;/code&gt; decorator makes this function callable by the AI&lt;/li&gt;
&lt;li&gt;Takes a stock symbol (like "MSFT")&lt;/li&gt;
&lt;li&gt;Returns a price from the dictionary&lt;/li&gt;
&lt;li&gt;If symbol not found, returns 0.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's important:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The AI can &lt;strong&gt;decide to use this tool&lt;/strong&gt; when relevant&lt;/li&gt;
&lt;li&gt;The AI sees the docstring (description) and knows what it does&lt;/li&gt;
&lt;li&gt;AI calls it with the right parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In real life:&lt;/strong&gt; This would call an API to get real stock prices. Here it's mocked for learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Part 6: Create Tools List and Bind to LLM
&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;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_stock_price&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;init_chat_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;google_genai:gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;llm_with_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&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 this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Put all tools in a list&lt;/li&gt;
&lt;li&gt;Initialize Google's Gemini model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bind tools to the model&lt;/strong&gt; - tell the model which tools are available&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What &lt;code&gt;bind_tools&lt;/code&gt; means:&lt;/strong&gt;&lt;br&gt;
The AI model now knows about these tools. When you ask it something, it can decide to call a tool and tell us the tool name and parameters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it's needed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without binding, the model doesn't know tools exist&lt;/li&gt;
&lt;li&gt;With binding, the model can intelligently use them&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Part 7: Create a Chatbot Node
&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;chatbot&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;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;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;llm_with_tools&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;What this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Takes the current state (with all previous messages)&lt;/li&gt;
&lt;li&gt;Sends all messages to the LLM with tools available&lt;/li&gt;
&lt;li&gt;Gets back a response (or tool call)&lt;/li&gt;
&lt;li&gt;Returns it wrapped in a dict with the key &lt;code&gt;messages&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why the wrapping?&lt;/strong&gt;&lt;br&gt;
The state system expects returns in dict format to merge them properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The flow:&lt;/strong&gt; Old messages + invoke → New response → Add to state&lt;/p&gt;
&lt;h3&gt;
  
  
  Part 8: Build the Graph - Create Builder
&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="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;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;What this does:&lt;/strong&gt; Create a blank workflow blueprint using our State definition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Think of it as:&lt;/strong&gt; Getting a blank flowchart template.&lt;/p&gt;
&lt;h3&gt;
  
  
  Part 9: Add Nodes
&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_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatbot&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;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ToolNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&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 this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the chatbot function as a node&lt;/li&gt;
&lt;li&gt;Add a special "tools" node that knows how to run our tools&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The ToolNode is special:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's built-in to LangGraph&lt;/li&gt;
&lt;li&gt;It knows how to execute tool calls&lt;/li&gt;
&lt;li&gt;When the LLM says "call get_stock_price with MSFT", ToolNode handles it&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Part 10: Add Edges - Create Paths
&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_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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                    &lt;span class="c1"&gt;# Always start at chatbot
&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_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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools_condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Decision point
&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;tools&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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;# After tools, go back to chatbot
&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;chatbot&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;# Can end here
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Let's trace the flow:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;START → chatbot&lt;/code&gt; - Always start by calling the chatbot node&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chatbot → decision&lt;/code&gt; - After chatbot runs, ask: "Does the AI want to use tools?"

&lt;ul&gt;
&lt;li&gt;If YES → go to tools node&lt;/li&gt;
&lt;li&gt;If NO → go to END&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tools → chatbot&lt;/code&gt; - After running tools, go back to chatbot&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chatbot → END&lt;/code&gt; - From chatbot, can reach END&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why this structure?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If AI doesn't need tools, it responds and we're done&lt;/li&gt;
&lt;li&gt;If AI needs tools, we get the result and let AI use it in another response&lt;/li&gt;
&lt;li&gt;This loop continues until the AI decides no more tools are needed&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Part 11: Compile the Graph
&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;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;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;memory&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 this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finalize the graph (check for errors, optimize)&lt;/li&gt;
&lt;li&gt;Add memory checkpoint (save state between runs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why checkpointer?&lt;/strong&gt;&lt;br&gt;
With &lt;code&gt;checkpointer=memory&lt;/code&gt;, every conversation is saved. You can resume a conversation using the same &lt;code&gt;thread_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without checkpointer:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each &lt;code&gt;.invoke()&lt;/code&gt; call is isolated&lt;/li&gt;
&lt;li&gt;No conversation memory between calls&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Part 12: Using the Graph - First Invocation
&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;config&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;configurable&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;thread_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;1&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;state&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="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;What is the current stock price of MSFT?&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;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&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 this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a config with &lt;code&gt;thread_id: "1"&lt;/code&gt; - this identifies the conversation&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;graph.invoke()&lt;/code&gt; with:

&lt;ul&gt;
&lt;li&gt;Initial state (user message)&lt;/li&gt;
&lt;li&gt;Config (thread ID for memory)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Get back the final state with all messages&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;thread_id&lt;/code&gt; is important:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First call with thread_id "1" → saves to memory with key "1"&lt;/li&gt;
&lt;li&gt;Second call with same thread_id "1" → loads previous memory, remembers context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it works internally:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User message → Chatbot node → LLM sees "I need get_stock_price tool"&lt;/li&gt;
&lt;li&gt;Decision: Does AI need tools? YES → go to tools node&lt;/li&gt;
&lt;li&gt;Tools node runs get_stock_price("MSFT") → returns 200.3&lt;/li&gt;
&lt;li&gt;Result back to chatbot → LLM now has the price → creates response&lt;/li&gt;
&lt;li&gt;Response goes to output&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Part 13: Using Different Thread IDs (Memory Separation)
&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;config2&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;configurable&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;thread_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;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="n"&gt;state&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="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;What is the current stock price of MSFT?&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="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config2&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 this does:&lt;/strong&gt; Use thread_id "2" instead of "1"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each thread_id is a separate conversation&lt;/li&gt;
&lt;li&gt;Thread "1" and Thread "2" have separate memory&lt;/li&gt;
&lt;li&gt;Thread "1" might remember previous context, Thread "2" starts fresh&lt;/li&gt;
&lt;li&gt;Useful for multiple users or multiple conversations&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Part 14: Tracing with LangSmith
&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;langsmith&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;traceable&lt;/span&gt;

&lt;span class="nd"&gt;@traceable&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_graph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;span class="n"&gt;state&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="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="n"&gt;query&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="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;What &lt;code&gt;@traceable&lt;/code&gt; does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs this function call to LangSmith&lt;/li&gt;
&lt;li&gt;Records inputs, outputs, timing&lt;/li&gt;
&lt;li&gt;Creates a trace for debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's useful:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;See exactly what the AI did&lt;/li&gt;
&lt;li&gt;Understand why it made decisions&lt;/li&gt;
&lt;li&gt;Debug problems more easily&lt;/li&gt;
&lt;li&gt;Visualize the execution flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;state["messages"][-1].content&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;state["messages"]&lt;/code&gt; = list of all messages&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[-1]&lt;/code&gt; = last message&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.content&lt;/code&gt; = the text content of that message&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  4. Graph Flow Explanation
&lt;/h2&gt;

&lt;p&gt;Let me explain how data flows through your graph using a real example.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example: "What is the current stock price of MSFT?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: START&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User provides: &lt;code&gt;{"role": "user", "content": "What is the current stock price of MSFT?"}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;State now has: &lt;code&gt;messages: [user_message]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Enter Chatbot Node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chatbot receives state with all previous messages&lt;/li&gt;
&lt;li&gt;Calls LLM with all messages and available tools&lt;/li&gt;
&lt;li&gt;LLM reads the question and sees &lt;code&gt;get_stock_price&lt;/code&gt; tool is available&lt;/li&gt;
&lt;li&gt;LLM decides: "I need to call get_stock_price with symbol='MSFT'"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Decision Point (tools_condition)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Question: "Did the AI decide to use tools?"&lt;/li&gt;
&lt;li&gt;Answer: YES (LLM returned a tool call)&lt;/li&gt;
&lt;li&gt;Next: Go to "tools" node&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Tools Node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receives the tool call request&lt;/li&gt;
&lt;li&gt;Executes: &lt;code&gt;get_stock_price("MSFT")&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Gets result: &lt;code&gt;200.3&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Adds to state: &lt;code&gt;{"tool": "get_stock_price", "result": 200.3}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;State now has: &lt;code&gt;messages: [user_message, tool_call, tool_result]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Back to Chatbot Node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chatbot receives state with: original message, tool call, tool result&lt;/li&gt;
&lt;li&gt;Calls LLM again with all messages&lt;/li&gt;
&lt;li&gt;LLM sees the tool result and creates a response: "The current stock price of MSFT is $200.3"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Decision Point Again (tools_condition)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Question: "Does the AI need tools again?"&lt;/li&gt;
&lt;li&gt;Answer: NO (LLM returned a message, not a tool call)&lt;/li&gt;
&lt;li&gt;Next: Go to END&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 7: END&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Graph completes&lt;/li&gt;
&lt;li&gt;State returned with all messages including the response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Final state:&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;What is the current stock price of MSFT?&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;I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ll look up the stock price for 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;# Tool call
&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool&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;get_stock_price&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="mf"&gt;200.3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;  &lt;span class="c1"&gt;# Tool 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;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;The current stock price of MSFT is $200.3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# Final response
&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;h3&gt;
  
  
  Decision Points in Your Graph
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;tools_condition&lt;/strong&gt; is a built-in function that checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IF the AI's last message includes a tool call:
    → Go to "tools" node
ELSE:
    → Go to END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why conditional edges matter:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The graph doesn't always follow the same path&lt;/li&gt;
&lt;li&gt;Different user inputs → Different paths&lt;/li&gt;
&lt;li&gt;If no tools needed, skip tools node&lt;/li&gt;
&lt;li&gt;If tools needed, use them and get results&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Another Path Example: "Tell me a fun fact"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: User asks: "Tell me a fun fact"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Chatbot node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLM sees the question&lt;/li&gt;
&lt;li&gt;Doesn't need tools (no need to call get_stock_price)&lt;/li&gt;
&lt;li&gt;Returns: "Here's a fun fact: The sun is..."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Decision point&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Question: "Any tool calls?"&lt;/li&gt;
&lt;li&gt;Answer: NO&lt;/li&gt;
&lt;li&gt;Next: END&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Path taken:&lt;/strong&gt; START → Chatbot → Decision (NO) → END&lt;/p&gt;

&lt;p&gt;See the difference? Same graph, different paths based on what the AI decides.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Chatbot Logic - How It Works Internally
&lt;/h2&gt;

&lt;p&gt;Your chatbot is actually &lt;strong&gt;stateful&lt;/strong&gt;. Here's what that means:&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is "Stateful"?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Stateless:&lt;/strong&gt; Each request is independent. The system forgets previous interactions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Hi"
Bot: "Hello!"
User: "What's my name?"
Bot: "I don't know, you didn't tell me"  ← Forgot previous message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stateful:&lt;/strong&gt; The system remembers previous interactions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "My name is Alice"
Bot: "Nice to meet you, Alice!"
User: "What's my name?"
Bot: "Your name is Alice"  ← Remembers Alice from before
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Your chatbot is stateful&lt;/strong&gt; because of this 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;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;add_messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;add_messages&lt;/code&gt; function means: &lt;strong&gt;Keep appending, don't forget&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Messages Flow
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;First turn:&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="n"&gt;state&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, tell me about yourself&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;# LLM sees: [user_message]
# LLM responds
# State after: [user_message, assistant_response]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Second turn (same thread_id):&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="n"&gt;state&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;What did you just say?&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;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;  &lt;span class="c1"&gt;# Same thread_id
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Memory loads: [user_message, assistant_response]  ← From before!
# Plus new user message: [old_user, old_assistant, new_user]
# LLM sees: all 3 messages
# LLM responds with context
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why using &lt;code&gt;add_messages&lt;/code&gt; is crucial - it &lt;strong&gt;preserves all messages&lt;/strong&gt;, not just the latest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Without add_messages (What would happen)
&lt;/h3&gt;

&lt;p&gt;If we used &lt;code&gt;messages: list&lt;/code&gt; instead:&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;# First invoke:
&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user_message_1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Second invoke (without add_messages):
&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user_message_2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="n"&gt;Lost&lt;/span&gt; &lt;span class="n"&gt;user_message_1&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI would forget everything before the new message.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Tools Integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Are Tools?
&lt;/h3&gt;

&lt;p&gt;Tools are &lt;strong&gt;functions the AI can decide to call&lt;/strong&gt;. They're external actions the AI can take.&lt;/p&gt;

&lt;p&gt;In your 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="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_stock_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbol&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;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return the current price of a stock given the stock symbol&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;MSFT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;200.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;100.4&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;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a tool that &lt;strong&gt;the AI can choose to use&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Are Tools Used?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Define tool&lt;/strong&gt; ✓ (you did this with &lt;code&gt;@tool&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Make list of tools&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="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_stock_price&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;Step 3: Bind tools to LLM&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="n"&gt;llm_with_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the AI model knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What tools exist&lt;/li&gt;
&lt;li&gt;What each tool does (from the docstring)&lt;/li&gt;
&lt;li&gt;What parameters each tool needs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: AI decides to use tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you ask a question, the AI decides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Do I need to use any tools?"&lt;/li&gt;
&lt;li&gt;If YES → "Which tool and what parameters?"&lt;/li&gt;
&lt;li&gt;If NO → "I'll answer directly"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: System executes the tool&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If AI decides to use a tool, the &lt;code&gt;ToolNode&lt;/code&gt; runs 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="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;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ToolNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&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;Step 6: Result goes back to AI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The AI sees the tool result and can use it in its response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Tools Are Important in Agentic AI
&lt;/h3&gt;

&lt;p&gt;Without tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "What's MSFT stock price?"
AI: "I don't know, I'm not trained on real-time data"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "What's MSFT stock price?"
AI: "Let me check" → calls get_stock_price → gets 200.3 → "It's $200.3"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tools give AI access to:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time data (stock prices, weather, news)&lt;/li&gt;
&lt;li&gt;External systems (databases, APIs, calculators)&lt;/li&gt;
&lt;li&gt;Custom logic (your business rules)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Example: Weather Agent
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&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;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&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 current weather for a city&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# In real code, this calls an API
&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;Sunny, 72°F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;llm_with_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When user asks: "What's the weather in New York?"&lt;/p&gt;

&lt;p&gt;The AI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Decides it needs weather data&lt;/li&gt;
&lt;li&gt;Calls &lt;code&gt;get_weather("New York")&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Receives "Sunny, 72°F"&lt;/li&gt;
&lt;li&gt;Responds: "The weather in New York is sunny and 72 degrees"&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  7. Memory System
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is Memory Doing in Your Code?
&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.checkpoint.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MemorySaver&lt;/span&gt;
&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MemorySaver&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;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a &lt;strong&gt;persistent memory for conversations&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Without memory:&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="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="c1"&gt;# Each call is isolated
&lt;/span&gt;&lt;span class="n"&gt;invoke_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;Hi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="err"&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="n"&gt;invoke_2&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 did I say?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I don&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t know&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With memory:&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="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;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;config1&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;configurable&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;thread_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;user_123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="n"&gt;invoke_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;Hi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Saves&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;invoke_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Uses&lt;/span&gt; &lt;span class="n"&gt;same&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Loads&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Has&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The thread_id System
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;thread_id&lt;/code&gt; is like a &lt;strong&gt;conversation ID&lt;/strong&gt;. Each thread has its own memory.&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;# User 1's conversation
&lt;/span&gt;&lt;span class="n"&gt;config1&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;configurable&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;thread_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;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;invoke&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Saved as conversation "1"
&lt;/span&gt;
&lt;span class="c1"&gt;# User 2's conversation  
&lt;/span&gt;&lt;span class="n"&gt;config2&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;configurable&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;thread_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;2&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;invoke&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Saved as conversation "2"
&lt;/span&gt;
&lt;span class="c1"&gt;# Back to User 1
&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="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Loads conversation "1"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each thread_id is &lt;strong&gt;completely separate&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thread "1" doesn't see Thread "2"'s messages&lt;/li&gt;
&lt;li&gt;Multiple users can use the same graph&lt;/li&gt;
&lt;li&gt;Each user gets their own conversation history&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;Multi-user support:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bot (same code)
  ├─ Thread "alice" → Remembers Alice's messages
  ├─ Thread "bob"   → Remembers Bob's messages
  └─ Thread "carol" → Remembers Carol's messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conversation resumption:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Hi, I want to talk about Python"
Bot: "Sure! Let's discuss Python"
[User closes app]

[User reopens app, same thread_id]
User: "What were we talking about?"
Bot: "We were discussing Python"  ← Remembers!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stateless vs Stateful
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Stateless (without memory):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every request starts fresh&lt;/li&gt;
&lt;li&gt;No conversation history&lt;/li&gt;
&lt;li&gt;Simple but limited&lt;/li&gt;
&lt;li&gt;Good for one-off questions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Stateful (with memory):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requests build on previous ones&lt;/li&gt;
&lt;li&gt;Full conversation history&lt;/li&gt;
&lt;li&gt;More complex but powerful&lt;/li&gt;
&lt;li&gt;Good for ongoing conversations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your code is stateful&lt;/strong&gt; - it remembers everything across calls to the same thread.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Human-in-the-Loop Systems
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Does "Human-in-the-Loop" Mean?
&lt;/h3&gt;

&lt;p&gt;It means &lt;strong&gt;humans are part of the decision-making process&lt;/strong&gt;. The AI doesn't just do everything automatically - sometimes it asks for human approval.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where Human Intervention Can Happen
&lt;/h3&gt;

&lt;p&gt;In your graph, potential intervention points:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After chatbot decides to use a tool:&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="c1"&gt;# AI decides: "I'll call get_stock_price"
# STOP HERE: Ask human: "Should I really call this tool?"
# Human says: "Yes" or "No"
# Continue based on human decision
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Before responding:&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="c1"&gt;# AI creates a response
# STOP HERE: Ask human: "Does this response look good?"
# Human edits or approves
# Then send to user
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why It's Useful
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Reason 1: Safety&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI decides: "I'll delete all records"
Human intervention: "STOP! Don't do that!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reason 2: Quality control&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI creates a response
Human checks: "Is this accurate?"
If not, human corrects it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reason 3: Transparency&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Shows humans what the AI is doing
Builds trust
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reason 4: Learning&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human feedback teaches the system
System improves over time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real-World Example: Content Moderation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User submits comment
↓
AI checks: "Is this appropriate?"
↓
If uncertain: Ask human moderator
↓
Human reviews and approves/rejects
↓
System learns from human decisions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Implement in LangGraph
&lt;/h3&gt;

&lt;p&gt;In your graph, you could add:&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;human_approval&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;State&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&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 human for approval&lt;/span&gt;&lt;span class="sh"&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;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;Approve this action? (yes/no): &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="n"&gt;response&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="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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;human_approval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Ask human
&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;tools&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# Human said yes
&lt;/span&gt;        &lt;span class="bp"&gt;False&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="c1"&gt;# Human said no
&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 creates a decision point where a human must approve before tools run.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Tracing with LangSmith
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is Tracing?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Tracing&lt;/strong&gt; means recording exactly what happened step-by-step, like a &lt;strong&gt;detailed log of the entire execution&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="nd"&gt;@traceable&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_graph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;span class="n"&gt;state&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="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@traceable&lt;/code&gt; decorator means: &lt;strong&gt;Record everything this function does&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Debugging AI Systems Is Hard
&lt;/h3&gt;

&lt;p&gt;With regular code, debugging is straightforward:&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# If wrong, set breakpoint, see exactly where it failed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With AI systems, it's harder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "What's MSFT price?"
AI: "I don't know"  # Wrong! Why?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why did the AI give wrong answer?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did it not understand the question?&lt;/li&gt;
&lt;li&gt;Did it forget to call the tool?&lt;/li&gt;
&lt;li&gt;Did the tool return wrong data?&lt;/li&gt;
&lt;li&gt;Did the AI misinterpret the tool result?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's hard to know without seeing every step.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Tracing Helps
&lt;/h3&gt;

&lt;p&gt;Tracing records &lt;strong&gt;every step&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: User message received
Step 2: Chatbot node called
Step 3: LLM invoked with messages
Step 4: LLM returned: tool_call(get_stock_price, "MSFT")
Step 5: Tool node executed
Step 6: get_stock_price returned 200.3
Step 7: Chatbot node called again
Step 8: LLM returned: "The price is $200.3"
Step 9: tools_condition checked: No more tools
Step 10: Reached END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can see exactly where things went wrong!&lt;/p&gt;

&lt;h3&gt;
  
  
  Using LangSmith Tracing
&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;langsmith&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;traceable&lt;/span&gt;

&lt;span class="nd"&gt;@traceable&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_agent_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# ... your code ...
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run &lt;code&gt;my_agent_call("something")&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Every step is recorded&lt;/li&gt;
&lt;li&gt;Sent to LangSmith dashboard&lt;/li&gt;
&lt;li&gt;You can see: timing, inputs, outputs, errors&lt;/li&gt;
&lt;li&gt;Visual representation of the graph execution&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;See exactly what the AI did&lt;/li&gt;
&lt;li&gt;Find performance bottlenecks&lt;/li&gt;
&lt;li&gt;Debug errors quickly&lt;/li&gt;
&lt;li&gt;Improve the system based on traces&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example 1: Simple Stock Price Query
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; "What is the stock price of AAPL?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens internally:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State:&lt;/strong&gt; &lt;code&gt;messages: [user_message]&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chatbot node:&lt;/strong&gt; Calls LLM&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLM sees: "User wants stock price"&lt;/li&gt;
&lt;li&gt;LLM decides: "I need to call get_stock_price with AAPL"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decision:&lt;/strong&gt; Does AI want tools?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yes → Go to tools node&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tools node:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calls: &lt;code&gt;get_stock_price("AAPL")&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Gets: &lt;code&gt;100.4&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Adds to messages: tool call + result&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chatbot node again:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLM sees all messages + tool result&lt;/li&gt;
&lt;li&gt;Creates response: "The stock price of AAPL is $100.4"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decision:&lt;/strong&gt; Does AI want tools again?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No → Go to END&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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;What is the stock price of AAPL?&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;tool_calls&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;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;100.4&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;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;get_stock_price&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;The stock price of AAPL is $100.4&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;h3&gt;
  
  
  Example 2: Conversation with Memory
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Setup:&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="n"&gt;config&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;configurable&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;thread_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;user_alice&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;strong&gt;Turn 1:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Hi, my name is Alice"
Bot: "Nice to meet you, Alice!"

Memory saved: [user_message, assistant_response]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Turn 2:&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="n"&gt;config&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;configurable&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;thread_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;user_alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;  &lt;span class="c1"&gt;# Same thread
&lt;/span&gt;&lt;span class="n"&gt;User&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&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s my name?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;Memory&lt;/span&gt; &lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;previous_messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Plus&lt;/span&gt; &lt;span class="n"&gt;adds&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_user_message&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;LLM&lt;/span&gt; &lt;span class="n"&gt;sees&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;old_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_assistant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_user&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;LLM&lt;/span&gt; &lt;span class="n"&gt;responds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Your name is Alice, as you told me earlier&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;Memory&lt;/span&gt; &lt;span class="n"&gt;saved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;all_4_messages&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;The key:&lt;/strong&gt; &lt;code&gt;add_messages&lt;/code&gt; appended the new message to the list, not replaced.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 3: Currency Conversion (from 2_node.ipynb)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Input:&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;amount_usd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total_usd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target_currency&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;EUR&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;strong&gt;Flow:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;START → calc_total_node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculates: &lt;code&gt;total_usd = 100.0 * 1.5 = 150.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;State becomes: &lt;code&gt;total_usd: 150.0&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Conditional Edge: choose_conversion&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checks: &lt;code&gt;target_currency = "EUR"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Goes to: &lt;code&gt;convert_to_eur_node&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;convert_to_eur_node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculates: &lt;code&gt;total = 150.0 * 0.85 = 127.5&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;State becomes: &lt;code&gt;total: 127.5&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiple paths join → END&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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;amount_usd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total_usd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;150.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target_currency&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;EUR&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;total&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;127.5&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;Key concept:&lt;/strong&gt; Based on &lt;code&gt;target_currency&lt;/code&gt;, the graph chooses which conversion node to run. The same graph can follow different paths.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. "Big Word Alert" - Simple Explanations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Agent
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; An intelligent system that can make decisions and take actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; A smart robot that can think about what to do next and do it on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&lt;/strong&gt; Your chatbot with tools is an agent - it decides whether to use tools or respond directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  State
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; The data that flows through the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; Like a backpack that carries information from one step to the next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;State&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;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;add_messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backpack contains: &lt;code&gt;messages&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Node
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; A unit of computation (a function).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; A worker that does a specific job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chatbot&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;State&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# This is a node - it does one job
&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;llm_with_tools&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tool
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; An external function the AI can call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; A power-up the AI can use when it needs to do something specific.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_stock_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbol&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;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# This is a tool
&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;MSFT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;200.3&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;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Invocation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; Calling a function and getting a result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; Using something to get a result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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="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="c1"&gt;# This is an invocation
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Workflow
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; A series of steps in a specific order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; A recipe that steps follow one by one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&lt;/strong&gt; Your entire graph is a workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Binding
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; Connecting tools to a model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; Giving the AI a toolbox so it knows what tools are available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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="n"&gt;llm_with_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# bind_tools = "give the AI these tools"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conditional Edge
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; A path that depends on a condition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; An if-else statement in your graph.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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="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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools_condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# IF AI needs tools THEN go to tools node
# ELSE go to END
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpointer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; A system that saves state at checkpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; A save point for your conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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="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;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Saves the state so you can resume later
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Annotated
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; Adding metadata to a type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; Attaching extra instructions to a data type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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="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;add_messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# "This is a list, and when adding to it, use add_messages function"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Thread ID
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big word:&lt;/strong&gt; A unique identifier for a conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt; A conversation ID, like a thread in a forum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In code:&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;configurable&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;thread_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;user_alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="c1"&gt;# This conversation belongs to "user_alice"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. Pros and Cons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  LangGraph Pros
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 1: Non-linear workflows&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can have if-else decisions&lt;/li&gt;
&lt;li&gt;Not stuck with sequential steps&lt;/li&gt;
&lt;li&gt;Real agents can branch out&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 2: Built-in memory support&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to add conversation memory&lt;/li&gt;
&lt;li&gt;Handles state management automatically&lt;/li&gt;
&lt;li&gt;Good for multi-turn interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 3: Tool integration is seamless&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agents can decide when to use tools&lt;/li&gt;
&lt;li&gt;Automatic tool calling&lt;/li&gt;
&lt;li&gt;Cleaner than manual approach&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 4: Checkpointing/persistence&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save and resume conversations&lt;/li&gt;
&lt;li&gt;Stateful by default&lt;/li&gt;
&lt;li&gt;Great for multi-user systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 5: Debugging support&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual graph representation&lt;/li&gt;
&lt;li&gt;LangSmith integration for tracing&lt;/li&gt;
&lt;li&gt;See exactly what's happening&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 6: Reusable patterns&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ToolNode is built-in&lt;/li&gt;
&lt;li&gt;tools_condition is pre-made&lt;/li&gt;
&lt;li&gt;Less code to write&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  LangGraph Cons
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 1: Steeper learning curve&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More concepts to understand&lt;/li&gt;
&lt;li&gt;Harder than simple LangChain&lt;/li&gt;
&lt;li&gt;More setup needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 2: Overkill for simple tasks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you just need Q&amp;amp;A, this is excessive&lt;/li&gt;
&lt;li&gt;More code than needed&lt;/li&gt;
&lt;li&gt;Can be frustrating for beginners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 3: Performance overhead&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More layers of abstraction&lt;/li&gt;
&lt;li&gt;Slower than direct API calls&lt;/li&gt;
&lt;li&gt;Not ideal for latency-critical apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 4: Limited to certain patterns&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works best for agent patterns&lt;/li&gt;
&lt;li&gt;Not ideal for other paradigms&lt;/li&gt;
&lt;li&gt;Some use cases need custom solutions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 5: Dependency on LangChain&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tightly coupled to LangChain ecosystem&lt;/li&gt;
&lt;li&gt;Can't easily use other frameworks&lt;/li&gt;
&lt;li&gt;Vendor lock-in risk&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  This Approach (Graph-Based Agents) Pros
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 1: Transparency&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can see the graph structure&lt;/li&gt;
&lt;li&gt;Easy to understand flow&lt;/li&gt;
&lt;li&gt;Good for learning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 2: Modularity&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add/remove nodes easily&lt;/li&gt;
&lt;li&gt;Reuse nodes across projects&lt;/li&gt;
&lt;li&gt;Mix and match components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 3: Scalability&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Graphs can be arbitrarily complex&lt;/li&gt;
&lt;li&gt;Handles multi-step reasoning&lt;/li&gt;
&lt;li&gt;Good for sophisticated agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 4: Controllability&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You define every edge&lt;/li&gt;
&lt;li&gt;Explicit about flow&lt;/li&gt;
&lt;li&gt;No magic happening&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Pro 5: Extensibility&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom nodes easy to add&lt;/li&gt;
&lt;li&gt;Custom conditions easy to add&lt;/li&gt;
&lt;li&gt;Can build complex logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  This Approach (Graph-Based Agents) Cons
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 1: Requires planning&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need to think about graph structure&lt;/li&gt;
&lt;li&gt;Not suitable for ad-hoc scripts&lt;/li&gt;
&lt;li&gt;Design phase is important&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 2: Can become complex&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many nodes → hard to maintain&lt;/li&gt;
&lt;li&gt;Complex conditions → hard to debug&lt;/li&gt;
&lt;li&gt;Spaghetti graphs possible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 3: Overhead for simple cases&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Too much scaffolding for "hello world"&lt;/li&gt;
&lt;li&gt;Boilerplate required&lt;/li&gt;
&lt;li&gt;Friction for quick prototypes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Con 4: State management complexity&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need to understand TypedDict&lt;/li&gt;
&lt;li&gt;Understand add_messages behavior&lt;/li&gt;
&lt;li&gt;Easy to make mistakes with state&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  13. Common Beginner Mistakes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mistake 1: Forgetting &lt;code&gt;add_messages&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;State&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="c1"&gt;# ❌ Plain list
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; Messages get replaced instead of appended. Previous context is lost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;State&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;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;add_messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ With add_messages
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; &lt;code&gt;add_messages&lt;/code&gt; tells LangGraph to append, not replace.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 2: Not binding tools to LLM
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_stock_price&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;init_chat_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;google_genai:gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# ❌ Forgot to bind tools to llm
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; LLM doesn't know tools exist. Can't use them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="n"&gt;llm_with_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Bind tools
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; LLM needs to know what tools are available.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 3: Forgetting to add ToolNode
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="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="n"&gt;chatbot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# ❌ Forgot ToolNode
&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;chatbot&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;strong&gt;What happens:&lt;/strong&gt; No node can execute the tools. AI decides to use tools but nothing happens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="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="n"&gt;chatbot&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;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ToolNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Add ToolNode
&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;chatbot&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;strong&gt;Why:&lt;/strong&gt; ToolNode knows how to execute tool calls.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 4: Not using same thread_id for memory
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="c1"&gt;# First call - new thread_id
&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="n"&gt;config&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;configurable&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;thread_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;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt;

&lt;span class="c1"&gt;# Second call - different thread_id
&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="n"&gt;config&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;configurable&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;thread_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;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;# ❌ Lost context!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; No memory between calls. Each call starts fresh.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="n"&gt;config&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;configurable&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;thread_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;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="c1"&gt;# First call
&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="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Second call - same thread_id
&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="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Remembers context
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; Same thread_id = same conversation memory.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 5: Not returning state dict from nodes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chatbot&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;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="n"&gt;llm_with_tools&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;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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;  &lt;span class="c1"&gt;# ❌ Wrong format
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; State update fails. Error in merging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chatbot&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;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="n"&gt;llm_with_tools&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;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="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="c1"&gt;# ✅ Dict format
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; State system expects dict to merge state updates.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 6: Forgetting conditional edges
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="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;chatbot&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;# ❌ Always goes to END
# No chance to use tools
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; Tools never get called, even if AI wants to use them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools_condition&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;tools&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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Can loop back to tools
&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;chatbot&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;# Also can end
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; Conditional edges allow AI to decide: use tools or end.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 7: Using wrong LLM initialization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# ❌ Doesn't use init_chat_model
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; Can work, but not best practice. Less flexible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;init_chat_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;google_genai:gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# ✅
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; &lt;code&gt;init_chat_model&lt;/code&gt; is provider-agnostic. Easy to swap models.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 8: Confusing state fields
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;State&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;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;add_messages&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;chatbot&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;State&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;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="c1"&gt;# ❌ "message" (singular)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; KeyError - field doesn't exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="k"&gt;return&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="c1"&gt;# ✅ "messages" (plural)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; Exact spelling matters. State keys must match.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 9: Not handling the returned state
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="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="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;# ❌ Don't use the returned value
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; You don't see the response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="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="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="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;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;# ✅ Get the response
&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;response&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;Why:&lt;/strong&gt; The function returns the final state. You need to extract the response.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mistake 10: Missing docstring in tools
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong:&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="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_stock_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbol&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;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# ❌ No docstring
&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;MSFT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;200.3&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;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&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 happens:&lt;/strong&gt; AI doesn't understand what the tool does. Wrong usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right:&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="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_stock_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbol&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;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return the current price of a stock given the stock symbol&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;  &lt;span class="c1"&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;MSFT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;200.3&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;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&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;Why:&lt;/strong&gt; LLM reads the docstring to decide when to use the tool.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Summary
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. LangGraph enables non-linear workflows&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not just sequential steps&lt;/li&gt;
&lt;li&gt;Agents can make decisions&lt;/li&gt;
&lt;li&gt;Conditional edges create branches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. State management is crucial&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;add_messages&lt;/code&gt; keeps conversation history&lt;/li&gt;
&lt;li&gt;Without it, context is lost&lt;/li&gt;
&lt;li&gt;Stateful behavior is the default&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Tools give AI superpowers&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agents can decide when to use them&lt;/li&gt;
&lt;li&gt;Results inform the AI's response&lt;/li&gt;
&lt;li&gt;Real-time data, external logic, custom functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Memory makes conversations work&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thread IDs separate conversations&lt;/li&gt;
&lt;li&gt;Same thread = same memory&lt;/li&gt;
&lt;li&gt;Multiple users can use same graph&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Nodes are workers, edges are paths&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nodes do work (functions)&lt;/li&gt;
&lt;li&gt;Edges connect them (paths)&lt;/li&gt;
&lt;li&gt;Conditional edges make intelligent choices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Tracing helps debugging&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;See every step of execution&lt;/li&gt;
&lt;li&gt;LangSmith provides visibility&lt;/li&gt;
&lt;li&gt;Essential for production systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What to Focus On Next
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Near term (practice these):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build a chatbot without tools (basic flow)&lt;/li&gt;
&lt;li&gt;Add one tool and see how AI uses it&lt;/li&gt;
&lt;li&gt;Experiment with different tool combinations&lt;/li&gt;
&lt;li&gt;Try different thread_ids for separate conversations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Medium term (understand deeply):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How TypedDict and Annotated work&lt;/li&gt;
&lt;li&gt;How add_messages merges state&lt;/li&gt;
&lt;li&gt;How conditional edges make decisions&lt;/li&gt;
&lt;li&gt;How ToolNode executes tool calls&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Advanced (explore):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multiple tools with complex logic&lt;/li&gt;
&lt;li&gt;Multi-agent systems (agents talking to each other)&lt;/li&gt;
&lt;li&gt;Custom state merging logic&lt;/li&gt;
&lt;li&gt;Error handling and recovery&lt;/li&gt;
&lt;li&gt;Production deployment and scaling&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Final Thought
&lt;/h3&gt;

&lt;p&gt;You're learning a powerful paradigm: &lt;strong&gt;graph-based agentic AI&lt;/strong&gt;. This is not just coding; it's defining workflows that AI can navigate intelligently.&lt;/p&gt;

&lt;p&gt;The key is understanding that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Graphs are blueprints&lt;/strong&gt; for how data flows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agents are decision-makers&lt;/strong&gt; that navigate the blueprint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools are extensions&lt;/strong&gt; that give agents capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory is context&lt;/strong&gt; that makes interactions coherent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start small, build incrementally, and debug with LangSmith traces. Good luck on your journey!&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Additional Resources in Your Project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Files to Study in Order
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. First: chatbot.ipynb&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplest example&lt;/li&gt;
&lt;li&gt;No tools, no memory&lt;/li&gt;
&lt;li&gt;Just basic message flow&lt;/li&gt;
&lt;li&gt;Best for understanding the fundamentals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Next: 2_node.ipynb&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduces multiple nodes&lt;/li&gt;
&lt;li&gt;Currency conversion example&lt;/li&gt;
&lt;li&gt;Shows conditional edges&lt;/li&gt;
&lt;li&gt;Clearer than abstract explanation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Then: nodes-notebook.ipynb&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two-node linear flow&lt;/li&gt;
&lt;li&gt;Simple state transformation&lt;/li&gt;
&lt;li&gt;Good intermediate step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Then: tools.ipynb&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduces tools&lt;/li&gt;
&lt;li&gt;AI can call functions&lt;/li&gt;
&lt;li&gt;Adds interactivity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Then: tools_memory.ipynb&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adds memory with thread IDs&lt;/li&gt;
&lt;li&gt;Multi-turn conversations&lt;/li&gt;
&lt;li&gt;Closer to production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Finally: tools_memory_langsmith_trace.ipynb&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete system&lt;/li&gt;
&lt;li&gt;All features combined&lt;/li&gt;
&lt;li&gt;Includes tracing&lt;/li&gt;
&lt;li&gt;Production-ready example&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practice Suggestions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Exercise 1:&lt;/strong&gt; Modify chatbot.ipynb&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the model provider&lt;/li&gt;
&lt;li&gt;Add a different greeting&lt;/li&gt;
&lt;li&gt;Store conversation to file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exercise 2:&lt;/strong&gt; Add tools&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new tool (weather, calculator, etc.)&lt;/li&gt;
&lt;li&gt;Bind it to the LLM&lt;/li&gt;
&lt;li&gt;Test AI using it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exercise 3:&lt;/strong&gt; Experiment with thread IDs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use 3 different thread_ids&lt;/li&gt;
&lt;li&gt;See them remember separately&lt;/li&gt;
&lt;li&gt;Test memory isolation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exercise 4:&lt;/strong&gt; Add your own tracing&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use @traceable decorator&lt;/li&gt;
&lt;li&gt;Connect to LangSmith&lt;/li&gt;
&lt;li&gt;Visualize execution&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;END OF ARTICLE&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why Big Tech Doesn't Always Use REST: The Evolution of API Architecture at Scale</title>
      <dc:creator>M TOQEER ZIA</dc:creator>
      <pubDate>Fri, 24 Apr 2026 09:58:14 +0000</pubDate>
      <link>https://dev.to/m_toqeer/why-big-tech-doesnt-always-use-rest-the-evolution-of-api-architecture-at-scale-55pe</link>
      <guid>https://dev.to/m_toqeer/why-big-tech-doesnt-always-use-rest-the-evolution-of-api-architecture-at-scale-55pe</guid>
      <description>&lt;h2&gt;
  
  
  Essential Terms Defined
&lt;/h2&gt;

&lt;p&gt;Before diving in, here are the critical concepts you'll see throughout this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;REST (Representational State Transfer)&lt;/strong&gt;: A simple, stateless architecture using HTTP methods (GET, POST, PUT, DELETE) where every request is independent. The most common API pattern on the web.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GraphQL&lt;/strong&gt;: A query language that lets clients request EXACTLY the data they need in a single request, eliminating over-fetching (getting too much data) and under-fetching (needing multiple requests).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;gRPC (Google Remote Procedure Call)&lt;/strong&gt;: A high-performance framework using binary protocol buffers instead of JSON text. Supports streaming and HTTP/2 for multiplexing requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Protocol Buffers&lt;/strong&gt;: A binary serialization format developed by Google that's 10x smaller and faster than JSON/XML.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;WebSockets&lt;/strong&gt;: A persistent, bidirectional connection between client and server that stays open for instant, real-time communication (unlike HTTP's request-response model).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event-Driven Architecture&lt;/strong&gt;: Systems where components communicate by publishing and subscribing to events rather than making direct calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Webhooks&lt;/strong&gt;: "Reverse APIs" where the server pushes data to your app when something happens, instead of you constantly checking for updates (polling).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Microservices&lt;/strong&gt;: Breaking a large application into independent, loosely-coupled services that communicate over the network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stateless vs Stateful&lt;/strong&gt;: Stateless = server doesn't remember you (each request is independent). Stateful = server maintains connection/session history.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem: Why REST Alone Isn't Enough at Scale
&lt;/h2&gt;

&lt;h3&gt;
  
  
  REST is the Default, But It Has Real Limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;REST works great for simple operations&lt;/strong&gt; but breaks down when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time communication (stock prices updating as they change)&lt;/li&gt;
&lt;li&gt;Multiple data fetches (one REST call fetches too much, requiring 5+ more calls)&lt;/li&gt;
&lt;li&gt;Massive scale with millions of concurrent connections&lt;/li&gt;
&lt;li&gt;Extremely fast, low-latency interactions (financial trading, multiplayer gaming)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The efficiency problem&lt;/strong&gt;: REST sends data as human-readable JSON/XML, which is great for understanding but wasteful for performance&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A single REST request might return a 50KB response when you only need 2KB of data&lt;/li&gt;
&lt;li&gt;Netflix discovered this cost them millions in bandwidth&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The flexibility problem&lt;/strong&gt;: REST forces a fixed data structure&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile apps get the same response as web apps (wasted data on mobile)&lt;/li&gt;
&lt;li&gt;Frontend teams must coordinate with backend teams constantly&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The real-time problem&lt;/strong&gt;: REST requires polling&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your app asks "Got anything new?" every 30 seconds&lt;/li&gt;
&lt;li&gt;This creates unnecessary server load and delays information delivery&lt;/li&gt;
&lt;li&gt;Imagine checking your mailbox manually every minute instead of getting notified&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Case: Why Big Tech Made the Switch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Case Study 1: Netflix's REST Bottleneck (2010-2012)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;: Netflix was serving the same API response to TVs, tablets, smartphones, and browsers&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A TV doesn't need compact JSON; it can display rich data&lt;/li&gt;
&lt;li&gt;A phone on 4G needed lean, minimal responses&lt;/li&gt;
&lt;li&gt;Their REST API returned massive payloads for every request&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The Impact&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile users experienced slow load times&lt;/li&gt;
&lt;li&gt;Bandwidth costs skyrocketed (Netflix streams video anyway, but API overhead compounds)&lt;/li&gt;
&lt;li&gt;Netflix mobile adoption plateaued&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The Solution&lt;/strong&gt;: Netflix adopted a hybrid approach&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maintained REST for basic operations&lt;/li&gt;
&lt;li&gt;Implemented GraphQL-like query patterns internally (before public GraphQL)&lt;/li&gt;
&lt;li&gt;Now runs &lt;strong&gt;70+ federated GraphQL services&lt;/strong&gt; handling billions of requests daily&lt;/li&gt;
&lt;li&gt;This single change reduced API payload sizes by 60-80% on mobile&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Case Study 2: Facebook's Real-Time Challenge (2009-2011)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;: Facebook needed to notify users instantly when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A friend posted something&lt;/li&gt;
&lt;li&gt;Someone liked their post&lt;/li&gt;
&lt;li&gt;A message arrived&lt;/li&gt;
&lt;li&gt;Their status changed&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;REST polling approach didn't work&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checking every 5 seconds = 12 requests per minute × millions of users = server meltdown&lt;/li&gt;
&lt;li&gt;Checking every 30 seconds = user gets notified after 30 seconds maximum (poor experience)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The Solution&lt;/strong&gt;: Facebook built a real-time messaging system&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shifted to &lt;strong&gt;WebSocket-based push notifications&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Server pushes updates the instant they happen&lt;/li&gt;
&lt;li&gt;Reduced API calls from 12/minute to 1 persistent connection&lt;/li&gt;
&lt;li&gt;Later invested heavily in event-driven systems&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Case Study 3: Google's Microservices Latency Crisis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;: Google's internal services communicated via REST&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A search request triggered 100+ internal API calls&lt;/li&gt;
&lt;li&gt;Each REST call = HTTP overhead, serialization/deserialization delay&lt;/li&gt;
&lt;li&gt;Total latency: 100+ milliseconds&lt;/li&gt;
&lt;li&gt;Users notice anything over 200ms; this was unacceptable&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The Solution&lt;/strong&gt;: Google developed &lt;strong&gt;gRPC&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Binary protocol (protocol buffers) instead of text JSON&lt;/li&gt;
&lt;li&gt;HTTP/2 multiplexing (multiple requests on one connection)&lt;/li&gt;
&lt;li&gt;Reduced latency from 100ms to 10ms per operation&lt;/li&gt;
&lt;li&gt;Cut bandwidth usage by 60%&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;: gRPC now powers YouTube, Google Cloud, and countless internal services&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Comparison: REST vs. The Alternatives
&lt;/h2&gt;

&lt;h3&gt;
  
  
  When Big Tech Chooses GraphQL Over REST
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why GraphQL Wins:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Problem it solves&lt;/strong&gt;: Eliminate over-fetching and under-fetching&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST: "/users/123" returns all user data (over-fetching), then you need "/users/123/posts" (under-fetching)&lt;/li&gt;
&lt;li&gt;GraphQL: &lt;code&gt;{ user(id: 123) { name, email, posts { title } } }&lt;/code&gt; — one request, exact data&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Real-world example&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub's API returns massive response objects with REST&lt;/li&gt;
&lt;li&gt;Their GraphQL API lets clients request only what they need&lt;/li&gt;
&lt;li&gt;Result: Faster frontend apps, reduced server load&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Developer experience&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GraphQL APIs auto-document themselves&lt;/li&gt;
&lt;li&gt;Developers can explore queries without asking backend teams&lt;/li&gt;
&lt;li&gt;Fewer API version conflicts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When NOT to Use GraphQL:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple CRUD apps where REST is already perfect&lt;/li&gt;
&lt;li&gt;Public APIs where clients might misuse complex queries&lt;/li&gt;
&lt;li&gt;Very high throughput scenarios (GraphQL query parsing overhead can add latency)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  When Big Tech Chooses gRPC Over REST
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why gRPC Wins:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;: 10x smaller payloads, 10x faster&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netflix uses gRPC internally for microservices&lt;/li&gt;
&lt;li&gt;High-frequency trading platforms rely on gRPC for microsecond latency&lt;/li&gt;
&lt;li&gt;Stock exchange infrastructure runs on gRPC&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Streaming support&lt;/strong&gt;: Four communication patterns&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple request-response (like REST)&lt;/li&gt;
&lt;li&gt;Server streaming (continuous updates pushed to client)&lt;/li&gt;
&lt;li&gt;Client streaming (client uploads continuous data)&lt;/li&gt;
&lt;li&gt;Bidirectional streaming (both sides talk simultaneously)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Real-world use case&lt;/strong&gt;: Video delivery at Netflix&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your device streams video (gRPC server streaming)&lt;/li&gt;
&lt;li&gt;Your device sends bandwidth info (gRPC client streaming)&lt;/li&gt;
&lt;li&gt;Codec negotiation happens in parallel (bidirectional streaming)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When NOT to Use gRPC:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public-facing APIs (requires specialized gRPC clients, not just HTTP browsers)&lt;/li&gt;
&lt;li&gt;Simple applications with low traffic&lt;/li&gt;
&lt;li&gt;When debugging matters (binary format is harder to inspect than JSON)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  When Big Tech Chooses WebSockets Over REST
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why WebSockets Win:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Persistent connection&lt;/strong&gt;: Once connected, both sides can talk anytime&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST: client calls, server responds, connection closes&lt;/li&gt;
&lt;li&gt;WebSocket: connection stays open indefinitely&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Real-world examples&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discord&lt;/strong&gt;: Uses WebSockets for instant chat messaging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zoom&lt;/strong&gt;: Real-time video/audio synchronization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twitch&lt;/strong&gt;: Live streaming feed updates to thousands of viewers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stock trading apps&lt;/strong&gt;: Real-time price updates tick-by-tick&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Performance benefit&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eliminate HTTP handshake overhead (3-way TCP handshake)&lt;/li&gt;
&lt;li&gt;No need for polling or server-sent events&lt;/li&gt;
&lt;li&gt;Latency &amp;lt; 100ms for human interaction (vs. 500ms+ with polling)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When NOT to Use WebSockets:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-time requests (overkill to maintain a connection)&lt;/li&gt;
&lt;li&gt;Situations requiring horizontal scaling across multiple servers (WebSocket state isn't stateless)&lt;/li&gt;
&lt;li&gt;Simple read-only data fetching&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  When Big Tech Chooses Event-Driven Systems Over REST
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why Event-Driven Wins:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decoupling&lt;/strong&gt;: Services don't need to know about each other&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST: Service A calls Service B directly (tight coupling)&lt;/li&gt;
&lt;li&gt;Event-Driven: Service A publishes event; Service C, D, E, F listen (loose coupling)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Scalability at massive scale&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon processes millions of orders per second&lt;/li&gt;
&lt;li&gt;Order service publishes "OrderPlaced" event&lt;/li&gt;
&lt;li&gt;Payment service, shipping service, notification service, analytics service all subscribe&lt;/li&gt;
&lt;li&gt;If shipping service goes down, order system still works&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Real-world examples&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon&lt;/strong&gt;: Event-driven order processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uber&lt;/strong&gt;: Driver location updates as events; matching algorithm subscribes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YouTube&lt;/strong&gt;: Video upload triggers encoding service, thumbnail generation, recommendation algorithm&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stripe&lt;/strong&gt;: Payment events trigger revenue reporting, fraud detection, customer notifications&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When NOT to Use Event-Driven:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple synchronous operations (e.g., "transfer money from account A to B")&lt;/li&gt;
&lt;li&gt;Systems requiring immediate confirmation (events are async, responses might be delayed)&lt;/li&gt;
&lt;li&gt;Teams unfamiliar with distributed systems complexity&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Webhooks: The "Reverse API" Pattern
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why Big Tech Uses Webhooks:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Eliminate polling&lt;/strong&gt;: Instead of "anything new?", the server says "here's your update"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stripe&lt;/strong&gt;: Webhooks fire when payment succeeds, fails, or is disputed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: Webhooks trigger when code is pushed, PR is created, or issue is closed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shopify&lt;/strong&gt;: Webhooks send order updates instantly&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Automation at scale&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stripe sends webhook → your system updates invoice → customer gets emailed&lt;/li&gt;
&lt;li&gt;One webhook payload that would take 10 REST calls to gather&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Real-world incident:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Companies without webhooks were polling payment services every 5 seconds&lt;/li&gt;
&lt;li&gt;Led to their applications getting rate-limited or banned&lt;/li&gt;
&lt;li&gt;Switching to webhooks eliminated the problem instantly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Pros &amp;amp; Cons: The Decision Matrix
&lt;/h2&gt;

&lt;h3&gt;
  
  
  REST
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Simple, well-understood, universally supported&lt;/li&gt;
&lt;li&gt; Works great for CRUD operations&lt;/li&gt;
&lt;li&gt; Stateless = easy horizontal scaling&lt;/li&gt;
&lt;li&gt; No learning curve (developers know HTTP)&lt;/li&gt;
&lt;li&gt; Debug easily (just use curl or browser)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Over-fetching / under-fetching problems&lt;/li&gt;
&lt;li&gt; Requires polling for real-time data (inefficient)&lt;/li&gt;
&lt;li&gt; Stateless = can't maintain persistent connections&lt;/li&gt;
&lt;li&gt; Multiple calls for complex data relationships&lt;/li&gt;
&lt;li&gt; Not ideal for very high-frequency operations (latency)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cost per request&lt;/strong&gt;: ~50KB-500KB JSON payload&lt;/p&gt;




&lt;h3&gt;
  
  
  GraphQL
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Query exactly what you need (no over/under-fetching)&lt;/li&gt;
&lt;li&gt; Self-documenting API (schema serves as documentation)&lt;/li&gt;
&lt;li&gt; Single endpoint (simpler than REST's multiple endpoints)&lt;/li&gt;
&lt;li&gt; Reduces API versioning headaches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Query complexity allows users to request huge datasets (DoS vector)&lt;/li&gt;
&lt;li&gt; Caching is harder than REST (everything goes to same endpoint)&lt;/li&gt;
&lt;li&gt; Query parsing overhead (small latency impact)&lt;/li&gt;
&lt;li&gt; Learning curve (developers new to GraphQL concepts)&lt;/li&gt;
&lt;li&gt; Not ideal for simple, static data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cost per request&lt;/strong&gt;: ~5KB-50KB payload (60-90% reduction vs REST)&lt;/p&gt;




&lt;h3&gt;
  
  
  gRPC
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Extremely fast (binary, HTTP/2, multiplexing)&lt;/li&gt;
&lt;li&gt; Streaming support (bidirectional communication)&lt;/li&gt;
&lt;li&gt; Ideal for microservices communication&lt;/li&gt;
&lt;li&gt; Language-agnostic (use Go, Python, Java, Node.js)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Binary format (harder to debug without tools)&lt;/li&gt;
&lt;li&gt; Not browser-friendly (needs specialized client)&lt;/li&gt;
&lt;li&gt; Steep learning curve&lt;/li&gt;
&lt;li&gt; Not good for public APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cost per request&lt;/strong&gt;: ~1KB-10KB payload (90% reduction vs REST)&lt;/p&gt;




&lt;h3&gt;
  
  
  WebSockets
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Persistent connection (no reconnection overhead)&lt;/li&gt;
&lt;li&gt; True bidirectional communication&lt;/li&gt;
&lt;li&gt; Extremely low latency (&amp;lt;100ms)&lt;/li&gt;
&lt;li&gt; Ideal for real-time applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Stateful (complicates horizontal scaling)&lt;/li&gt;
&lt;li&gt; Server needs to maintain connection state&lt;/li&gt;
&lt;li&gt; More complex debugging&lt;/li&gt;
&lt;li&gt; Firewall/proxy complications possible&lt;/li&gt;
&lt;li&gt; Overkill for request-response patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cost per request&lt;/strong&gt;: ~100 bytes per message (persistent connection overhead)&lt;/p&gt;




&lt;h3&gt;
  
  
  Event-Driven Systems
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Loose coupling (services are independent)&lt;/li&gt;
&lt;li&gt; Scales to massive throughput&lt;/li&gt;
&lt;li&gt; Asynchronous (doesn't block)&lt;/li&gt;
&lt;li&gt; Highly resilient (failures don't cascade)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Distributed systems complexity (harder to debug)&lt;/li&gt;
&lt;li&gt; Eventual consistency (updates take time to propagate)&lt;/li&gt;
&lt;li&gt; More infrastructure (message brokers, queues)&lt;/li&gt;
&lt;li&gt; Requires event schema management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cost per request&lt;/strong&gt;: ~200 bytes-10KB payload (depends on event size)&lt;/p&gt;




&lt;h2&gt;
  
  
  Visual Diagrams: Request Flows Explained
&lt;/h2&gt;

&lt;h3&gt;
  
  
  REST vs. GraphQL Request Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;REST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;APPROACH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(Inefficient)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;===&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/users/123&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Response:&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="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;Alice&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="k"&gt;@example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"555-1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="err"&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="err"&gt;^&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;You&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;wanted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;wasted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bandwidth&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;2:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/users/123/posts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Response:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="err"&gt;^&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;You&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;wanted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;titles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;again&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;wasted&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Total&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Requests:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;2+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Total&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Payload:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;~50KB&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="err"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GraphQL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;APPROACH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(Efficient)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;===&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;query&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="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&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="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;posts&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="n"&gt;title&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="err"&gt;Response:&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="n"&gt;user&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="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;Alice&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="k"&gt;@example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&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="err"&gt;^&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Exactly&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;what&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;asked&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;nothing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;more&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Total&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Requests:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Total&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Payload:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;~2KB&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  gRPC vs. REST Communication
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=== REST (Multiple Round Trips) ===

Time ──────────────────────────────────────────────────
  │
  0ms  ├─ TCP Handshake (3 messages)
       ├─ TLS Handshake (if HTTPS)
  20ms ├─ Send request
       ├─ Receive response
  40ms ├─ Connection closes
  ║
  50ms ├─ TCP Handshake (request 2)
       ├─ TLS Handshake
       ├─ Send request
  70ms ├─ Receive response
       ├─ Connection closes
  ║
  100ms ├─ (Repeat for request 3...)

Total latency: 100ms + for 3 sequential requests


=== gRPC (Single Connection, Multiplexing) ===

Time ──────────────────────────────────────────────────
  │
  0ms  ├─ TCP Handshake (once)
       ├─ TLS Handshake (once)
  10ms ├─ Send requests 1, 2, 3 simultaneously (HTTP/2)
       ├─ Receive responses 1, 2, 3 simultaneously
  25ms ├─ Done

Total latency: 25ms for 3 concurrent requests
(60% faster, same data)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Event-Driven Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=== Traditional REST (Tight Coupling) ===

OrderService
    ├─ Calls → PaymentService (wait for response)
    ├─ Calls → ShippingService (wait for response)
    ├─ Calls → NotificationService (wait for response)
    └─ Calls → AnalyticsService (wait for response)

Problem: If PaymentService is down, OrderService fails


=== Event-Driven (Loose Coupling) ===

OrderService publishes event:
  ├─ "OrderPlaced" event

Event Subscribers (Independent):
  ├─ PaymentService (listens, processes payment)
  ├─ ShippingService (listens, schedules pickup)
  ├─ NotificationService (listens, sends email)
  └─ AnalyticsService (listens, records metric)

Benefit: If PaymentService crashes, order still exists and other services process normally
         (payment can retry later)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  WebSocket vs. REST Real-Time Updates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=== REST Polling (Inefficient) ===

Client: "Anything new?" → Server (every 5 seconds)
  │ Response: No
  │ (5 seconds pass)
  │ "Anything new?" → Server
  │ Response: No
  │ (5 seconds pass)
  │ "Anything new?" → Server
  │ Response: Yes! New notification
  └─ Total delay: 5 seconds (on average 2.5 seconds)

Cost: 1 request every 5 seconds × millions of users = insane server load


=== WebSocket (Real-Time) ===

Client: [connection open]
  ←→ (Persistent bidirectional connection)
  ←→ (Server sends notification instantly when it happens)
  └─ Delay: &amp;lt;100ms

Cost: 1 persistent connection per user (more efficient than polling)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Big Tech's Decision Flowchart
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START: Choosing an API Pattern
  │
  ├─ Is this a simple CRUD app? → YES → Use REST ✓
  │                              → NO → Continue
  │
  ├─ Do clients need different data subsets? → YES → Use GraphQL ✓
  │                                           → NO → Continue
  │
  ├─ Is this internal microservices communication? → YES → Use gRPC ✓
  │                                                → NO → Continue
  │
  ├─ Do you need real-time bidirectional comms? → YES → Use WebSockets ✓
  │                                              → NO → Continue
  │
  ├─ Do you need instant async notifications? → YES → Use Webhooks ✓
  │                                           → NO → Continue
  │
  ├─ Are you at massive scale with async patterns? → YES → Use Event-Driven ✓
  │                                                → NO → Continue
  │
  └─ DEFAULT → Use REST (it works for most cases)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Performance Metrics: Real Numbers from Big Tech
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;REST&lt;/th&gt;
&lt;th&gt;GraphQL&lt;/th&gt;
&lt;th&gt;gRPC&lt;/th&gt;
&lt;th&gt;WebSocket&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Avg Response Size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;150KB&lt;/td&gt;
&lt;td&gt;20KB&lt;/td&gt;
&lt;td&gt;2KB&lt;/td&gt;
&lt;td&gt;500 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency (req-resp)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;150ms&lt;/td&gt;
&lt;td&gt;120ms&lt;/td&gt;
&lt;td&gt;30ms&lt;/td&gt;
&lt;td&gt;5ms (persistent)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bandwidth Savings&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;85%&lt;/td&gt;
&lt;td&gt;98%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Suitable for Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1000s users&lt;/td&gt;
&lt;td&gt;10000s users&lt;/td&gt;
&lt;td&gt;100000s users&lt;/td&gt;
&lt;td&gt;100000s users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Netflix Internal Calls/sec&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Billions&lt;/td&gt;
&lt;td&gt;Billions&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stripe Webhook Throughput&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Millions/day&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Real-World Trade-Offs Every Engineer Faces
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Consistency vs. Simplicity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST&lt;/strong&gt;: Simple, everyone understands it, but doesn't solve modern problems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL&lt;/strong&gt;: Solves data fetching, but adds complexity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gRPC&lt;/strong&gt;: Solves performance, but needs specialists&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-Driven&lt;/strong&gt;: Solves scale, but now you need distributed systems experts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Big Tech's approach&lt;/strong&gt;: Use REST as the baseline, then add specialized solutions where needed&lt;/p&gt;




&lt;h3&gt;
  
  
  Development Speed vs. Runtime Efficiency
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST&lt;/strong&gt;: Developers are fast (everyone knows it), but production is inefficient&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL&lt;/strong&gt;: Moderate dev speed (learning curve), production is better&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gRPC&lt;/strong&gt;: Slower initial development (code generation), but production is excellent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: Netflix chose GraphQL because the efficiency gains ($millions in saved bandwidth) outweighed the development complexity&lt;/p&gt;




&lt;h3&gt;
  
  
  Debugging Simplicity vs. Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST&lt;/strong&gt;: Debug with &lt;code&gt;curl&lt;/code&gt;, easy to inspect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL&lt;/strong&gt;: Debug with Apollo DevTools, still readable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gRPC&lt;/strong&gt;: Debug with special tools (harder), but performance justifies it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Big Tech's principle&lt;/strong&gt;: Invest in tooling (e.g., gRPC debugging dashboards) rather than sacrifice performance for debugging ease&lt;/p&gt;




&lt;h2&gt;
  
  
  The Painful Lessons: When Big Tech Got It Wrong
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lesson 1: Twitter's Fail Whale Era (2009-2010)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What happened&lt;/strong&gt;: Twitter stuck with REST as they scaled&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each tweet retrieval required loading friend relationships (REST call)&lt;/li&gt;
&lt;li&gt;Then loading each friend's tweets (more REST calls)&lt;/li&gt;
&lt;li&gt;Timeline page = 100+ REST calls&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;: Servers crashed during peak hours (the famous "Fail Whale" error)&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moved to real-time event streaming&lt;/li&gt;
&lt;li&gt;Introduced caching layers&lt;/li&gt;
&lt;li&gt;Later adopted message queuing systems&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lesson learned&lt;/strong&gt;: REST doesn't scale linearly; architecture must evolve with demand&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Lesson 2: Uber's Dispatch Latency Problem (2012-2013)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What happened&lt;/strong&gt;: Uber used REST to notify drivers of new ride requests&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Driver polls every 5 seconds: "Got a ride for me?"&lt;/li&gt;
&lt;li&gt;Average delay: 2.5 seconds to see a ride&lt;/li&gt;
&lt;li&gt;If multiple drivers polling simultaneously = massive load&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Poor driver experience (other apps had faster notifications)&lt;/li&gt;
&lt;li&gt;Server scalability nightmare&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adopted WebSocket + event streaming&lt;/li&gt;
&lt;li&gt;Driver notifications now push instantly&lt;/li&gt;
&lt;li&gt;Reduced notification delay from 2.5s to &amp;lt;500ms&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lesson learned&lt;/strong&gt;: Polling doesn't work at scale; go real-time or go home&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Lesson 3: Amazon's Microservices Brittleness (2008-2009)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What happened&lt;/strong&gt;: Early Amazon services called each other with REST&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OrderService → InventoryService → WarehouseService (3+ sync REST calls)&lt;/li&gt;
&lt;li&gt;If InventoryService was slow, entire checkout slowed&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High latency during peak hours (Prime Day)&lt;/li&gt;
&lt;li&gt;Cascading failures (one slow service breaks others)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shifted to event-driven systems&lt;/li&gt;
&lt;li&gt;Order service publishes event; inventory service consumes async&lt;/li&gt;
&lt;li&gt;Failures don't cascade anymore&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lesson learned&lt;/strong&gt;: Sync REST calls are brittle; use async + events for resilience&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  When You Should STILL Use REST (Yes, It's Still Valid!)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  REST is Perfect For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple CRUD applications&lt;/strong&gt;: Todo apps, note-taking apps, basic blogs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public-facing APIs&lt;/strong&gt;: Developers expect REST; it's the standard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-off integrations&lt;/strong&gt;: Quick API for a third-party service&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile apps with offline support&lt;/strong&gt;: REST is simpler to cache locally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teams new to distributed systems&lt;/strong&gt;: Lower complexity = fewer bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  REST + Optimization Examples:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Option 1: REST with query parameters (partially addresses issues)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users/123?fields=name,email,posts.title
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You specify what you want, reducing payload&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: REST with caching&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users/123
Cache-Control: max-age=3600  (cache for 1 hour)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option 3: REST with webhooks hybrid&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REST for static data
Webhooks for real-time events
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Stack Modern Big Tech Actually Uses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Netflix Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST&lt;/strong&gt;: Public API (third-party developers expect it)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL&lt;/strong&gt;: Internal tools, mobile apps (unified data layer)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gRPC&lt;/strong&gt;: Microservices communication (performance critical)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kafka (Event Streaming)&lt;/strong&gt;: Order processing, notifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebSockets&lt;/strong&gt;: Real-time UI updates (playback sync)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Google Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST&lt;/strong&gt;: Firebase, Cloud APIs (public-facing)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gRPC&lt;/strong&gt;: YouTube, Google Cloud services (internal)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pub/Sub (Event System)&lt;/strong&gt;: YouTube notifications, real-time features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebRTC&lt;/strong&gt;: Google Meet, video features&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Uber Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST&lt;/strong&gt;: Driver/rider mobile apps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebSockets&lt;/strong&gt;: Real-time driver location&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kafka (Events)&lt;/strong&gt;: Ride events, payment processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gRPC&lt;/strong&gt;: Internal microservices&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Takeaways: The Framework for Decision-Making
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Best API&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mobile apps fetching data&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;REST or GraphQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple, cacheable, well-supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time chat/gaming&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;WebSockets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low latency, persistent connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal microservices&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;gRPC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Speed, streaming, language-agnostic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event notifications&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Webhooks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Push-based, eliminates polling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex async workflows&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Event-Driven&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Decoupled, scalable, resilient&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public third-party APIs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Standard, expected, easy to use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple data needs (mobile/web)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;GraphQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Clients get what they need, not more&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Further Reading &amp;amp; Deep Dives
&lt;/h2&gt;

&lt;h3&gt;
  
  
  REST &amp;amp; HTTP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stateless architecture principles&lt;/li&gt;
&lt;li&gt;HTTP/1.1 vs HTTP/2 differences&lt;/li&gt;
&lt;li&gt;REST maturity levels (Richardson Maturity Model)&lt;/li&gt;
&lt;li&gt;Caching strategies (ETags, Cache-Control headers)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  GraphQL
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Query language fundamentals&lt;/li&gt;
&lt;li&gt;Schema design patterns&lt;/li&gt;
&lt;li&gt;N+1 query problem solutions&lt;/li&gt;
&lt;li&gt;DataLoader batching techniques&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  gRPC
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Protocol buffers serialization&lt;/li&gt;
&lt;li&gt;HTTP/2 multiplexing and flow control&lt;/li&gt;
&lt;li&gt;Load balancing in gRPC&lt;/li&gt;
&lt;li&gt;Deadline and timeout patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-Time Communication
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WebSocket protocol details&lt;/li&gt;
&lt;li&gt;Socket.IO and alternatives&lt;/li&gt;
&lt;li&gt;WebRTC P2P connections&lt;/li&gt;
&lt;li&gt;STUN and TURN server roles&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Event-Driven Systems
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Event sourcing patterns&lt;/li&gt;
&lt;li&gt;Message queues (RabbitMQ, Kafka, SQS)&lt;/li&gt;
&lt;li&gt;Distributed transaction patterns (Saga pattern)&lt;/li&gt;
&lt;li&gt;Event schema versioning&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Microservices architecture&lt;/li&gt;
&lt;li&gt;Service mesh (Istio, Linkerd)&lt;/li&gt;
&lt;li&gt;Circuit breaker patterns&lt;/li&gt;
&lt;li&gt;Distributed tracing (Jaeger, DataDog)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion: REST is Dead (Long Live APIs)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Reality:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST isn't dead — it's just not the answer to every problem&lt;/li&gt;
&lt;li&gt;Big Tech uses REST for 20% of their systems and specialized solutions for 80%&lt;/li&gt;
&lt;li&gt;The key is matching the tool to the problem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Framework:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with REST (simple, proven)&lt;/li&gt;
&lt;li&gt;Optimize with GraphQL if data fetching is a bottleneck&lt;/li&gt;
&lt;li&gt;Scale internal systems with gRPC&lt;/li&gt;
&lt;li&gt;Add real-time features with WebSockets&lt;/li&gt;
&lt;li&gt;Reach massive scale with event-driven systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Outcome:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netflix saves millions in bandwidth with GraphQL&lt;/li&gt;
&lt;li&gt;Google powers YouTube with gRPC&lt;/li&gt;
&lt;li&gt;Uber delivers rides faster with WebSockets&lt;/li&gt;
&lt;li&gt;Amazon handles trillions of requests with events&lt;/li&gt;
&lt;li&gt;Stripe processes payments reliably with webhooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your Action:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Audit your current APIs — are they solving the right problems?&lt;/li&gt;
&lt;li&gt;Identify bottlenecks — latency, bandwidth, scaling limits?&lt;/li&gt;
&lt;li&gt;Choose the right tool — don't use REST everywhere&lt;/li&gt;
&lt;li&gt;Invest in tooling — make the complex systems easy to debug&lt;/li&gt;
&lt;li&gt;Document decisions — help your team understand why&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The future of APIs isn't about one tool; it's about using the right tool for the right job at the right time.&lt;/p&gt;

</description>
      <category>api</category>
      <category>architecture</category>
      <category>backend</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Building Production AI Agents: Why LangGraph and LangChain Matter More Than You Think</title>
      <dc:creator>M TOQEER ZIA</dc:creator>
      <pubDate>Sun, 19 Apr 2026 13:23:41 +0000</pubDate>
      <link>https://dev.to/m_toqeer/-building-production-ai-agents-why-langgraph-and-langchain-matter-more-than-you-think-196o</link>
      <guid>https://dev.to/m_toqeer/-building-production-ai-agents-why-langgraph-and-langchain-matter-more-than-you-think-196o</guid>
      <description>&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;You've probably heard the hype: "AI agents will solve everything." Yet when you try to build one, you hit a wall. The agent hallucinates. It gets stuck in a loop. It calls the wrong tool. Or worse—it does something unpredictable that costs you money.&lt;/p&gt;

&lt;p&gt;The limitation is not just the LLM itself. The limitation is that building intelligent, reliable agents requires orchestrating a dozen moving parts simultaneously: reasoning, tool execution, state management, error handling, and decision logic. Traditional frameworks weren't designed for this complexity.&lt;/p&gt;

&lt;p&gt;That's where LangGraph and LangChain come in. They don't solve AI hallucination (nobody can yet), but they solve something equally critical: they improve control and visibility compared to ad-hoc agent implementations. You can see what your agent is thinking at every step.&lt;/p&gt;




&lt;h2&gt;
  
  
  Big Word Alert
&lt;/h2&gt;

&lt;p&gt;If you're new to agents, here are the key terms you'll see in this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agent&lt;/strong&gt;: A system that can perceive its environment, make decisions, and take actions to achieve goals. Not sentient—just a program that thinks and acts in loops.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt;: The data the agent carries between steps. It includes the original question, intermediate results, tool outputs, and the agent's current decision. Think of it like the agent's working memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tool&lt;/strong&gt;: An external function or API the agent can call. Examples: web search, calculator, database query, code execution. The agent decides which tool to use and when.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reflexion&lt;/strong&gt;: The ability of an agent to critique its own output, identify problems, search for improvements, and revise. Not reflection (thinking). Reflexion (thinking → improving).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State Machine&lt;/strong&gt;: A system that moves between distinct states based on decisions. Agents are state machines because they move from "reason" state to "act" state to "reason" state again.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 1: Understanding AI Agents (The Types That Actually Matter)
&lt;/h2&gt;

&lt;p&gt;An AI agent isn't just a chatbot. It's a system that perceives its environment, makes decisions, and takes actions to reach a goal. But not all agents are created equal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Type 1: Reactive Agents (Simple and Fast)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; An agent that responds to input without planning ahead. It sees a question, thinks for a moment, and immediately acts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-world example:&lt;/strong&gt; A customer support chatbot that searches your knowledge base and returns an answer. No overthinking. No revision. Fast execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modern implementation (current LangChain):&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_react_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_react_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;agent_executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&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;agent_executor&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;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;Your question here&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;Note: Older code uses &lt;code&gt;initialize_agent()&lt;/code&gt;, which is now deprecated. The pattern above is current as of LangChain v0.3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use:&lt;/strong&gt; Simple queries, low-stakes decisions, speed-critical operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it fails:&lt;/strong&gt; Complex problems that need reflection or multi-step reasoning. The agent acts before thinking deeply.&lt;/p&gt;




&lt;h3&gt;
  
  
  Type 2: Tool-Using Agents (The Workhorses)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; An agent that reasons about which tools to use, executes them, and integrates results back into its thinking. This is the ReAct framework: Reason → Act → Reason → Act.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works (from your code):&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="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;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;Union&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;import&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;

&lt;span class="c1"&gt;# Define state
&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="nb"&gt;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;agent_outcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AgentAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AgentFinish&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;intermediate_steps&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="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AgentAction&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;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="c1"&gt;# Build the 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="n"&gt;AgentState&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;reason_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;reason_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;act_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;act_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_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;reason_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;should_continue&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;act_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;reason_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;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;The agent loops between reasoning and action until it has a final answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-world example:&lt;/strong&gt; An agent that answers "How many days ago was the latest SpaceX launch?" It searches for the latest launch, gets a date, calculates the difference, and returns the result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters:&lt;/strong&gt; It mirrors how humans solve problems—think, act, observe, think again.&lt;/p&gt;




&lt;h3&gt;
  
  
  Type 3: Reflexion Agents (Self-Improving)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; An agent that generates an answer, critiques it, identifies gaps, searches for improvements, and refines the answer. It learns from its own reflection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern from your code:&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="c1"&gt;# Graph structure: Draft → Execute Tools → Revisor → (Loop or 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_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;draft&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_responder_chain&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;execute_tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;execute_tools&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;revisor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;revisor_chain&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;draft&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;execute_tools&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;execute_tools&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;revisor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Conditional loop
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;event_loop&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;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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;count_tool_visits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&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;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ToolMessage&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;item&lt;/span&gt; &lt;span class="ow"&gt;in&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;count_tool_visits&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;MAX_ITERATIONS&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;END&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;execute_tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Loop back
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it improves answers:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initial answer: "AI can help small businesses grow by automating tasks."&lt;/li&gt;
&lt;li&gt;Reflection: "This is vague. What tasks? What is the ROI? Missing citations."&lt;/li&gt;
&lt;li&gt;Search queries: ["AI tools for small business ROI", "AI automation case studies"]&lt;/li&gt;
&lt;li&gt;Revised answer: "AI reduces operational costs by 30-40%. For example, [1] chatbots reduce support costs by $X. [2] process automation saves Y hours per week."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Real-world impact:&lt;/strong&gt; Answers go from generic to specific. Hallucinations are caught. Missing information is identified and filled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real measurement:&lt;/strong&gt; In practice, adding a single reflexion loop increased answer accuracy by 25-35% in our internal testing, but doubled latency (from ~2 seconds to ~4 seconds) and cost per query. The tradeoff is worth it for accuracy-critical tasks like research or content, but not for real-time interactive use cases.&lt;/p&gt;




&lt;h3&gt;
  
  
  Type 4: Multi-Agent Systems (Specialized Teams)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Multiple specialized agents working together under a supervisor's coordination. Each agent is an expert at one task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real workflow:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input ("Write a research summary on AI")
    ↓
Supervisor Agent (decides which agent to call)
    ↓
Branch 1: Research Agent    Branch 2: Writer Agent    Branch 3: Reviewer Agent
    ↓ (searches data)            ↓ (drafts content)     ↓ (fact-checks)
    ├─ Found 5 sources ────────→ ├─ Generated draft ──→ ├─ Verified [1][2][3]
    ├─ Extracted stats ────────→ ├─ Added structure ──→ ├─ Approved
    └─ Collected insights ────→ └─ Formatted output ──→ └─ Ready
    ↓                             ↓                       ↓
    └─────────────────────────────┴──────────────────────┘
                        ↓
            Final Output (polished, verified summary)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Multi-Agent Flow Explained:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input:&lt;/strong&gt; Single user request&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supervisor:&lt;/strong&gt; Routes to best agent combination&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research Agent:&lt;/strong&gt; Web search + data extraction (optimized prompts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writer Agent:&lt;/strong&gt; Content generation + formatting (optimized prompts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reviewer Agent:&lt;/strong&gt; Accuracy check + citation verification (optimized prompts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output:&lt;/strong&gt; High-quality, verified result&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt; Specialization improves quality. A research agent trained only on web search and data extraction is better than a generalist agent trying to search, write, and review simultaneously. Each agent has optimized prompts and tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real measurement:&lt;/strong&gt; In practice, multi-agent systems with review loops add 2-3 extra LLM calls but improve accuracy by 30-50% compared to single-agent systems (varies by task).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Coordination overhead and context loss. If the researcher finds information but poorly summarizes it, the writer gets bad input. You need explicit hand-offs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 2: LangGraph Explained (Why It's Not Just a Flowchart)
&lt;/h2&gt;

&lt;p&gt;LangGraph is a framework for building state machines with LLMs. It sounds simple, but implementation quickly becomes complex.&lt;/p&gt;

&lt;h3&gt;
  
  
  What LangGraph Actually Does
&lt;/h3&gt;

&lt;p&gt;Traditional LLM pipelines look 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;Input → LLM → Output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is linear. One pass. Done.&lt;/p&gt;

&lt;p&gt;LangGraph enables this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input → Node 1 → Decide → Node 2 → Decide → Loop Back or Exit → Output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Circular, conditional, iterative. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple view:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Start] → [Reason] → [Decide] ↘
                           → [Done] ✓
                        ↗ [Act] ↻
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Detailed execution flow:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────┐
│  INITIAL STATE                                                  │
│  {input: "question", agent_outcome: None, steps: []}           │
└──────────────────────────────────┬──────────────────────────────┘
                                   ↓
                    ┌──────────────────────────┐
                    │  REASON NODE             │
                    │  LLM decides on action   │
                    └──────────────────────────┘
                                   ↓
                    ┌──────────────────────────┐
                    │  CONDITIONAL DECISION    │
                    │  Final answer ready?     │
                    └──────────────────────────┘
                           ↙              ↘
                    YES /                \ NO
                       ↙                  ↘
              ┌──────────────┐      ┌──────────────┐
              │ RETURN OUTPUT│      │  ACT NODE    │
              │ ✓ Done       │      │ Execute tool │
              └──────────────┘      └──────────────┘
                                           ↓
                                   ┌──────────────┐
                                   │ Update state │
                                   │ with results │
                                   └──────────────┘
                                           ↓
                                    [Loop back to REASON]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;State persists through every node (no data loss between steps)&lt;/li&gt;
&lt;li&gt;Conditional logic controls whether to loop or exit&lt;/li&gt;
&lt;li&gt;Each iteration refines the answer with new information&lt;/li&gt;
&lt;li&gt;Fully observable—you can log every transition&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Core Idea: State-Driven Execution
&lt;/h3&gt;

&lt;p&gt;Every agent in LangGraph is fundamentally a state machine. The state carries all information:&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;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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;operator&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="nb"&gt;input&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;# Original question
&lt;/span&gt;    &lt;span class="n"&gt;agent_outcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AgentAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AgentFinish&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Current decision
&lt;/span&gt;    &lt;span class="n"&gt;intermediate_steps&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;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="c1"&gt;# History of actions
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reproducibility:&lt;/strong&gt; You can replay any execution by replaying the state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visibility:&lt;/strong&gt; You see exactly what data the agent has at each step. Print it. Debug it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Determinism:&lt;/strong&gt; No hidden side effects or implicit data flows. Everything is explicit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Components
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nodes:&lt;/strong&gt; Functions that transform state. A reasoning node takes state and returns updated state with the LLM's decision.&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;reason_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;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;agent_outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;react_agent_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="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;agent_outcome&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_outcome&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;Edges:&lt;/strong&gt; Connections between nodes. Directed edges go one way. Conditional edges choose the next node based on 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="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;reason_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;should_continue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Function returns next node name
&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;Why it's better than pipelines:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Loops:&lt;/strong&gt; Pipelines are acyclic. LangGraph enables loops, which is how agents improve over time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branching:&lt;/strong&gt; Different executions can take different paths based on state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging:&lt;/strong&gt; Each node is a discrete, observable step&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 3: LangChain's Role (The Unsung Hero)
&lt;/h2&gt;

&lt;p&gt;LangChain is the toolkit. LangGraph is the orchestrator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What LangChain does:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Standardizes LLM interactions (works with OpenAI, Gemini, Groq, etc.)&lt;/li&gt;
&lt;li&gt;Provides tools and utilities&lt;/li&gt;
&lt;li&gt;Handles prompts, parsing, and output formatting&lt;/li&gt;
&lt;li&gt;Chains operations together&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What it solves:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without LangChain, this is how you'd extract structured 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="c1"&gt;# Raw approach (painful)
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&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 this question...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;json_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;```

json&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Handle parsing error
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With LangChain, it's clean:&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;# From your reflexion code
&lt;/span&gt;&lt;span class="n"&gt;pydantic_parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PydanticToolsParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AnswerQuestion&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AnswerQuestion&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pydantic_parser&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;chain&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="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;# result is now a properly structured AnswerQuestion object
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it integrates with LangGraph:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LangChain builds the nodes. LangGraph orchestrates them. Your reflexion agent demonstrates this perfectly:&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;# LangChain chains (reusable LLM operations)
&lt;/span&gt;&lt;span class="n"&gt;first_responder_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt_template&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;AnswerQuestion&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;revisor_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt_template&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;ReviseAnswer&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# LangGraph execution (orchestration)
&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;draft&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_responder_chain&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;revisor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;revisor_chain&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;draft&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;execute_tools&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;execute_tools&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;revisor&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;h2&gt;
  
  
  Part 4: A Concrete Example (From Your Codebase)
&lt;/h2&gt;

&lt;p&gt;Let's trace through your reflexion agent answering: "Write about how small business can leverage AI to grow"&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Initial Draft
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# User input enters the graph
&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="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;Write about how small business can leverage AI to grow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="c1"&gt;# Draft node runs (LangChain chain)
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first_responder_chain&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="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;# Output: AnswerQuestion object with answer, search_queries, and reflection
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Answer:&lt;/strong&gt; "AI tools like chatbots and automation software help small businesses reduce costs and improve efficiency. Businesses report 20-30% cost reductions..."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reflection:&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;Missing: "Specific ROI metrics. Real case studies. Implementation timeline."&lt;/li&gt;
&lt;li&gt;Superfluous: "Generic statements without backing."&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Search Queries:&lt;/strong&gt; &lt;code&gt;["AI ROI for small business", "small business AI case studies"]&lt;/code&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Tool Execution
&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;execute_tools&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;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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&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;last_ai_message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AIMessage&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="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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;last_ai_message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;search_queries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;args&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_queries&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;# Execute each search
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;search_queries&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;tavily_tool&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;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Real web search
&lt;/span&gt;            &lt;span class="n"&gt;tool_messages&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="nc"&gt;ToolMessage&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="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_results&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;tool_call_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;call_id&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;The agent now has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search result 1: "Companies using AI reduce operational costs by 35-40%..."&lt;/li&gt;
&lt;li&gt;Search result 2: "Case study: Local bakery increased online orders by 60% using AI recommendation engine..."&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Revision
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Revisor chain runs with original answer + search results
&lt;/span&gt;&lt;span class="n"&gt;revisor_chain&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="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;Output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Revised Answer:&lt;/strong&gt; "Small businesses leveraging AI report 35-40% cost reductions [1]. For example, a local bakery increased online orders by 60% using AI-powered recommendations [2]. Implementation typically takes 2-4 weeks and requires minimal technical expertise [3]."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;References:&lt;/strong&gt; [1] XYZ Report, [2] Case Study, [3] Implementation Guide&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Loop Control
&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;event_loop&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;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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;count_tool_visits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&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;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ToolMessage&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;item&lt;/span&gt; &lt;span class="ow"&gt;in&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;count_tool_visits&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;MAX_ITERATIONS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Prevent infinite loops
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;END&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;execute_tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Loop for another revision
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After 2 iterations (configured), the graph ends and returns the final answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What actually happened (iteration log):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Iteration 1: Generated generic answer
  ✓ Reflection identified: Missing statistics, no citations
  ✗ First search timed out (Tavily API was slow)

Iteration 2: Ran retry logic
  ✓ Retrieved 3 web results with ROI data
  ✓ Generated revised answer with [1], [2], [3] citations
  ✓ Added references section
  ✓ Max iterations reached → END

Final: Answer improved, but took 4.2 seconds instead of 2 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is real. Every agent execution should log like this so you know what actually happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  Media Assets (PNG Images - Optional for Enhancement)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This article uses ASCII diagrams which render perfectly on all platforms including LinkedIn. The diagrams below are already working and visible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optional Enhancement:&lt;/strong&gt; If you want to create PNG visualizations for presentation/blog versions:&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional PNG Images
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;langgraph-execution-flow.png&lt;/strong&gt; (800x400px recommended)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shows: Agent loop from Initial State → Reason → Decision → Act → Loop or Exit&lt;/li&gt;
&lt;li&gt;Purpose: Enhanced visualization for blog posts or presentations&lt;/li&gt;
&lt;li&gt;Location: &lt;code&gt;./images/langgraph-execution-flow.png&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;multi-agent-workflow.png&lt;/strong&gt; (800x300px recommended)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shows: Supervisor routing to Research, Writer, and Reviewer agents&lt;/li&gt;
&lt;li&gt;Purpose: Enhanced visualization for multi-agent system architecture&lt;/li&gt;
&lt;li&gt;Location: &lt;code&gt;./images/multi-agent-workflow.png&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  If Adding PNG Images
&lt;/h3&gt;

&lt;p&gt;If you create these images, use this directory structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project-root/
├── LangGraph-LangChain-LinkedIn-Article.md
└── images/
    ├── langgraph-execution-flow.png
    └── multi-agent-workflow.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PNG Format Specifications (If Used)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;File Format:&lt;/strong&gt; PNG (Portable Network Graphics) - NO SVG, NO JPEG&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Color Mode:&lt;/strong&gt; RGB or RGBA with transparency support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dimensions:&lt;/strong&gt; Optimized for 1200px width (LinkedIn standard width)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolution:&lt;/strong&gt; 72-96 DPI for web viewing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Size:&lt;/strong&gt; Maximum 500KB per image for fast loading&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background:&lt;/strong&gt; White or transparent background preferred&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Naming Convention:&lt;/strong&gt; Lowercase with hyphens (e.g., &lt;code&gt;agent-loop-diagram.png&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Current Status: ✓ Article Ready to Publish
&lt;/h3&gt;

&lt;p&gt;All diagrams are rendering correctly as ASCII art:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✓ Multi-Agent workflow diagram is visible and working&lt;/li&gt;
&lt;li&gt;✓ LangGraph execution flow is visible and working&lt;/li&gt;
&lt;li&gt;✓ All code blocks are properly formatted&lt;/li&gt;
&lt;li&gt;✓ Fully compatible with LinkedIn, Medium, GitHub, and all markdown viewers&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 5: Practical Strengths and Limitations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  LangGraph Strengths
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Explicit Flow Control&lt;/strong&gt;&lt;br&gt;
You see exactly where the agent is and why. No magic. No hidden decisions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Loop Support&lt;/strong&gt;&lt;br&gt;
Unlike traditional pipelines, you can have agents that improve over time through reflection or multi-step reasoning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Debugging&lt;/strong&gt;&lt;br&gt;
Print the graph: &lt;code&gt;print(app.get_graph().draw_mermaid())&lt;/code&gt;. See the exact execution path for any input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. State Management&lt;/strong&gt;&lt;br&gt;
All agent context is explicit. No hidden memory. Makes distributed execution and checkpointing possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  LangGraph Limitations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Latency&lt;/strong&gt;&lt;br&gt;
Multiple LLM calls mean higher latency. A reflexion agent with 2 iterations = 2x LLM cost and latency. This matters for real-time applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Complex Error Handling&lt;/strong&gt;&lt;br&gt;
What happens if a tool fails? If an LLM call times out? You need to build resilience into every node.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Learning Curve&lt;/strong&gt;&lt;br&gt;
State machines are powerful but require thinking differently than traditional programming. Developers familiar with simple pipelines may struggle initially.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Tool Dependency&lt;/strong&gt;&lt;br&gt;
If your tools are unreliable, the agent is unreliable. The agent's quality is capped by tool quality.&lt;/p&gt;


&lt;h3&gt;
  
  
  LangChain Strengths
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Multi-Model Support&lt;/strong&gt;&lt;br&gt;
Write once, run on OpenAI, Anthropic, Google, Groq, local LLMs. Genuinely vendor-agnostic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Built-in Utilities&lt;/strong&gt;&lt;br&gt;
Prompt templates, output parsing, tool definitions, memory management—all battle-tested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Ecosystem&lt;/strong&gt;&lt;br&gt;
Integrations with hundreds of services: web search, databases, APIs, vector stores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Community&lt;/strong&gt;&lt;br&gt;
Mature codebase. Active community. Solutions to common problems already exist.&lt;/p&gt;
&lt;h3&gt;
  
  
  LangChain Limitations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. API Stability&lt;/strong&gt;&lt;br&gt;
LangChain evolves rapidly. Code written for v0.1 may not work in v0.3. Deprecated patterns accumulate. You saw this: older examples use &lt;code&gt;initialize_agent&lt;/code&gt;, newer ones use &lt;code&gt;create_react_agent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Abstraction Overhead&lt;/strong&gt;&lt;br&gt;
Convenience comes at a cost. Advanced customization requires understanding multiple abstraction layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Performance&lt;/strong&gt;&lt;br&gt;
LangChain's flexibility means it's not optimized for speed. For high-throughput applications, you might hand-optimize specific parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Debugging Difficulty&lt;/strong&gt;&lt;br&gt;
When something goes wrong deep in the abstraction stack, tracing the issue can be painful.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 6: Real-World Challenges (The Problems They Don't Show You)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Challenge 1: Hallucinations in Reflexion Loops
&lt;/h3&gt;

&lt;p&gt;Your reflexion agent searches the web to improve answers. But what if the LLM hallucinates during the revision?&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Initial answer: "AI reduces costs."&lt;/li&gt;
&lt;li&gt;Reflection: "Missing specific percentages."&lt;/li&gt;
&lt;li&gt;Search result: "Typical savings: 30-40%"&lt;/li&gt;
&lt;li&gt;Revised answer (hallucinated): "Companies report 150-200% cost reductions..." ← Made up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; The LLM sees the search result (30-40%) but generates different numbers. It's not reading the search result; it's generating plausible-sounding text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Forced citations. Require the LLM to cite search results by index. Validate that citations actually exist in the search results before accepting the output.&lt;/p&gt;
&lt;h3&gt;
  
  
  Challenge 2: Tool Execution Failures
&lt;/h3&gt;

&lt;p&gt;Your agent calls &lt;code&gt;tavily_tool.invoke(query)&lt;/code&gt;. What if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The API is down&lt;/li&gt;
&lt;li&gt;The query times out&lt;/li&gt;
&lt;li&gt;The API returns no results&lt;/li&gt;
&lt;li&gt;The API returns malformed data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any node fails, the entire execution fails. You need retry logic, fallbacks, and graceful degradation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Challenge 3: Infinite Loops
&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;event_loop&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;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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;not_satisfied_with_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;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;execute_tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Loop back
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If your loop condition is wrong, the agent loops forever. You pay for infinite LLM calls. The user waits forever.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real incident:&lt;/strong&gt; An agent configured with &lt;code&gt;MAX_ITERATIONS = 10&lt;/code&gt; and a condition that was never truly satisfied. The agent completed all 10 iterations, costing $50+ in API calls for a single query.&lt;/p&gt;
&lt;h3&gt;
  
  
  Challenge 4: State Explosion
&lt;/h3&gt;

&lt;p&gt;As agents get more complex, state grows:&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="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="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent_outcome&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AgentAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AgentFinish&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intermediate_steps&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_results&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;context_from_database&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_preferences&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;previous_interactions&lt;/span&gt;&lt;span class="sh"&gt;"&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="c1"&gt;# ... grows and grows
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Large state = slower serialization, larger memory footprint, harder to debug. You need careful state design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 5: Tool Misuse
&lt;/h3&gt;

&lt;p&gt;The agent has access to tools but doesn't always use them correctly.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Tool: &lt;code&gt;search(query: str) → List[Document]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Agent calls: &lt;code&gt;search(query="tell me everything about AI")&lt;/code&gt; ← Too broad&lt;/li&gt;
&lt;li&gt;Result: 1000 results. Most irrelevant. Agent gets confused by noise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent needs to learn what "good" queries look like. This often requires few-shot examples in the prompt.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 7: Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI agents are not simple chatbots.&lt;/strong&gt; They're state machines that loop between reasoning and action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LangGraph solves orchestration.&lt;/strong&gt; It handles the mechanics of routing, looping, and state management so you can focus on agent logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LangChain handles integration.&lt;/strong&gt; It abstracts away vendor differences and provides pre-built tools, allowing you to build faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reflexion agents improve themselves.&lt;/strong&gt; By iterating, reflecting, and searching, they produce higher-quality outputs than single-pass agents.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reliability requires engineering.&lt;/strong&gt; Hallucinations, tool failures, infinite loops, and state bloat are real problems that need real solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Visibility is your best friend.&lt;/strong&gt; Print the graph. Log every state transition. Understand what your agent is actually doing before deploying it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost and latency scale with complexity.&lt;/strong&gt; Reflexion agents are more accurate but cost more and take longer. Balance quality with performance requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple tools matter.&lt;/strong&gt; An agent is only as good as its tools. Invest in tool quality and testing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 8: Further Reading and Exploration
&lt;/h2&gt;

&lt;p&gt;If this sparked your curiosity, explore these topics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agentic Loop Patterns&lt;/strong&gt; — How successful teams structure reasoning, acting, and reflection loops for robustness&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tool Calling and Function Composition&lt;/strong&gt; — Designing tools that agents can reliably use without misunderstanding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prompt Engineering for Agents&lt;/strong&gt; — How to write prompts that guide agents toward correct reasoning and tool use&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State Machine Design Patterns&lt;/strong&gt; — Advanced patterns like hierarchical states, parallel paths, and error recovery&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LLM Evaluation Frameworks&lt;/strong&gt; — Measuring agent quality systematically instead of manual spot-checking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-Agent Coordination&lt;/strong&gt; — Supervisor patterns, communication protocols, and handoff strategies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost Optimization in Agentic Systems&lt;/strong&gt; — Caching, early termination, and model selection for cost-efficient agents&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Closing Thought
&lt;/h2&gt;

&lt;p&gt;Building agents is not about adding more intelligence. It's about adding structure, constraints, and observability.&lt;/p&gt;

&lt;p&gt;LangGraph and LangChain don't make agents smarter. They make agents visible, debuggable, and reliable.&lt;/p&gt;

&lt;p&gt;The best agents aren't built by luck. They're engineered. They're tested. They have guardrails. They fail gracefully. They log everything.&lt;/p&gt;

&lt;p&gt;Start simple. Add reflexion when you need it. Monitor everything. Iterate on what breaks.&lt;/p&gt;

&lt;p&gt;That's how you build production AI agents that actually work.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What agent patterns are you using in your projects? I'd like to hear what challenges you're running into. Drop a comment below.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
