
{"id":104328,"date":"2025-10-13T13:36:20","date_gmt":"2025-10-13T13:36:20","guid":{"rendered":"https:\/\/mycryptomania.com\/?p=104328"},"modified":"2025-10-13T13:36:20","modified_gmt":"2025-10-13T13:36:20","slug":"understanding-long-term-memory-in-langgraph-a-hands-on-guide","status":"publish","type":"post","link":"https:\/\/mycryptomania.com\/?p=104328","title":{"rendered":"Understanding Long-Term Memory in LangGraph: A Hands-On Guide"},"content":{"rendered":"<p>Maintain Context over time, adapt to our preferences\u00a0, learn from our past instructions<\/p>\n<p>AI applications need memory to share context across multiple interactions. In LangGraph, you can add two types of memory: (<a href=\"https:\/\/medium.com\/coinmonks\/how-to-add-memory-to-llm-applications-cdf9bee83da0\">Read More<\/a>: <a href=\"https:\/\/medium.com\/coinmonks\/how-to-add-memory-to-llm-applications-cdf9bee83da0\">How to Add Memory to LLM Applications<\/a>)<\/p>\n<p>Add <strong>short-term memory<\/strong> as a part of your agent\u2019s state to enable multi-turn conversationsAdd <strong>long-term memory<\/strong> to store user-specific or application-level data across\u00a0sessions<\/p>\n<p>Long-term Agentic Memory in LangGraph transforms AI agents from forgetful bots into genuinely helpful assistants that l<em>earn, adapt, and personalize <\/em>over time a game-changer for building practical agentic workflows.<\/p>\n<h3>Why Long-Term Memory\u00a0Matters<\/h3>\n<p>We all know that AI agents are <em>stateless<\/em> without memory, AI agents are limited to responding in short, exchanges missing the crucial ability to recall context, preferences, and past events. When an agent \u201cremembers\u201d several capabilities become possible:<\/p>\n<p><strong>Adapting<\/strong> to user preferences and\u00a0history<strong>Providing<\/strong> contextual, relevant answers across conversations<strong>Learning<\/strong> new skills or facts and evolving responses<strong>Delivering<\/strong> highly personalized experiences<\/p>\n<p>LangGraph makes these capabilities accessible through its modular approach to agent memory, supporting diverse storage and retrieval strategies.<\/p>\n<h3>The Core Memory\u00a0Types<\/h3>\n<p>Humans use memories to remember facts (<a href=\"https:\/\/langchain-ai.github.io\/langgraph\/concepts\/memory\/#semantic-memory\">semantic memory<\/a>), experiences (<a href=\"https:\/\/langchain-ai.github.io\/langgraph\/concepts\/memory\/#episodic-memory\">episodic memory<\/a>), and rules (<a href=\"https:\/\/langchain-ai.github.io\/langgraph\/concepts\/memory\/#procedural-memory\">procedural memory<\/a>). AI agents can use memory in the same ways. For example, AI agents can use memory to remember specific facts about a user to accomplish a\u00a0task.<\/p>\n<p>Let\u2019s understand this by an example. As data scientists, we often build internal tools to streamline workflows. Imagine we\u2019re tasked with creating a project management assistant for a software team lead, Mr John. Her team is working on a major Q3 feature launch, codenamed <strong>\u201cProject\u00a0Marvel.\u201d<\/strong><\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Marvel_Television\">Source<\/a><\/p>\n<p>Sam sends a simple message to the assistant:<\/p>\n<p>\u201cHey, what\u2019s the status on the \u2018Marvel\u2019 release?\u201d<\/p>\n<p>If our \u201cagent\u201d is just a simple pass-through to a raw LLM, we see the immediate failure of statelessness. The LLM, with its vast <strong>general knowledge<\/strong> but zero <strong>local context<\/strong>, would likely\u00a0reply:<\/p>\n<p>\u201cHey\u200a\u2014\u200acould you clarify which \u201cMarvel\u201d release you mean? Here are a few recent updates; maybe one matches your reference:Marvel Zombies premiered September 24, 2025, on\u00a0DisneyThe Fantastic Four: First Steps is scheduled for July 25, 2025 in theaters.Spider-Man: Brand New Day (Spider-Man 4) is set for July\u00a02026.Avengers: Doomsday is currently slated for December 18,\u00a02026.<\/p>\n<p>This response is practically useless. It forces the user to do all the work of providing context. Now, let\u2019s see how an agent with a proper memory architecture would handle this.Lets discuss these memory types and its\u00a0analogy.<\/p>\n<p><a href=\"https:\/\/langchain-ai.github.io\/langgraph\/concepts\/memory\/\">Source<\/a><\/p>\n<h3>1. Semantic Memory: The Agent\u2019s Fact\u00a0Book<\/h3>\n<p>Things you just know, like the capital of France or facts you learned in school. It\u2019s your internal library of knowledge.<\/p>\n<p><strong>Semantic Memory<\/strong> is the agent\u2019s collection of hard facts. It\u2019s a database of objective information about you, the world, and the people it interacts with. This isn\u2019t about remembering the full chat history, it\u2019s about pulling out the important truths from that chat and filing them away for\u00a0later.<\/p>\n<p><strong>How it works for an agent:<\/strong><br \/>This is usually a <strong>vector store<\/strong> working behind the scenes. The agent gets tools like send_slack_message, create_jira_ticket, schedule_standup, check_sprint_capacity\u00a0. When it learns something new and important during a conversation, it saves it using update_project_status. Later on, when it needs to make a decision, it can instantly look up relevant facts to get the context it\u00a0needs.<\/p>\n<p>  # ========================================<br \/>  # SEMANTIC MEMORY: General knowledge about project management rules and procedures<br \/>  # ========================================<br \/>  # This contains factual knowledge about how to categorize and handle different types of <br \/>  prompt_instructions = {<br \/>      &#8220;triage_rules&#8221;: {<br \/>          &#8220;ignore&#8221;: &#8220;General company announcements, unrelated project updates, promotional <br \/>  content&#8221;,<br \/>          &#8220;notify&#8221;: &#8220;Sprint retrospective notes, deployment status updates, team <br \/>  availability changes&#8221;,<br \/>          &#8220;respond&#8221;: &#8220;Blocker reports from team members, stakeholder requests, urgent bug <br \/>  escalations&#8221;,<br \/>      },<br \/>      &#8220;agent_instructions&#8221;: &#8220;Use these tools to help John manage Project Marvel tasks and <br \/>  team coordination efficiently.&#8221;<br \/>  }<br \/>  profile = {<br \/>      &#8220;name&#8221;: &#8220;John&#8221;,<br \/>      &#8220;full_name&#8221;: &#8220;John Martinez&#8221;,<br \/>      &#8220;user_profile_background&#8221;: &#8220;Senior Team Lead managing Project Marvel &#8211; Q3 feature launch with 8 team members&#8221;,<br \/>  }<br \/>  # SEMANTIC MEMORY: Knowledge about available tools and their mapping<br \/>  tools_map = {<br \/>      &#8220;send_slack_message&#8221;: send_slack_message,<br \/>      &#8220;create_jira_ticket&#8221;: create_jira_ticket,<br \/>      &#8220;schedule_standup&#8221;: schedule_standup,<br \/>      &#8220;check_sprint_capacity&#8221;: check_sprint_capacity,<br \/>      &#8220;update_project_status&#8221;: update_project_status<br \/>  }<\/p>\n<p>In our \u201cProject Marvel\u201d example, this was the agent\u2019s knowledge that \u201cJohn Martinez is the Senior Team Lead managing Project Marvel\u200a\u2014\u200aQ3 feature launch with 8 team members\u201d. These factual details were the key that helped the agent understand the context and technical specification.<\/p>\n<h3>2. Episodic Memory: The Agent\u2019s Lived Experience<\/h3>\n<p>Remembering specific events, like your first day at a new job or the exact words of a conversation you had yesterday.<\/p>\n<p><strong>Episodic Memory<\/strong> is about recalling specific events, just as they happened. It\u2019s not a single fact, but the entire replay of a past experience. For an agent, this is like a recording of a previous job it did what it saw, what it did, and how it all turned\u00a0out.<\/p>\n<p><strong>How it works for an agent:<\/strong><br \/>This is a fantastic way to create <strong>few-shot examples<\/strong>. By giving the agent a \u201cdiary\u201d of its past successes, we can guide it to make better choices in the future. It\u2019s a powerful way to <em>show<\/em>, not just <em>tell<\/em>, the agent how to act, which makes it far more reliable.<\/p>\n<p># ========================================<br \/># EPISODIC MEMORY: Specific test scenarios and experiences<br \/># ========================================<br \/># These represent specific examples of messages that the system has learned to handle<\/p>\n<p>test_message_1 = {<br \/>    &#8220;author&#8221;: &#8220;Sarah Chen &lt;sarah.chen@company.com&gt;&#8221;,<br \/>    &#8220;to&#8221;: &#8220;John Martinez &lt;john.martinez@company.com&gt;&#8221;,<br \/>    &#8220;subject&#8221;: &#8220;BLOCKER: API Integration Issue for Project Marvel&#8221;,<br \/>    &#8220;message_thread&#8221;: &#8220;&#8221;&#8221;Hi John,<\/p>\n<p>We&#8217;ve hit a critical blocker on the authentication microservice integration for Project Marvel. The OAuth flow is failing in staging environment.<\/p>\n<p>Error: Token validation failing with 401 on \/marvel\/auth\/verify<\/p>\n<p>This is blocking 3 developers from completing their sprint tasks. Can we schedule a quick sync to debug this today?<\/p>\n<p>Impact: High &#8211; affects core functionality for Q3 launch<\/p>\n<p>Thanks,<br \/>Sarah&#8221;&#8221;&#8221;,<br \/>}<\/p>\n<p>def triage_router(state: State) -&gt; Command[Literal[&#8220;response_agent&#8221;, &#8220;__end__&#8221;]]:<br \/>    &#8220;&#8221;&#8221;PROCEDURAL MEMORY: How to route messages based on triage classification.&#8221;&#8221;&#8221;<br \/>    # EPISODIC MEMORY: Extract specific message details from current context<br \/>    author = state[&#8216;message_input&#8217;][&#8216;author&#8217;]<br \/>    to = state[&#8216;message_input&#8217;][&#8216;to&#8217;]<br \/>    subject = state[&#8216;message_input&#8217;][&#8216;subject&#8217;]<br \/>    message_thread = state[&#8216;message_input&#8217;][&#8216;message_thread&#8217;]<\/p>\n<p>    # SEMANTIC + EPISODIC MEMORY: Combine general knowledge with specific context<br \/>    system_prompt = triage_system_prompt.format(<br \/>        full_name=profile[&#8220;full_name&#8221;],<br \/>        name=profile[&#8220;name&#8221;],<br \/>        user_profile_background=profile[&#8220;user_profile_background&#8221;],<br \/>        triage_no=prompt_instructions[&#8220;triage_rules&#8221;][&#8220;ignore&#8221;],<br \/>        triage_notify=prompt_instructions[&#8220;triage_rules&#8221;][&#8220;notify&#8221;],<br \/>        triage_email=prompt_instructions[&#8220;triage_rules&#8221;][&#8220;respond&#8221;],<br \/>    )<\/p>\n<p>In our example, this was the agent recalling the specific experience of Sarah Chen\u2019s urgent message on Tuesday morning about the OAuth authentication failing with a 401 error on the \/marvel\/auth\/verify endpoint, which was blocking 3 developers and threatening the Q3 launch deadline. This wasn\u2019t a general rule, but the complete contextual memory of that specific incident requiring immediate escalation.<\/p>\n<h3>3. Procedural Memory: The Agent\u2019s Muscle\u00a0Memory<\/h3>\n<p>Skills and habits you don\u2019t have to think about, like riding a bike or typing. It\u2019s the \u201chow-to\u201d knowledge that\u2019s become second\u00a0nature.<\/p>\n<p><strong>Procedural Memory<\/strong> is the agent\u2019s set of core principles and instincts. It\u2019s the rulebook that defines its personality, its style, and how it operates. Think of it less as a stored\u00a0memory.<\/p>\n<p><strong>How it works for an agent:<\/strong><br \/>This is the agent\u2019s <strong>system prompt<\/strong>. The system prompt acts as its constitution or its prime directives a set of instructions it follows at all times. This is what ensures the agent is consistent, safe, and acts the way you want it\u00a0to.<\/p>\n<p># ========================================<br \/># PROCEDURAL MEMORY: Skills and action-oriented tools<br \/># ========================================<br \/># These functions represent learned procedures for executing project management tasks<\/p>\n<p>@tool<br \/>def create_jira_ticket(<br \/>    title: str,<br \/>    description: str,<br \/>    priority: str,<br \/>    assignee: str<br \/>) -&gt; str:<br \/>    &#8220;&#8221;&#8221;PROCEDURAL MEMORY: How to create and track project tasks.&#8221;&#8221;&#8221;<br \/>    return f&#8221;JIRA ticket created: &#8216;{title}&#8217; &#8211; Priority: {priority}, Assigned to: {assignee}&#8221;<\/p>\n<p>@tool<br \/>def schedule_standup(<br \/>    attendees: list[str],<br \/>    topic: str,<br \/>    duration_minutes: int,<br \/>    preferred_time: str<br \/>) -&gt; str:<br \/>    &#8220;&#8221;&#8221;PROCEDURAL MEMORY: How to organize and schedule team meetings.&#8221;&#8221;&#8221;<br \/>    return f&#8221;Meeting &#8216;{topic}&#8217; scheduled for {preferred_time} with {len(attendees)} attendees ({duration_minutes} min)&#8221;<\/p>\n<p>def call_gemini_for_triage(system_prompt: str, user_prompt: str) -&gt; Router:<br \/>    &#8220;&#8221;&#8221;PROCEDURAL MEMORY: How to classify and triage incoming messages.&#8221;&#8221;&#8221;<br \/>    model = genai.GenerativeModel(GEMINI_MODEL_NAME)<\/p>\n<p>    # PROCEDURAL MEMORY: Steps for parsing JSON responses<br \/>    if response_text.startswith(&#8220;&#8220;`json&#8221;):<br \/>        response_text = response_text[7:]<br \/>    if response_text.endswith(&#8220;&#8220;`&#8221;):<br \/>        response_text = response_text[:-3]<br \/>    response_text = response_text.strip()<\/p>\n<p>    try:<br \/>        result_dict = json.loads(response_text)<br \/>        return Router(**result_dict)<br \/>    except json.JSONDecodeError:<br \/>        # PROCEDURAL MEMORY: Error handling &#8211; default to notify for safety<br \/>        return Router(<br \/>            reasoning=&#8221;Failed to parse response, defaulting to notify&#8221;,<br \/>            classification=&#8221;notify&#8221;<br \/>        )<\/p>\n<p># PROCEDURAL MEMORY: Decision tree for routing based on classification<br \/>if result.classification == &#8220;respond&#8221;:<br \/>    print(&#8220;\ud83c\udfaf Classification: RESPOND &#8211; This message requires action&#8221;)<br \/>    print(f&#8221;Reasoning: {result.reasoning}&#8221;)<br \/>    goto = &#8220;response_agent&#8221;<br \/>    update = {<br \/>        &#8220;messages&#8221;: [<br \/>            {<br \/>                &#8220;role&#8221;: &#8220;user&#8221;,<br \/>                &#8220;content&#8221;: f&#8221;Handle this Project Marvel message: {state[&#8216;message_input&#8217;]}&#8221;,<br \/>            }<br \/>        ]<br \/>    }<br \/>elif result.classification == &#8220;ignore&#8221;:<br \/>    print(&#8220;\u23ed\ufe0f Classification: IGNORE &#8211; This message can be skipped&#8221;)<br \/>    print(f&#8221;Reasoning: {result.reasoning}&#8221;)<br \/>    update = None<br \/>    goto = END<\/p>\n<p>For the project assistant, the procedural memory was its fundamental learned process: \u201cWhen you receive a message with \u2018BLOCKER\u2019 in the subject line from a team member, immediately classify it as \u2018respond\u2019, then execute the sequence:<\/p>\n<p>create_jira_ticket() \u2192 schedule_standup() \u2192 send_slack_message()<\/p>\n<p>to coordinate the response.\u201d This step-by-step procedure was what told the agent exactly how to handle Sarah\u2019s authentication blocker systematically and efficiently.<\/p>\n<h4>MAIN SYSTEM ORCHESTRATION<\/h4>\n<p>def project_assistant(message_input: Dict) -&gt; Dict:<br \/>    &#8220;&#8221;&#8221;Main function that orchestrates the project management assistant.&#8221;&#8221;&#8221;<br \/>    print(&#8220;n&#8221; + &#8220;=&#8221;*60)<br \/>    print(&#8220;PROJECT MARVEL ASSISTANT &#8211; PROCESSING MESSAGE&#8221;)<br \/>    print(&#8220;=&#8221;*60)<\/p>\n<p>    # Step 1: Triage the message<br \/>    classification = triage_router(message_input)<\/p>\n<p>    result = {<br \/>        &#8220;classification&#8221;: classification,<br \/>        &#8220;message_input&#8221;: message_input<br \/>    }<\/p>\n<p>    # Step 2: If needs response, generate one<br \/>    if classification == &#8220;respond&#8221;:<br \/>        print(&#8220;n\ud83e\udd16 Generating response&#8230;&#8221;)<br \/>        response = response_agent(message_input)<br \/>        result[&#8220;response&#8221;] = response<br \/>        print(f&#8221;n\ud83d\udcdd Generated Response: {response}&#8221;)<\/p>\n<p>    return result<\/p>\n<p>Now Lets test some\u00a0cases,<\/p>\n<p>CASE 1: Critical Blocker\u00a0Report:<\/p>\n<p> test_message_1 = {<br \/>      &#8220;author&#8221;: &#8220;Sarah Chen &lt;sarah.chen@company.com&gt;&#8221;,<br \/>      &#8220;to&#8221;: &#8220;John Martinez &lt;john.martinez@company.com&gt;&#8221;,<br \/>      &#8220;subject&#8221;: &#8220;BLOCKER: API Integration Issue for Project Marvel&#8221;,<br \/>      &#8220;message_thread&#8221;: &#8220;&#8221;&#8221;Hi John,<\/p>\n<p>      We&#8217;ve hit a critical blocker on the authentication microservice integration for Project Marvel. The OAuth flow is failing in staging environment.<\/p>\n<p>      Error: Token validation failing with 401 on \/marvel\/auth\/verify<\/p>\n<p>      This is blocking 3 developers from completing their sprint tasks. Can we schedule a quick sync to debug this today?<\/p>\n<p>      Impact: High &#8211; affects core functionality for Q3 launch<\/p>\n<p>      Thanks,<br \/>      Sarah&#8221;&#8221;&#8221;,<br \/>          }<\/p>\n<p>Classification: RESPOND\u200a\u2014\u200aThis message requires\u00a0action<\/p>\n<p>Reasoning: The message explicitly states a \u2018critical blocker\u2019 on Project Marvel, which is John\u2019s project. It details the issue (OAuth flow failing), provides an error, and highlights a significant impact (blocking 3 developers, affecting core functionality for Q3 launch). The sender, Sarah, is likely a team member, and she directly requests \u2018a quick sync to debug this\u00a0today\u2019\u2026\u2026<\/p>\n<p># Executing tool: schedule_standup with parameters: <br \/>{&#8216;team_members&#8217;: [&#8216;Sarah Chen&#8217;, &#8216;John Martinez&#8217;],<br \/> &#8216;date&#8217;: &#8216;today&#8217;, &#8216;time&#8217;: &#8216;earliest_available&#8217;,<br \/> &#8216;duration&#8217;: &#8217;30 minutes&#8217;, &#8216;topic&#8217;: <br \/>&#8216;Project Marvel: Debug API Integration Blocker (OAuth Flow)&#8217;}<\/p>\n<p>## Generated Response: <br \/>A sync meeting has been scheduled for today to debug the API Integration Blocker (OAuth Flow) with Sarah Chen and John Martinez. Please ensure both attend the scheduled meeting. I will also create a JIRA ticket to track this critical blocker.<\/p>\n<p>CASE 2: Company Announcement<\/p>\n<p>test_message_2 = {<br \/>    &#8220;author&#8221;: &#8220;Company Wide &lt;announcements@company.com&gt;&#8221;,<br \/>    &#8220;to&#8221;: &#8220;All Employees &lt;all@company.com&gt;&#8221;,<br \/>    &#8220;subject&#8221;: &#8220;Reminder: Health &amp; Wellness Week Next Month&#8221;,<br \/>    &#8220;message_thread&#8221;: &#8220;&#8221;&#8221;Dear Team,<\/p>\n<p>    Just a friendly reminder that our annual Health &amp; Wellness Week is coming up next month!<\/p>\n<p>    Activities include:<br \/>    &#8211; Yoga sessions<br \/>    &#8211; Mental health workshops<br \/>    &#8211; Free health screenings<\/p>\n<p>    Sign up on the company portal.<\/p>\n<p>    Best,<br \/>    HR Team&#8221;&#8221;&#8221;,<br \/>        }<\/p>\n<p>Classification: IGNORE\u200a\u2014\u200aThis message can be\u00a0skipped<\/p>\n<p>Reasoning: The message is from \u2018Company Wide\u2019 to \u2018All Employees\u2019 and is a \u2018Reminder: Health &amp; Wellness Week Next Month\u2019. This is a classic example of a general company announcement. According to the rules, \u2018General company announcements\u2019 are messages that are not worth responding to or tracking.<\/p>\n<h3>Conclusion<\/h3>\n<p>Long-term agentic memory in LangGraph transforms AI agents from forgetful bots into intelligent assistants that learn and adapt over time. By implementing semantic, episodic, and procedural memory systems, you can create agents\u00a0that:<\/p>\n<p>Remember: memory is not just about storage it\u2019s about creating agents that become more valuable with every interaction, just like human assistants who learn your preferences and working style over\u00a0time.<\/p>\n<p>Thank you for reading!\ud83e\udd17I hope that you found this article both informative and enjoyable to\u00a0read.<\/p>\n<p>Fore more information like this follow me on\u00a0<a href=\"https:\/\/www.linkedin.com\/in\/sweety-tripathi\/\"><em>LinkedIn<\/em><\/a><\/p>\n<p><a href=\"https:\/\/medium.com\/coinmonks\/understanding-long-term-memory-in-langgraph-a-hands-on-guide-01d9c6c97b77\">Understanding Long-Term Memory in LangGraph: A Hands-On Guide<\/a> was originally published in <a href=\"https:\/\/medium.com\/coinmonks\">Coinmonks<\/a> on Medium, where people are continuing the conversation by highlighting and responding to this story.<\/p>","protected":false},"excerpt":{"rendered":"<p>Maintain Context over time, adapt to our preferences\u00a0, learn from our past instructions AI applications need memory to share context across multiple interactions. In LangGraph, you can add two types of memory: (Read More: How to Add Memory to LLM Applications) Add short-term memory as a part of your agent\u2019s state to enable multi-turn conversationsAdd [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-104328","post","type-post","status-publish","format-standard","hentry","category-interesting"],"_links":{"self":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts\/104328"}],"collection":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=104328"}],"version-history":[{"count":0,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts\/104328\/revisions"}],"wp:attachment":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=104328"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=104328"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=104328"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}