TellWorldAI World Archive
Ask中文

Home›Practice›Practice

Practice

Message Types in LangChain

Learn LangChain's message objects: what SystemMessage, HumanMessage, AIMessage and ToolMessage do, how content blocks and multimodal input are structured, and how streamed chunks are combined.

Who this is for and what you will be able to do

This guide is for developers who already call chat models in LangChain and want to understand how message objects are organized. By the end you should be able to tell SystemMessage, HumanMessage, AIMessage, and ToolMessage apart, decide when to use a plain string and when to use a list of messages, write image input as content blocks, combine streamed chunks into a full message, and save and restore conversation history.

What a message is

A message is the basic unit of context for a model in LangChain. Each message has a role, content, and optional metadata such as response information, message IDs, and token usage[1]. LangChain provides one standard set of message types that behaves the same way across model providers[1].

Strings or message lists

A text prompt is a plain string. It suits a single standalone request that does not need conversation history[1]. Use a message prompt, a list of message objects, for multi-turn conversations, multimodal content, or system instructions[1]. Messages can also be written as dictionaries in OpenAI chat completions format[1]. This example puts a system instruction in front of a user request:

from langchain.messages import SystemMessage, HumanMessage, AIMessage

messages = [
    SystemMessage("You are a poetry expert"),
    HumanMessage("Write a haiku about spring"),
    AIMessage("Cherry blossoms bloom...")
]
response = model.invoke(messages)

Passing a string to invoke() is a shortcut for a single HumanMessage[1].

The four message types

SystemMessage gives the model its initial instructions, which can set its tone, its role, and the guidelines for its answers[1].

HumanMessage represents user input and can include text, images, audio, files, and other multimodal content[1]. Its name field is handled differently by each provider: some use it to identify users, and others ignore it. Check the provider's reference before relying on it[1].

AIMessage is the output of a model invocation. It can carry multimodal data, tool calls, and provider-specific metadata[1]. Its main fields are text, content, content_blocks, tool_calls, id, usage_metadata, and response_metadata[1]. When the provider returns token counts, they appear in usage_metadata[1].

Sometimes it helps to build an AIMessage by hand and insert it into the history, as if the model had produced it. Providers weigh message types differently, so this is a legitimate technique[1].

ToolMessage passes the result of one tool execution back to the model. Its tool_call_id must match the ID of the tool call in the AIMessage[1]. The artifact field holds data that is not sent to the model but can be read by your code, such as raw results or debugging information[1].

How tool calls appear in messages

When a model makes tool calls, they are listed in the tool_calls of the AIMessage, and each call has a name, arguments, and an ID[1]. Reading them looks like this:

for tool_call in response.tool_calls:
    print(f"Tool: {tool_call['name']}")
    print(f"Args: {tool_call['args']}")
    print(f"ID: {tool_call['id']}")

Combining streamed chunks

During streaming, the model yields AIMessageChunk objects. They can be combined into a full message object[1]. The following code collects each chunk and adds them together with +:

chunks = []
full_message = None
for chunk in model.stream("Hi"):
    chunks.append(chunk)
    print(chunk.text)
    full_message = chunk if full_message is None else full_message + chunk

Content blocks and multimodal input

content can be a string, a list of provider-native content blocks, or a list of LangChain's standard content blocks[1]. The content_blocks property lazily parses content into a standard, type-safe representation that works across providers[1].

If you specify content_blocks when initializing a message, content is still populated, but you get a type-safe interface for writing it[1]:

human_message = HumanMessage(content_blocks=[
    {"type": "text", "text": "Hello, how are you?"},
    {"type": "image", "url": "https://example.com/image.jpg"},
])

Image input can come from a URL, from base64 data with a mime_type, or from a provider-managed file ID[1]. Here is an image message that uses a URL:

message = {
    "role": "user",
    "content": [
        {"type": "text", "text": "Describe the content of this image."},
        {"type": "image", "url": "https://example.com/path/to/image.jpg"},
    ]
}

Extra keys can go at the top level of a content block or inside extras. Some providers need additional fields; OpenAI, for example, requires a filename for PDFs[1].

To read standard content blocks outside LangChain, set output_version="v1" on a chat model, or set the LC_OUTPUT_VERSION environment variable to v1. The standard blocks are then stored in message content[1].

Saving and restoring history

Messages can be serialized to plain objects for storage and deserialized back into message instances. This is useful for persisting conversation history and resuming a session[1]. Deserialization instantiates Python objects and can trigger side effects, so never call load() on data from an untrusted or unauthenticated source[1].

Limits and common questions

  • Interactions with chat models are often stateless, so the caller passes the messages it needs on each call[1].
  • Multi-turn agents accumulate long message histories. LangSmith records each turn, tool result, and model response, so you can inspect the full conversation[1].
  • The name field behaves differently across providers, so check each one before depending on it[1].

Next steps

For provider-specific message details, see the reference for the integration you use[1].

Adapted from LangChain's official documentation page on messages[1], released under the MIT License.

Sources

  1. 1
    MessagesLangChain docs (MIT)

Cite this page: Message Types in LangChain. TellWorld, https://www.tellworld.net/practice/practice-langchain-messages. Updated 2026-11-14

Related news

View all