LangChain Mastery

Course Content

LangChain Mastery

7 sections · 109 lessons

How do you use LangChain to create a conversational chain?


One turn with LangGraph persistenceNew messagewith thread_idCheckpointerloads thesaved messagestrim_messages to a3,000-token budgetModel repliesCheckpointersaves theupdated listPostgresSaver shares threads across all four servers.
History lives in the checkpointer, not the process, so a deploy or a different server no longer wipes the conversation.

What you need to know

The model itself remembers nothing between calls. "Memory" means your code sends the earlier messages again with each new one.

Python
from langchain_core.messages import SystemMessage, trim_messagesfrom langchain_core.messages.utils import count_tokens_approximatelyfrom langgraph.graph import StateGraph, MessagesState, STARTfrom langgraph.checkpoint.memory import InMemorySaverSYSTEM = SystemMessage("You are PayEase support. Answer from the help centre only.")def respond(state: MessagesState):    recent = trim_messages(state["messages"], strategy="last", max_tokens=3000,                           token_counter=count_tokens_approximately, start_on="human")    return {"messages": [llm.invoke([SYSTEM, *recent])]}builder = StateGraph(MessagesState)builder.add_node("respond", respond)builder.add_edge(START, "respond")bot = builder.compile(checkpointer=InMemorySaver())cfg = {"configurable": {"thread_id": "user-812"}}bot.invoke({"messages": [{"role": "user", "content": "My salary credit failed"}]}, cfg)bot.invoke({"messages": [{"role": "user", "content": "Which bank was it sent to?"}]}, cfg)
  • MessagesState holds a messages list; returning new messages appends them.
  • The checkpointer saves the list after each turn; the same thread_id loads it back.
  • trim_messages keeps only the most recent messages that fit a token budget, starting on a human turn.
  • If you also need tools, create_agent(model, tools, checkpointer=...) gives the same persistence with less code.

Where history is stored

CheckpointerPackageUse
InMemorySaverlanggraphTests and demos; lost on restart
SqliteSaverlanggraph-checkpoint-sqliteSingle-machine apps
PostgresSaverlanggraph-checkpoint-postgresProduction, many servers

The legacy APIs

ConversationChain with ConversationBufferMemory stored history inside the chain object. RunnableWithMessageHistory wrapped a chain with a get_session_history function; it still runs but now emits a deprecation warning in langchain-core 1.6, and so does InMemoryChatMessageHistory. Know them for older codebases, but build new work on LangGraph persistence.

A real-life example

A payroll company's support bot over its help-centre docs stored chat history in a Python dict inside the web process. Each deploy wiped every conversation, and with four servers behind a load balancer, a user's second message often landed on a server that had never seen the first. Moving to a LangGraph graph with PostgresSaver, keyed by thread_id = chat session ID, fixed both problems. Adding trim_messages with a 3,000-token budget kept long chats, some over 60 turns, from failing with context-length errors, and cut the average prompt size by about 40%.

Follow-up questions to expect

  • "How do you keep facts from early in a long chat?" — Summarise older turns into a short system note (LangChain's SummarizationMiddleware does this for agents), or save key facts to a long-term store.
  • "How do you separate users?" — One thread_id per conversation, and check on the server that the thread belongs to the logged-in user.
  • "How do you clear a conversation?" — Start a new thread_id, or delete that thread's checkpoints.