LangChain/Core Concepts
Beginner12 min

Message Types

A field-by-field reference for every message class in LangChain — HumanMessage, AIMessage, SystemMessage, ToolMessage, AIMessageChunk, RemoveMessage, and legacy types. Know what each field does, what breaks when you get it wrong, and how providers differ.

Quick Reference

  • Six types: SystemMessage, HumanMessage, AIMessage, ToolMessage, AIMessageChunk, RemoveMessage
  • FunctionMessage is legacy — use ToolMessage with tool_call_id
  • AIMessage.tool_calls is a list of dicts — always check before iterating
  • ToolMessage.tool_call_id must exactly match AIMessage.tool_calls[i]['id']
  • AIMessageChunk is addable — accumulate with: full = chunk if full is None else full + chunk
  • usage_metadata only arrives on the final chunk when streaming
  • RemoveMessage is a LangGraph-only type — not a chat role, it signals state deletion

The Complete Type Hierarchy

Every message class in LangChain extends BaseMessage. BaseMessage provides four fields that all types inherit: content (the payload), id (auto-assigned UUID), name (optional label for multi-agent tracing), and additional_kwargs (provider-specific overflow). Concrete types add role-specific fields on top.

BaseMessagecontent · id · name · additional_kwargsSystemMessagerole: systemHumanMessagerole: userAIMessagerole: assistantToolMessagerole: toolRemoveMessageLangGraph onlyAIMessageChunkstreaming only · addableFunctionMessagelegacy — use ToolMessage

All message types extend BaseMessage. FunctionMessage is legacy — use ToolMessage.

Typerole valueUnique fieldsWho creates it
SystemMessagesystemYou, before conversation starts
HumanMessageuserYou, from user input
AIMessageassistanttool_calls, usage_metadata, response_metadata, text (v1), content_blocks (v1)model.invoke() return value
ToolMessagetooltool_call_id, artifact, statusYou, after executing a tool
AIMessageChunkassistantsame as AIMessage (partial)model.stream() yield value
RemoveMessageremoveid (the message to delete)You, in LangGraph reducers only
ChatMessageany stringroleYou, for custom role strings
FunctionMessage (legacy)functionnameLegacy — superseded by ToolMessage
FunctionMessage is superseded

FunctionMessage was created for OpenAI's original function-calling API before tool_call_id existed. It has no tool_call_id, so you cannot correlate results when the model calls multiple tools in parallel. Use ToolMessage instead. FunctionMessage still exists in langchain_core for backwards compatibility but should not appear in new code.