LangChain:消息(Message)类型和特性详解
LangChain的消息系统是结构化对话管理的核心组件,通过明确区分角色和上下文,使大模型能精准处理多轮对话与工具调用。
其核心是四种基础消息类型(SystemMessage、HumanMessage、AIMessage、ToolMessage),官方文档明确要求必须使用类型化消息对象而非原始字典,以确保跨模型兼容性和功能完整性。
核心概念
消息是 LangChain 中模型的基本上下文单元,代表模型的输入和输出,携带内容和元数据,用于表示与 LLM 交互时的对话状态。每条消息是一个对象,包含三个核心要素:
- 角色(Role):标识消息类型(如
system、user、assistant) - 内容(Content):消息的实际内容,可以是文本、图像、音频、文档等
- 元数据(Metadata):可选字段,如响应信息、消息 ID、token 使用量等
LangChain 提供跨所有模型提供商的标准消息类型,确保无论调用哪个模型,行为都保持一致。
核心消息类型
所有消息类都继承自 BaseMessage,LangChain 提供了以下主要类型:
| 消息类 | 字典Role | 用途 | 前提条件 |
|---|---|---|---|
| SystemMessage | system |
设定 AI 的行为规范、背景、角色定位、知识边界 | 通常位于对话开头,优先级最高 |
| HumanMessage | user |
代表用户(人类)的输入或提问 | — |
| AIMessage | assistant |
代表模型的回复,可能包含工具调用 | — |
| ToolMessage | tool |
代表工具执行后的结果,包含 tool_call_id |
必须在 AIMessage 包含工具调用之后出现 |
| ChatMessage | 自定义 | 当标准角色不够用时,手动指定 role 参数 |
— |
LangChain的消息系统通过结构化角色分工解决上下文混乱问题,必须严格使用类型化消息对象并维护完整对话链。
对比传统方式的好处:使用这些语义化的消息类,可以避免手动写 {"role": ...} 字典,更重要的是可以直接用 isinstance(last_message, AIMessage) 进行类型判断,代码可读性和可维护性显著提升。
SystemMessage
SystemMessage:系统消息
作用:定义AI的角色、行为规则及知识边界,优先级最高,通常作为消息列表的首条消息。
关键特性:
- 决定模型的“身份设定”,直接影响输出风格和内容范围。
- 若模型不支持系统消息(如部分旧版API),LangChain会自动将其合并到
HumanMessage中。
示例代码:
1
2
3
4
5
6from langchain_core.messages import SystemMessage
system_msg = SystemMessage(
content="你是一名金融分析师,仅回答2023年后的A股市场数据问题,"
"超出范围时回复'该问题超出我的知识边界'"
)
HumanMessage
HumanMessage:用户消息
作用:表示用户输入内容,是对话的核心触发点。
关键特性:
- 支持纯文本或多模态输入(如文本+图片),需模型本身支持多模态能力。
- 可附加元数据(如用户ID、会话ID)用于上下文追踪。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12from langchain_core.messages import HumanMessage
# 纯文本输入
human_msg = HumanMessage(content="2024年上证指数最高点是多少?")
# 多模态输入(需模型支持,如GPT-4o)
human_msg_multimodal = HumanMessage(
content=[
{"type": "text", "text": "描述这张图片的金融含义"},
{"type": "image_url", "image_url": "https://example.com/chart.png"}
]
)消息内容不再局限于纯文本。LangChain 支持标准化的多模态内容块,可以自然交错排列文本、图像、音频等内容。
AIMessage
AIMessag:AI回复消息
作用:存储模型生成的响应,包含工具调用请求或最终答案。
关键特性:
content字段存储文本回复,tool_calls字段存储工具调用指令(如需外部工具)。- 支持流式输出(
AIMessageChunk),逐块返回响应内容。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14from langchain_core.messages import AIMessage
# 普通文本回复
ai_msg = AIMessage(content="2024年上证指数最高点为3,400点(截至2024年12月)")
# 工具调用请求(模拟模型需查询实时数据)
ai_msg_with_tool = AIMessage(
content="",
tool_calls=[{
"name": "get_stock_data",
"args": {"market": "A股", "metric": "index_high"},
"id": "call_abc123" # 必须唯一标识调用
}]
)
ToolMessage
ToolMessage:工具结果消息
作用:传递工具执行结果给模型,**必须关联
tool_call_id**。关键特性:
tool_call_id必须与AIMessage中的调用ID完全匹配,否则模型无法关联结果。content为工具返回的字符串化结果,artifact可存储未发送给模型的原始数据。
示例代码:
1
2
3
4
5
6
7from langchain_core.messages import ToolMessage
tool_msg = ToolMessage(
content="2024年上证指数最高点:3,421.87点(2024-08-15)",
tool_call_id="call_abc123", # 必须与AIMessage中的ID一致
name="get_stock_data"
)
消息组合与多轮对话
多轮对话的正确结构
必须按顺序组织消息列表,保留完整对话历史:
1
2
3
4
5
6
7
8
9from langchain_core.messages import SystemMessage, HumanMessage, AIMessage, ToolMessage
messages = [
SystemMessage(content="你是一名金融分析师..."),
HumanMessage(content="2024年上证指数最高点是多少?"),
AIMessage(tool_calls=[{"name": "get_stock_data", "id": "call_abc123"}]),
ToolMessage(content="3,421.87点", tool_call_id="call_abc123"),
HumanMessage(content="这个数据来源可靠吗?") # 新问题需带上历史
]
错误 vs 正确实践
错误做法:每次仅传当前问题,丢失上下文:
1
2# ❌ 错误:无历史记录,模型无法关联问题
messages = [HumanMessage(content="这个数据来源可靠吗?")]正确做法:始终携带必要历史,确保逻辑连贯:
1
2
3
4
5
6
7
8# ✅ 正确:包含系统设定、历史问题与工具结果
messages = [
SystemMessage(content="..."),
HumanMessage(content="2024年上证指数最高点..."),
AIMessage(tool_calls=[...]),
ToolMessage(...),
HumanMessage(content="这个数据来源可靠吗?") # 当前问题
]
消息的高级特性
元数据(Metadata)
每条消息都可以携带丰富的元数据:
response_metadata:来自模型提供商的响应信息,如 token 使用量、finish_reason 等id:消息的唯一标识符additional_kwargs:模型供应商特有的额外字段
1 | # 访问响应元数据(以 Python 为例) |
流式消息块(Message Chunks)
LangChain 为每种消息类型提供了流式分块版本,用于实时流式输出
| 消息类型 | 分块类型 | 用途 |
|---|---|---|
AIMessage |
AIMessageChunk |
流式接收 AI 回复片段 |
HumanMessage |
HumanMessageChunk |
流式处理用户输入 |
SystemMessage |
SystemMessageChunk |
流式系统提示 |
ToolMessage |
ToolMessageChunk |
流式工具结果 |
当使用流式输出时,模型会逐块返回数据。LangChain 提供了对应的 Chunk 类(如 AIMessageChunk),且支持用 + 运算符拼接多个块:
1 | # Python 示例:流式输出与消息块拼接 |
消息实用工具(Utilities)
langchain_core.messages.utils 模块提供了一系列消息处理工具函数:
| 函数 | 用途 |
|---|---|
convert_to_messages |
将多种格式(字典、消息列表等)统一转换为消息列表 |
messages_from_dict |
从字典序列反序列化为消息对象 |
get_buffer_string |
将消息列表拼接成一个字符串 |
filter_messages |
按名称、类型或 ID 过滤消息 |
trim_messages |
按 token 数量或消息数量修剪消息列表 |
merge_message_runs |
合并同类型的连续消息(ToolMessage 除外) |
1 | # filter_messages 示例:只保留人类消息和 AI 后续消息 |
1 | # trim_messages 示例:修剪消息以保持 token 预算,并保留系统消息 |
示例代码
多轮对话
1 | # 安装:pip install langchain langchain-openai |
官方示例
官方示例:完整工具调用流程
1 | from langchain_core.messages import SystemMessage, HumanMessage, AIMessage, ToolMessage |
实践建议
消息管理规范
必须显式使用消息类型,避免原始字典:
1
2
3
4
5# ✅ 官方推荐:类型化消息
messages = [SystemMessage(content="..."), HumanMessage(content="...")]
# ❌ 不推荐:原始字典(可能丢失功能)
messages = [{"role": "system", "content": "..."}, {"role": "user", "content": "..."}]为消息添加ID:便于追踪和删除特定消息(如调试时)。
工具调用关键规则
tool_call_id必须严格匹配:AIMessage中的调用ID与ToolMessage的tool_call_id需完全一致。- 工具结果需结构化:
ToolMessage.content应为字符串化结果,避免直接传递复杂对象。
多模态支持
仅多模态模型(如GPT-4o)支持图像/音频输入,需按规范格式组织 content:
1
2
3
4HumanMessage(content=[
{"type": "text", "text": "分析此图表趋势"},
{"type": "image_url", "image_url": "https://example.com/chart.jpg"}
])
问题与注意事项
| 问题 | 注意事项 |
|---|---|
| 消息顺序要求 | 大多数聊天模型期望对话以 HumanMessage 或 SystemMessage + HumanMessage 开头;ToolMessage 必须出现在对应的 AIMessage(包含工具调用)之后 |
| SystemMessage 限制 | 一次通常只能有一个有效 SystemMessage;多个 SystemMessage 可能会被模型忽略或覆盖 |
| Token 计算 | 不同模型的 tokenizer 不同,trim_messages 的 token_counter 应使用模型自身的计数方法 |
| 多模态模型支持 | 仅多模态模型(如GPT-4o)支持图像/音频输入,需按规范格式组织 content,使用前请查阅模型提供商的文档 |
| 版本变更 | 在较新的 LangChain 版本中,消息核心类主要存放在 langchain_core.messages 模块下 |
核心总结
LangChain的消息系统通过结构化角色分工解决上下文混乱问题,必须严格使用类型化消息对象并维护完整对话链。多轮对话中,遗漏历史消息会导致逻辑断裂;工具调用时,ID匹配是结果整合的关键。官方文档强调,正确使用消息类型是构建可靠对话应用的基础。
LangChain 的消息系统是一个标准化、可扩展、跨模型的抽象层:
- 标准化:统一接口屏蔽不同模型提供商的差异
- 结构化:通过类型系统明确区分角色和用途
- 可追踪:通过
tool_call_id实现工具调用的完整链路追踪 - 多模态:
content支持文本、图像、音频等混合内容
掌握消息系统是构建复杂 Agent 应用的基础,特别是在处理多轮对话、工具调用、流式输出等场景时。
快速参考表
| 场景 | 推荐的消息类型 | 关键点 |
|---|---|---|
| 设定 AI 角色/行为 | SystemMessage |
放在对话开头,只设置一次 |
| 用户输入 | HumanMessage(content=user_input) |
— |
| 模型回复 | AIMessage |
由 model.invoke() 返回 |
| 工具执行结果 | ToolMessage(content=result, tool_call_id=id) |
必须在工具调用之后 |
| 图片输入 | HumanMessage(content=[{type: "image_url", ...}]) |
需模型支持 |
| 流式输出 | AIMessageChunk |
可用 + 拼接 |
| 过滤消息 | filter_messages() |
按类型、名称或 ID 筛选 |
| 控制 token 预算 | trim_messages() |
保留系统消息,确保有效开头 |
| 自定义角色 | ChatMessage(role="custom", content=...) |
用于标准角色之外的场景 |
提示:官方文档入口常变,需要查阅最新资料时,建议使用 site:docs.langchain.com messages 或 site:reference.langchain.com python/core/messages 进行定向搜索。
LangChain:消息(Message)类型和特性详解
http://blog.gxitsky.com/2026/05/04/AI-LangChain-045-Message/

