How LangGraph Gives AI Chatbots Multi‑Turn Memory with Checkpoints and State Machines

This article explains how to use LangGraph's checkpoint and memory features together with a state‑machine router to build a chatbot that retains full conversation history, compresses long contexts, and dynamically switches between chat and task modes across multiple turns.

Tech Ocean
Tech Ocean
Tech Ocean
How LangGraph Gives AI Chatbots Multi‑Turn Memory with Checkpoints and State Machines

Core Challenges of Conversational Agents

Memory loss : Traditional bots resend the entire history each turn.

Context overflow : Long histories are truncated, discarding information.

Multi‑turn logic : Developers manually stitch responses together.

LangGraph addresses these issues with automatic checkpoint saving, compression + summarization, and a state‑machine with conditional edges.

Minimal Chatbot Implementation

from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver

class ChatbotState(TypedDict):
    messages: list
    mode: str  # "chat" / "task"
    context: dict

def router(state: ChatbotState) -> str:
    """Decide mode based on the latest user message"""
    last_msg = state["messages"][-1]["content"]
    if any(kw in last_msg for kw in ["帮我", "请", "查询"]):
        return "task_mode"
    return "chat_mode"

def chat_mode(state: ChatbotState) -> dict:
    """Casual chat response"""
    return {"messages": [{"role": "assistant", "content": "你好!"}]}

def task_mode(state: ChatbotState) -> dict:
    """Task‑oriented response"""
    return {"messages": [{"role": "assistant", "content": "任务已记录"}]}

memory = InMemorySaver()
builder = StateGraph(ChatbotState)
builder.add_node("chat_mode", chat_mode)
builder.add_node("task_mode", task_mode)
builder.add_conditional_edges(START, router, {"chat_mode": "chat_mode", "task_mode": "task_mode"})
builder.add_edge("chat_mode", END)
builder.add_edge("task_mode", END)
app = builder.compile(checkpointer=memory)

Multi‑Turn Dialogue Flow

┌─────────────────────────────────────┐
│         Multi‑Turn Dialogue          │
│                                     │
│  User: 你好 ──▶ Router ──▶ chat_mode │
│                                     │
│  User: 帮我查天气               │
│          ──▶ Router ──▶ task_mode │
│                                     │
│  User: 谢谢!                     │
│          ──▶ Router ──▶ chat_mode │
│                                     │
│  (History automatically saved in Checkpoint)
└─────────────────────────────────────┘

Router Logic for Mode Switching

def router(state: ChatbotState) -> Literal["chat_mode", "task_mode"]:
    """Route to the appropriate mode"""
    messages = state["messages"]
    if not messages:
        return "chat_mode"
    last_msg = messages[-1]["content"].lower()
    task_keywords = ["帮我", "请", "查询", "搜索", "告诉"]
    for kw in task_keywords:
        if kw in last_msg:
            return "task_mode"
    return "chat_mode"

Streaming Output Example

config = {"configurable": {"thread_id": "chatbot-1"}}
# First turn
result = app.invoke({
    "messages": [{"role": "user", "content": "你好"}],
    "mode": "chat",
    "context": {}
}, config)
# Second turn (history automatically included)
result = app.invoke({
    "messages": [{"role": "user", "content": "谢谢"}],
    "mode": "chat",
    "context": {}
}, config)
# Streaming version
async for chunk in app.astream(input_data, config, stream_mode="updates"):
    print(chunk)

Complete Architecture Overview

┌─────────────────────────────────────────┐
│               Chatbot Architecture       │
│                                         │
│  ┌───────┐   ┌─────────────┐            │
│  │ User │──▶│   Router   │            │
│  └───────┘   └──────┬──────┘            │
│                 │                     │
│   ┌─────────────┼─────────────┐       │
│   ▼             ▼             ▼       │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │chat_mode│ │task_mode│ │info_mode│ │
│ └─────┬───┘ └─────┬───┘ └─────┬───┘ │
│       │           │           │       │
│       └───────────┼───────────┘       │
│                   ▼                 │
│               ┌─────────┐           │
│               │ Memory  │           │
│               │(Checkpoint)│        │
│               └─────────┘           │
└─────────────────────────────────────────┘

Key Takeaways

The messages list stores the full dialogue history.

The mode field distinguishes between chat and task processing.

The router function dynamically selects the appropriate mode based on keyword detection.

Checkpoints automatically persist state, enabling seamless multi‑turn conversations.

For further reading, see the official LangGraph tutorial and the GitHub repository linked at the end of the original article.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonLangChainMemoryChatbotMulti-turn DialogueStateMachineLangGraph
Tech Ocean
Written by

Tech Ocean

Focused on AI programming, sharing ready-to-use development efficiency solutions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.