Implementation:Langchain ai Langgraph Add Messages
| Metadata | Value |
|---|---|
| Type | Implementation (API Doc) |
| Library | langgraph |
| Source File | libs/langgraph/langgraph/graph/message.py
|
| Lines | L61-244 (add_messages), L307-308 (MessagesState)
|
| Workflow | Building_a_Stateful_Graph |
Overview
add_messages is a reducer function that merges two lists of messages, updating existing messages by ID and appending new ones. It is the primary mechanism for managing conversational message state in LangGraph. The companion MessagesState is a prebuilt TypedDict schema that uses add_messages as its reducer.
Description
The add_messages function implements append-only-by-default semantics for message lists. When a node returns new messages, they are appended to the existing list. However, if a new message shares the same id as an existing message, the new message replaces the old one in-place. Messages can also be removed by returning a RemoveMessage instance with the target message's ID.
The function also supports a special REMOVE_ALL_MESSAGES sentinel: when a RemoveMessage with id "__remove_all__" appears in the right-hand list, all prior messages are discarded and only messages after the sentinel are kept.
When called with no positional arguments but with keyword arguments (e.g., add_messages(format="langchain-openai")), it returns a functools.partial that can be used as a reducer with preconfigured formatting.
Usage
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, MessagesState
from langgraph.graph.message import add_messages
# Option 1: Use add_messages directly as a reducer
class MyState(TypedDict):
messages: Annotated[list, add_messages]
# Option 2: Use the prebuilt MessagesState
graph = StateGraph(MessagesState)
# Option 3: Use add_messages with OpenAI formatting
class FormattedState(TypedDict):
messages: Annotated[list, add_messages(format="langchain-openai")]
Code Reference
Source Location
| Item | Path | Lines |
|---|---|---|
add_messages |
libs/langgraph/langgraph/graph/message.py |
L61-244 |
MessagesState |
libs/langgraph/langgraph/graph/message.py |
L307-308 |
REMOVE_ALL_MESSAGES |
libs/langgraph/langgraph/graph/message.py |
L38 |
Signature
@_add_messages_wrapper
def add_messages(
left: Messages,
right: Messages,
*,
format: Literal["langchain-openai"] | None = None,
) -> Messages:
MessagesState is defined as:
class MessagesState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
Import
from langgraph.graph.message import add_messages
from langgraph.graph import MessagesState
I/O Contract
| Parameter | Type | Description |
|---|---|---|
left |
MessageLikeRepresentation | The base (existing) list of messages in the state. |
right |
MessageLikeRepresentation | The new message(s) to merge into the base list. |
format |
None | Optional formatting mode. When set to "langchain-openai", returned messages have their contents formatted to match the OpenAI message format (string, text blocks, or image_url blocks). Requires langchain-core>=0.3.11. Default: None.
|
Returns: list[BaseMessage] -- A new list with messages from right merged into left. Messages with matching IDs in right replace those in left. RemoveMessage instances cause the targeted message to be removed.
Usage Examples
Basic: Appending Messages
from langchain_core.messages import AIMessage, HumanMessage
from langgraph.graph.message import add_messages
msgs1 = [HumanMessage(content="Hello", id="1")]
msgs2 = [AIMessage(content="Hi there!", id="2")]
result = add_messages(msgs1, msgs2)
# [HumanMessage(content='Hello', id='1'), AIMessage(content='Hi there!', id='2')]
Overwriting an Existing Message by ID
msgs1 = [HumanMessage(content="Hello", id="1")]
msgs2 = [HumanMessage(content="Hello again", id="1")]
result = add_messages(msgs1, msgs2)
# [HumanMessage(content='Hello again', id='1')]
Removing a Message
from langchain_core.messages import RemoveMessage
msgs1 = [HumanMessage(content="Hello", id="1"), AIMessage(content="Hi", id="2")]
msgs2 = [RemoveMessage(id="1")]
result = add_messages(msgs1, msgs2)
# [AIMessage(content='Hi', id='2')]
Using in a StateGraph
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph
class State(TypedDict):
messages: Annotated[list, add_messages]
builder = StateGraph(State)
builder.add_node("chatbot", lambda state: {"messages": [("assistant", "Hello")]})
builder.set_entry_point("chatbot")
builder.set_finish_point("chatbot")
graph = builder.compile()
graph.invoke({})
# {'messages': [AIMessage(content='Hello', id=...)]}
Using the Prebuilt MessagesState
from langgraph.graph import StateGraph, MessagesState
builder = StateGraph(MessagesState)
builder.add_node("chatbot", lambda state: {"messages": [("assistant", "Hi!")]})
builder.set_entry_point("chatbot")
builder.set_finish_point("chatbot")
graph = builder.compile()
graph.invoke({"messages": [("user", "Hello")]})