Course Content
LangChain Mastery
7 sections · 109 lessons
How do you use LangChain to create a conversational chain?
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.
1from langchain_core.messages import SystemMessage, trim_messages2from langchain_core.messages.utils import count_tokens_approximately3from langgraph.graph import StateGraph, MessagesState, START4from langgraph.checkpoint.memory import InMemorySaver56SYSTEM = SystemMessage("You are PayEase support. Answer from the help centre only.")78def respond(state: MessagesState):9 recent = trim_messages(state["messages"], strategy="last", max_tokens=3000,10 token_counter=count_tokens_approximately, start_on="human")11 return {"messages": [llm.invoke([SYSTEM, *recent])]}1213builder = StateGraph(MessagesState)14builder.add_node("respond", respond)15builder.add_edge(START, "respond")16bot = builder.compile(checkpointer=InMemorySaver())1718cfg = {"configurable": {"thread_id": "user-812"}}19bot.invoke({"messages": [{"role": "user", "content": "My salary credit failed"}]}, cfg)20bot.invoke({"messages": [{"role": "user", "content": "Which bank was it sent to?"}]}, cfg)MessagesStateholds amessageslist; returning new messages appends them.- The checkpointer saves the list after each turn; the same
thread_idloads it back. trim_messageskeeps 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
| Checkpointer | Package | Use |
|---|---|---|
InMemorySaver | langgraph | Tests and demos; lost on restart |
SqliteSaver | langgraph-checkpoint-sqlite | Single-machine apps |
PostgresSaver | langgraph-checkpoint-postgres | Production, 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
SummarizationMiddlewaredoes this for agents), or save key facts to a long-term store. - "How do you separate users?" — One
thread_idper 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.