消息是 LangChain 中模型上下文的基本单元。它们表示模型的输入和输出,携带在与 LLM 交互时表示对话状态所需的内容和元数据。 消息是包含以下内容的对象:
  • 角色 - 标识消息类型(例如 systemuser
  • 内容 - 表示消息的实际内容(如文本、图像、音频、文档等)
  • 元数据 - 可选字段,如响应信息、消息 ID 和令牌使用情况
LangChain 提供了一个适用于所有模型提供商的标准消息类型,确保无论调用哪个模型都具有一致的行为。

基本用法

使用消息的最简单方法是创建消息对象并在调用时将它们传递给模型。
import { initChatModel, HumanMessage, SystemMessage } from "langchain";

const model = await initChatModel("gpt-5-nano");

const systemMsg = new SystemMessage("You are a helpful assistant.");
const humanMsg = new HumanMessage("Hello, how are you?");

const messages = [systemMsg, humanMsg];
const response = await model.invoke(messages);  // Returns AIMessage

文本提示

文本提示是字符串 - 适用于不需要保留对话历史记录的简单生成任务。
const response = await model.invoke("Write a haiku about spring");
在以下情况下使用文本提示:
  • 您有一个单一的独立请求
  • 您不需要对话历史记录
  • 您希望代码复杂性最小

消息提示

或者,您可以通过提供消息对象列表向模型传递消息列表。
import { SystemMessage, HumanMessage, AIMessage } from "langchain";

const messages = [
  new SystemMessage("You are a poetry expert"),
  new HumanMessage("Write a haiku about spring"),
  new AIMessage("Cherry blossoms bloom..."),
];
const response = await model.invoke(messages);
在以下情况下使用消息提示:
  • 管理多轮对话
  • 处理多模态内容(图像、音频、文件)
  • 包含系统指令

字典格式

您也可以直接以 OpenAI 聊天完成格式指定消息。
const messages = [
  { role: "system", content: "You are a poetry expert" },
  { role: "user", content: "Write a haiku about spring" },
  { role: "assistant", content: "Cherry blossoms bloom..." },
];
const response = await model.invoke(messages);

消息类型

系统消息

@[SystemMessage] 表示一组初始指令,用于引导模型的行为。您可以使用系统消息来设置语气、定义模型的角色并建立响应指南。
Basic instructions
import { SystemMessage, HumanMessage, AIMessage } from "langchain";

const systemMsg = new SystemMessage("You are a helpful coding assistant.");

const messages = [
  systemMsg,
  new HumanMessage("How do I create a REST API?"),
];
const response = await model.invoke(messages);
Detailed persona
import { SystemMessage, HumanMessage } from "langchain";

const systemMsg = new SystemMessage(`
You are a senior TypeScript developer with expertise in web frameworks.
Always provide code examples and explain your reasoning.
Be concise but thorough in your explanations.
`);

const messages = [
  systemMsg,
  new HumanMessage("How do I create a REST API?"),
];
const response = await model.invoke(messages);

Human Message

A @[HumanMessage] represents user input and interactions. They can contain text, images, audio, files, and any other amount of multimodal content.

Text content

Message object
const response = await model.invoke([
  new HumanMessage("What is machine learning?"),
]);
String shortcut
const response = await model.invoke("What is machine learning?");

Message metadata

Add metadata
const humanMsg = new HumanMessage({
  content: "Hello!",
  name: "alice",
  id: "msg_123",
});
name 字段的行为因提供商而异 - 有些将其用于用户识别,有些则忽略它。要检查,请参阅模型提供商的参考

AI 消息

AIMessage 表示模型调用的输出。它们可以包括多模态数据、工具调用和您稍后可以访问的提供商特定元数据。
const response = await model.invoke("Explain AI");
console.log(typeof response);  // AIMessage
AIMessage 对象在调用模型时由模型返回,它包含响应中的所有相关元数据。 提供商对消息类型的权衡/上下文化方式不同,这意味着有时手动创建一个新的 AIMessage 对象并将其插入消息历史记录中,就像它来自模型一样,会很有帮助。
import { AIMessage, SystemMessage, HumanMessage } from "langchain";

const aiMsg = new AIMessage("I'd be happy to help you with that question!");

const messages = [
  new SystemMessage("You are a helpful assistant"),
  new HumanMessage("Can you help me?"),
  aiMsg,  // Insert as if it came from the model
  new HumanMessage("Great! What's 2+2?")
]

const response = await model.invoke(messages);
text
string
The text content of the message.
content
string | ContentBlock[]
The raw content of the message.
content_blocks
ContentBlock.Standard[]
The standardized content blocks of the message. (See content)
tool_calls
ToolCall[] | None
The tool calls made by the model. Empty if no tools are called.
id
string
A unique identifier for the message (either automatically generated by LangChain or returned in the provider response)
usage_metadata
UsageMetadata | None
The usage metadata of the message, which can contain token counts when available. See UsageMetadata.
response_metadata
ResponseMetadata | None
The response metadata of the message.

Tool calls

When models make tool calls, they’re included in the AIMessage:
const modelWithTools = model.bindTools([getWeather]);
const response = await modelWithTools.invoke("What's the weather in Paris?");

for (const toolCall of response.tool_calls) {
  console.log(`Tool: ${toolCall.name}`);
  console.log(`Args: ${toolCall.args}`);
  console.log(`ID: ${toolCall.id}`);
}
Other structured data, such as reasoning or citations, can also appear in message content.

Token usage

An AIMessage can hold token counts and other usage metadata in its usage_metadata field:
import { initChatModel } from "langchain";

const model = await initChatModel("gpt-5-nano");

const response = await model.invoke("Hello!");
console.log(response.usage_metadata);
{
  "output_tokens": 304,
  "input_tokens": 8,
  "total_tokens": 312,
  "input_token_details": {
    "cache_read": 0
  },
  "output_token_details": {
    "reasoning": 256
  }
}
See UsageMetadata for details.

Streaming and chunks

During streaming, you’ll receive AIMessageChunk objects that can be combined into a full message object:
import { AIMessageChunk } from "langchain";

let finalChunk: AIMessageChunk | undefined;
for (const chunk of chunks) {
  finalChunk = finalChunk ? finalChunk.concat(chunk) : chunk;
}

Tool Message

For models that support tool calling, AI messages can contain tool calls. Tool messages are used to pass the results of a single tool execution back to the model. Tools can generate @[ToolMessage] objects directly. Below, we show a simple example. Read more in the tools guide.
import { AIMessage, ToolMessage } from "langchain";

const aiMessage = new AIMessage({
  content: [],
  tool_calls: [{
    name: "get_weather",
    args: { location: "San Francisco" },
    id: "call_123"
  }]
});

const toolMessage = new ToolMessage({
  content: "Sunny, 72°F",
  tool_call_id: "call_123"
});

const messages = [
  new HumanMessage("What's the weather in San Francisco?"),
  aiMessage,  // Model's tool call
  toolMessage,  // Tool execution result
];

const response = await model.invoke(messages);  // Model processes the result
content
string
required
The stringified output of the tool call.
tool_call_id
string
required
The ID of the tool call that this message is responding to. (this must match the ID of the tool call in the AIMessage)
name
string
required
The name of the tool that was called.
artifact
dict
Additional data not sent to the model but can be accessed programmatically.
The artifact field stores supplementary data that won’t be sent to the model but can be accessed programmatically. This is useful for storing raw results, debugging information, or data for downstream processing without cluttering the model’s context.
For example, a retrieval tool could retrieve a passage from a document for reference by a model. Where message content contains text that the model will reference, an artifact can contain document identifiers or other metadata that an application can use (e.g., to render a page). See example below:
import { ToolMessage } from "langchain";

// Artifact available downstream
const artifact = { document_id: "doc_123", page: 0 };

const toolMessage = new ToolMessage({
  content: "It was the best of times, it was the worst of times.",
  tool_call_id: "call_123",
  name: "search_books",
  artifact
});
See the RAG tutorial for an end-to-end example of building retrieval agents with LangChain.

Message content

You can think of a message’s content as the payload of data that gets sent to the model. Messages have a content attribute that is loosely-typed, supporting strings and lists of untyped objects (e.g., dictionaries). This allows support for provider-native structures directly in LangChain chat models, such as multimodal content and other data. Separately, LangChain provides dedicated content types for text, reasoning, citations, multi-modal data, server-side tool calls, and other message content. See content blocks below. LangChain chat models accept message content in the content attribute, and can contain:
  1. A string
  2. A list of content blocks in a provider-native format
  3. A list of LangChain’s standard content blocks
See below for an example using multimodal inputs:
import { HumanMessage } from "langchain";

// String content
const humanMessage = new HumanMessage("Hello, how are you?");

// Provider-native format (e.g., OpenAI)
const humanMessage = new HumanMessage({
  content: [
    { type: "text", text: "Hello, how are you?" },
    {
      type: "image_url",
      image_url: { url: "https://example.com/image.jpg" },
    },
  ],
});

// List of standard content blocks
const humanMessage = new HumanMessage({
  contentBlocks: [
    { type: "text", text: "Hello, how are you?" },
    { type: "image", url: "https://example.com/image.jpg" },
  ],
});

Standard content blocks

LangChain provides a standard representation for message content that works across providers. Message objects implement a contentBlocks property that will lazily parse the content attribute into a standard, type-safe representation. For example, messages generated from ChatAnthropic or ChatOpenAI will include thinking or reasoning blocks in the format of the respective provider, but can be lazily parsed into a consistent ReasoningContentBlock representation:
  • Anthropic
  • OpenAI
import { AIMessage } from "@langchain/core/messages";

const message = new AIMessage({
  content: [
    {
      "type": "thinking",
      "thinking": "...",
      "signature": "WaUjzkyp...",
    },
    {
      "type":"text",
      "text": "...",
      "id": "msg_abc123",
    },
  ],
  response_metadata: { model_provider: "anthropic" },
});

console.log(message.contentBlocks);
See the integrations guides to get started with the inference provider of your choice.
Serializing standard contentIf an application outside of LangChain needs access to the standard content block representation, you can opt-in to storing content blocks in message content.To do this, you can set the LC_OUTPUT_VERSION environment variable to v1. Or, initialize any chat model with outputVersion: "v1":
import { initChatModel } from "langchain";

const model = await initChatModel(
  "gpt-5-nano",
  { outputVersion: "v1" }
);

Multimodal

Multimodality refers to the ability to work with data that comes in different forms, such as text, audio, images, and video. LangChain includes standard types for these data that can be used across providers. Chat models can accept multimodal data as input and generate it as output. Below we show short examples of input messages featuring multimodal data.
Extra keys can be included top-level in the content block or nested in "extras": {"key": value}.OpenAI and AWS Bedrock Converse, for example, require a filename for PDFs. See the provider page for your chosen model for specifics.
// From URL
const message = new HumanMessage({
  content: [
    { type: "text", text: "Describe the content of this image." },
    {
      type: "image",
      source_type: "url",
      url: "https://example.com/path/to/image.jpg"
    },
  ],
});

// From base64 data
const message = new HumanMessage({
  content: [
    { type: "text", text: "Describe the content of this image." },
    {
      type: "image",
      source_type: "base64",
      data: "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
    },
  ],
});

// From provider-managed File ID
const message = new HumanMessage({
  content: [
    { type: "text", text: "Describe the content of this image." },
    { type: "image", source_type: "id", id: "file-abc123" },
  ],
});
Not all models support all file types. Check the model provider’s reference for supported formats and size limits.

Content block reference

Content blocks are represented (either when creating a message or accessing the contentBlocks field) as a list of typed objects. Each item in the list must adhere to one of the following block types:
Purpose: Standard text output
type
string
required
Always "text"
text
string
required
The text content
annotations
Citation[]
List of annotations for the text
Example:
{
    type: "text",
    text: "Hello world",
    annotations: []
}
Purpose: Model reasoning steps
type
string
required
Always "reasoning"
reasoning
string
required
The reasoning content
Example:
{
    type: "reasoning",
    reasoning: "The user is asking about..."
}
Purpose: Image data
type
string
required
Always "image"
url
string
URL pointing to the image location.
data
string
Base64-encoded image data.
fileId
string
Reference ID to an externally stored image (e.g., in a provider’s file system or in a bucket).
mimeType
string
Image MIME type (e.g., image/jpeg, image/png)
Purpose: Audio data
type
string
required
Always "audio"
url
string
URL pointing to the audio location.
data
string
Base64-encoded audio data.
fileId
string
Reference ID to an externally stored audio file (e.g., in a provider’s file system or in a bucket).
mimeType
string
Audio MIME type (e.g., audio/mpeg, audio/wav)
Purpose: Video data
type
string
required
Always "video"
url
string
URL pointing to the video location.
data
string
Base64-encoded video data.
fileId
string
Reference ID to an externally stored video file (e.g., in a provider’s file system or in a bucket).
mimeType
string
Video MIME type (e.g., video/mp4, video/webm)
Purpose: Generic files (PDF, etc)
type
string
required
Always "file"
url
string
URL pointing to the file location.
data
string
Base64-encoded file data.
fileId
string
Reference ID to an externally stored file (e.g., in a provider’s file system or in a bucket).
mimeType
string
File MIME type (e.g., application/pdf)
Purpose: Document text (.txt, .md)
type
string
required
Always "text-plain"
text
string
required
The text content
title
string
Title of the text content
mimeType
string
MIME type of the text (e.g., text/plain, text/markdown)
Purpose: Function calls
type
string
required
Always "tool_call"
name
string
required
Name of the tool to call
args
object
required
Arguments to pass to the tool
id
string
required
Unique identifier for this tool call
Example:
{
    type: "tool_call",
    name: "search",
    args: { query: "weather" },
    id: "call_123"
}
Purpose: Streaming tool fragments
type
string
required
Always "tool_call_chunk"
name
string
Name of the tool being called
args
string
Partial tool arguments (may be incomplete JSON)
id
string
Tool call identifier
index
number | string
required
Position of this chunk in the stream
Purpose: Malformed calls
type
string
required
Always "invalid_tool_call"
name
string
Name of the tool that failed to be called
args
string
Raw arguments that failed to parse
error
string
required
Description of what went wrong
Common errors: Invalid JSON, missing required fields
Purpose: Tool call that is executed server-side.
type
string
required
Always "server_tool_call"
id
string
required
An identifier associated with the tool call.
name
string
required
The name of the tool to be called.
args
string
required
Partial tool arguments (may be incomplete JSON)
Purpose: Streaming server-side tool call fragments
type
string
required
Always "server_tool_call_chunk"
id
string
An identifier associated with the tool call.
name
string
Name of the tool being called
args
string
Partial tool arguments (may be incomplete JSON)
index
number | string
Position of this chunk in the stream
Purpose: Search results
type
string
required
Always "server_tool_result"
tool_call_id
string
required
Identifier of the corresponding server tool call.
id
string
Identifier associated with the server tool result.
status
string
required
Execution status of the server-side tool. "success" or "error".
output
Output of the executed tool.
Purpose: Provider-specific escape hatch
type
string
required
Always "non_standard"
value
object
required
Provider-specific data structure
Usage: For experimental or provider-unique features
Additional provider-specific content types may be found within the reference documentation of each model provider.
Each of these content blocks mentioned above are indvidually addressable as types when importing the @[ContentBlock] type.
import { ContentBlock } from "langchain";

// Text block
const textBlock: ContentBlock.Text = {
    type: "text",
    text: "Hello world",
}

// Image block
const imageBlock: ContentBlock.Multimodal.Image = {
    type: "image",
    url: "https://example.com/image.png",
    mimeType: "image/png",
}
View the canonical type definitions in the @[API reference][langchain.messages].
Content blocks were introduced as a new property on messages in LangChain v1 to standardize content formats across providers while maintaining backward compatibility with existing code. Content blocks are not a replacement for the @[content][BaseMessage(content)] property, but rather a new property that can be used to access the content of a message in a standardized format.

Use with chat models

Chat models accept a sequence of message objects as input and return an AIMessage as output. Interactions are often stateless, so that a simple conversational loop involves invoking a model with a growing list of messages. Refer to the below guides to learn more:
Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.