The messages list
Put that list in the state and one problem appears immediately. A node that returns a message would replace the whole conversation with it.
You already know the fix. In lesson 10 two nodes wanted to add to a list, and a reducer combined the values instead of replacing them. A conversation has exactly the same shape, so LangGraph ships a reducer written for it.
from langchain_core.messages import HumanMessage, AIMessage
from langgraph.graph import add_messages
so_far = [HumanMessage("I was charged twice")]
new = [AIMessage("Thanks, I will look into that.")]
for m in add_messages(so_far, new):
print(f"{m.type:<6} {m.content}")Two messages out, from a list of one and a list of one. A node returns only the message it produced, and add_messages puts it on the end of the conversation.
Using it in a state
It goes in the same place operator.add went.
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import add_messages
class State(TypedDict):
messages: Annotated[list, add_messages]You will write that so often that LangGraph gives you it ready made. MessagesState is a TypedDict holding exactly that one annotated key, so you can hand it straight to StateGraph and get the same behaviour.
from langchain_core.messages import HumanMessage, AIMessage
from langgraph.graph import StateGraph, START, MessagesState
def reply(state):
return {"messages": [AIMessage("Thanks, I will look into that.")]}
builder = StateGraph(MessagesState)
builder.add_node("reply", reply)
builder.add_edge(START, "reply")
result = builder.compile().invoke({"messages": [HumanMessage("I was charged twice")]})
for m in result["messages"]:
print(f"{m.type:<6} {m.content}")Use MessagesState when messages are all you need, and write the Annotated line yourself when your state has other keys too. Most real graphs do both, by inheriting from MessagesState and adding keys.
- Swap
add_messagesfor a plain list in the state and watch the human message vanish. - Add a
ticketkey alongsidemessagesby inheriting fromMessagesState. - Call
add_messageswith two lists of two and count what comes out.
Slow is fine. Stopping is the only problem.