跳转至

Messages

Abstract

在 LangChain 中,Message 是模型上下文的基本单位。无论是直接调用 Chat Model,还是在 Agent 中维护对话状态,本质上都是在组织一组 messages。每条 message 通常包含三类信息:角色、内容和元数据。

  • Role:表示消息来源或类型,例如 systemuserassistanttool
  • Content:消息正文,可以是文本,也可以是图片、音频、文件等多模态内容。
  • Metadata:额外信息,例如 message id、token usage、response metadata、tool call id 等。

LangChain 提供统一的 message 类型,让不同模型 provider 之间能尽量使用一致的消息表示。

基本使用

最简单的方式是创建 message 对象,然后传给模型:

from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage, SystemMessage

model = init_chat_model("gpt-5-nano")

messages = [
    SystemMessage("You are a helpful assistant."),
    HumanMessage("Hello, how are you?"),
]

response = model.invoke(messages)

如果只是一次性的简单请求,也可以直接传字符串。字符串可以理解为单条 HumanMessage 的快捷写法:

response = model.invoke("Write a haiku about spring")

对于多轮对话、系统指令、多模态内容或工具调用,建议显式使用 message 列表:

from langchain.messages import SystemMessage, HumanMessage, AIMessage

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

response = model.invoke(messages)

也可以使用 OpenAI chat completions 风格的字典格式:

messages = [
    {"role": "system", "content": "You are a poetry expert."},
    {"role": "user", "content": "Write a haiku about spring."},
    {"role": "assistant", "content": "Cherry blossoms bloom..."},
]

response = model.invoke(messages)

Message 类型

SystemMessage

SystemMessage 用来设定模型行为,例如角色、语气、任务边界和回答规则。它通常放在消息列表开头。

from langchain.messages import SystemMessage, HumanMessage

messages = [
    SystemMessage("You are a senior Python developer. Be concise and practical."),
    HumanMessage("How do I create a REST API?"),
]

response = model.invoke(messages)

System message 适合放稳定的全局指令,不适合塞入频繁变化的大量业务数据。长上下文或动态上下文更适合通过检索、memory 或 middleware 管理。

HumanMessage

HumanMessage 表示用户输入。它可以包含普通文本,也可以包含多模态内容。

from langchain.messages import HumanMessage

response = model.invoke([
    HumanMessage("What is machine learning?")
])

HumanMessage 也可以带元数据:

human_msg = HumanMessage(
    content="Hello!",
    name="alice",
    id="msg_123",
)

name 字段在不同 provider 中行为不完全一致,有些会使用它区分用户,有些会忽略。

AIMessage

AIMessage 表示模型输出。调用 chat model 后通常会得到一个 AIMessage,其中可能包含文本、工具调用、token 统计和 provider 返回的元数据。

response = model.invoke("Explain AI in one sentence.")

print(response.text)
print(response.usage_metadata)
print(response.response_metadata)

在维护对话历史时,也可以手动创建 AIMessage,把它作为历史上下文的一部分:

from langchain.messages import AIMessage, HumanMessage, SystemMessage

messages = [
    SystemMessage("You are a helpful assistant."),
    HumanMessage("Can you help me?"),
    AIMessage("Yes, what would you like to do?"),
    HumanMessage("What's 2 + 2?"),
]

response = model.invoke(messages)

AIMessage 常见字段:

  • text:标准文本内容。
  • content:原始内容,可能是字符串或 provider-native content blocks。
  • content_blocks:LangChain 标准化后的内容块。
  • tool_calls:模型请求调用的工具列表。
  • usage_metadata:token 使用量等统计信息。
  • response_metadata:provider 返回的额外响应信息。

ToolMessage

当模型发起 tool call 后,工具执行结果需要通过 ToolMessage 返回给模型。ToolMessagetool_call_id 必须和原始 tool call 的 id 匹配,这样模型才能知道结果对应哪次工具调用。

from langchain.messages import AIMessage, HumanMessage, ToolMessage

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

tool_message = ToolMessage(
    content="Sunny, 72°F",
    tool_call_id="call_123",
    name="get_weather",
)

messages = [
    HumanMessage("What's the weather in San Francisco?"),
    ai_message,
    tool_message,
]

response = model.invoke(messages)

如果使用 Agent,工具执行循环通常由 Agent 自动管理;如果单独使用 Model,就需要自己执行工具并维护 AIMessage / ToolMessage 的往返。

ToolMessage 还可以包含 artifact,用于保存不发送给模型但程序后续需要使用的附加数据,例如检索到的文档 id、页码、原始 JSON 等。

Message Content

Message 的 content 是实际发送给模型的 payload。它可以是:

  1. 普通字符串。
  2. provider 原生格式的 content blocks。
  3. LangChain 标准 content blocks。
from langchain.messages import HumanMessage

text_message = HumanMessage("Hello, how are you?")

image_message = HumanMessage(content_blocks=[
    {"type": "text", "text": "Describe this image."},
    {"type": "image", "url": "https://example.com/image.jpg"},
])

content_blocks 是 LangChain v1 引入的标准化表示,用来统一不同 provider 的内容格式。它不是替代 content,而是提供更类型化、更跨 provider 的访问方式。

常见 content block 类型:

  • text:普通文本。
  • reasoning:模型推理内容或推理摘要。
  • image:图片输入或输出。
  • audio:音频输入或输出。
  • video:视频输入或输出。
  • file:文件,例如 PDF。
  • tool_call:工具调用请求。
  • tool_call_chunk:流式工具调用片段。
  • server_tool_call:由 provider 服务端执行的工具调用。
  • server_tool_result:服务端工具执行结果。
  • non_standard:provider 特有的扩展内容。

多模态消息

支持多模态的模型可以接收图片、音频、视频或文件。LangChain 使用标准 content blocks 描述这些内容。

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

response = model.invoke([message])

也可以使用 base64 或 provider-managed file id:

message = {
    "role": "user",
    "content": [
        {"type": "text", "text": "Summarize this PDF."},
        {
            "type": "file",
            "base64": "AAAAIGZ0eXBtcDQy...",
            "mime_type": "application/pdf",
        },
    ],
}

不是所有模型都支持所有文件类型。实际使用前要确认 provider 的模型能力、文件大小限制和 MIME type 要求。

Streaming 与 Chunks

使用 stream 时,模型不会一次性返回完整 AIMessage,而是返回多个 AIMessageChunk。这些 chunk 可以逐步展示,也可以累加成完整消息。

full_message = None

for chunk in model.stream("Explain LangChain messages."):
    print(chunk.text, end="", flush=True)
    full_message = chunk if full_message is None else full_message + chunk

工具调用在流式输出中也可能以 tool_call_chunk 的形式逐步出现,因此消费端需要能处理“未完成的 JSON 参数”或等待 chunk 聚合完成。

与 Chat Model 和 Agent 的关系

Chat Model 接收一组 messages,返回一个 AIMessage。如果应用需要维护上下文,就把新的 user message、AI response、tool message 继续追加到消息列表中。

Agent 也是围绕 messages 工作:用户输入、模型决策、工具调用、工具结果、最终回答都会进入 message state。理解 messages 的结构,有助于理解 Agent 为什么能在多轮工具调用中保持上下文。

小结

Messages 是 LangChain 中承载上下文的核心结构。SystemMessage 定义行为,HumanMessage 表示用户输入,AIMessage 表示模型输出,ToolMessage 连接工具执行结果。对于真实应用,消息管理不仅是“把聊天记录传给模型”,还包括多模态内容、工具调用、token 使用、流式 chunk、元数据和上下文窗口控制。