A chatbot needs more than the latest message if users are going to ask follow-up questions. In LangGraph, state is the collection of named values carried through a graph execution. A node reads the current state and returns values to update; the next node receives the resulting state. section 10.2.2 section 10.3.1
Define the fields before building the graph. A simple chatbot can use one field, messages, containing the conversation’s messages. Its assistant node sends that list to an LLM and returns an AI response as a state update. The graph starts with an initial state and produces a final state. section 10.2.3 section 10.2.2
Listing 10.1 An example of a graph
from langgraph.graph import START, END, StateGraph
from langchain_core.messages import AnyMessage, HumanMessage
from langchain_openai import ChatOpenAI
from typing import TypedDict
llm = ChatOpenAI(model_name="gpt-5.1", openai_api_key="sk-proj-...")
class MyGraphState(TypedDict):
messages: list[AnyMessage]
builder = StateGraph(MyGraphState)
def assistant_node(state):
messages = state["messages"]
ai_response_message = llm.invoke(messages)
return {"messages": messages + [ai_response_message]}
builder.add_node("assistant", assistant_node)
builder.add_edge(START, "assistant")
builder.add_edge("assistant", END)
graph = builder.compile()
input_message = input("Talk to the bot: ")
initial_state = {"messages": [HumanMessage(content=input_message)]}
final_state = graph.invoke(initial_state)
print("Bot:\n" + final_state["messages"][-1].content)
The one-node Python example shows a TypedDict state schema, an assistant node that returns an updated messages list, and a graph invocation that supplies the initial state. section 10.2.3
State can hold more than conversation history. For example, a state based on MessagesState can add a sys_msg_text field. A base-context node returns only that field’s new value; the assistant then uses it to put a system message before the conversation sent to the LLM. Nodes need return only the fields they change, not the entire state. section 10.4.2
Why the chatbot forgets—and how to fix it
Without persistence, invoking the graph with a follow-up creates a fresh state containing only that message. Compile the graph with a MemorySaver checkpointer and invoke it with the same thread ID to resume that thread’s saved state. To display the conversation, read the thread’s current state with get_state(config), then render its messages in Streamlit. section 10.3.1 section 10.3.2
Graph state and Streamlit session state have different jobs here: the graph’s state contains conversation data, while the frontend keeps its bot object in st.session_state across app reruns. Retaining the bot object alone does not replace saving the graph’s conversation state. section 10.2.3 section 10.3.1






































