Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Langchain ai Langgraph Add Messages

From Leeroopedia
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")]})

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment