3.3 Messages
本节介绍 LangChain 中的消息系统。
什么是 Messages?
Messages(消息) 是 LangChain 中表示对话上下文的基本单元。每条消息携带内容和元数据,用于表示对话状态。
消息的三要素
每条消息包含三个核心元素:
| 元素 | 说明 | 示例 |
|---|---|---|
| Role | 消息角色 | system, user, assistant, tool |
| Content | 消息内容 | 文本、图片、音频等 |
| Metadata | 元数据 | 消息 ID、token 用量等 |
四种消息类型
1. SystemMessage - 系统消息
定义模型的行为和上下文:
python
from langchain_core.messages import SystemMessage
system_msg = SystemMessage(content="你是一个专业的翻译助手,精通中英双语。")"Tells the model how to behave and provide context for interactions."
2. HumanMessage - 用户消息
表示用户的输入:
python
from langchain_core.messages import HumanMessage
user_msg = HumanMessage(content="请把这句话翻译成英文:今天天气很好。")支持多模态内容:
python
# 图片 + 文本
user_msg = HumanMessage(
content=[
{"type": "text", "text": "这张图片里有什么?"},
{"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}}
]
)3. AIMessage - AI 消息
模型生成的响应:
python
from langchain_core.messages import AIMessage
ai_msg = AIMessage(
content="The weather is very nice today.",
response_metadata={
"model": "gpt-4o",
"finish_reason": "stop"
}
)包含工具调用时:
python
ai_msg = AIMessage(
content="",
tool_calls=[
{
"id": "call_123",
"name": "get_weather",
"args": {"city": "北京"}
}
]
)4. ToolMessage - 工具消息
工具执行的结果:
python
from langchain_core.messages import ToolMessage
tool_msg = ToolMessage(
content="北京:晴,25度",
tool_call_id="call_123" # 对应 AIMessage 中的 tool_call id
)内容格式
消息内容支持多种格式:
简单字符串
python
HumanMessage(content="你好")内容块列表
python
HumanMessage(
content=[
{"type": "text", "text": "请描述这张图片"},
{"type": "image_url", "image_url": {"url": "..."}}
]
)标准内容块类型
| 类型 | 说明 |
|---|---|
text | 文本内容 |
image_url | 图片 URL |
image | Base64 图片 |
audio | 音频内容 |
video | 视频内容 |
file | 文件附件 |
tool_use | 工具调用 |
tool_result | 工具结果 |
基本用法
构建对话
python
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o")
messages = [
SystemMessage(content="你是一个友好的助手"),
HumanMessage(content="你好!")
]
response = model.invoke(messages)
print(response.content) # "你好!有什么可以帮助你的吗?"多轮对话
python
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
messages = [
SystemMessage(content="你是一个数学老师"),
HumanMessage(content="1+1等于多少?"),
AIMessage(content="1+1等于2"),
HumanMessage(content="那2+2呢?"),
]
response = model.invoke(messages)
# AI 会基于上下文回答:2+2等于4使用字典格式
也可以使用字典代替消息对象:
python
messages = [
{"role": "system", "content": "你是一个助手"},
{"role": "user", "content": "你好"},
{"role": "assistant", "content": "你好!"},
{"role": "user", "content": "今天天气怎么样?"},
]
response = model.invoke(messages)消息元数据
访问响应元数据
python
response = model.invoke(messages)
# 响应元数据
print(response.response_metadata)
# {
# "model": "gpt-4o",
# "finish_reason": "stop",
# "usage": {"prompt_tokens": 50, "completion_tokens": 20}
# }
# 消息 ID
print(response.id)Token 使用统计
python
response = model.invoke(messages)
usage = response.response_metadata.get("usage", {})
print(f"输入 tokens: {usage.get('prompt_tokens')}")
print(f"输出 tokens: {usage.get('completion_tokens')}")消息操作
添加消息
python
messages = [SystemMessage(content="你是助手")]
messages.append(HumanMessage(content="你好"))过滤消息
python
# 只获取用户消息
user_messages = [m for m in messages if isinstance(m, HumanMessage)]
# 获取最后 N 条消息
recent_messages = messages[-5:]消息修剪
python
from langchain_core.messages import trim_messages
trimmer = trim_messages(
max_tokens=4000,
strategy="last",
token_counter=model,
include_system=True,
)
trimmed = trimmer.invoke(messages)工具调用流程
完整的工具调用消息流:
python
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
# 1. 用户提问
messages = [HumanMessage(content="北京天气怎么样?")]
# 2. AI 决定调用工具
ai_response = AIMessage(
content="",
tool_calls=[{
"id": "call_abc123",
"name": "get_weather",
"args": {"city": "北京"}
}]
)
messages.append(ai_response)
# 3. 执行工具,添加结果
tool_result = ToolMessage(
content="北京:晴,25度,微风",
tool_call_id="call_abc123"
)
messages.append(tool_result)
# 4. AI 生成最终回复
final_response = model.invoke(messages)
# "北京今天天气晴朗,温度25度,有微风,非常适合外出。"多模态消息
图片理解
python
message = HumanMessage(
content=[
{"type": "text", "text": "图片中有几个人?"},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/photo.jpg",
"detail": "high" # 可选:low, high, auto
}
}
]
)Base64 图片
python
import base64
with open("image.png", "rb") as f:
image_data = base64.b64encode(f.read()).decode()
message = HumanMessage(
content=[
{"type": "text", "text": "描述这张图片"},
{
"type": "image_url",
"image_url": {
"url": f"data:image/png;base64,{image_data}"
}
}
]
)什么是 Base64?
Base64 是一种将二进制数据(如图片)编码为纯文本的方法。它把每 3 字节数据转换为 4 个可打印 ASCII 字符。
原始图片 (二进制) → Base64 编码 → 纯文本字符串
0x89 0x50 0x4E... → 编码转换 → "iVBORw0KGgo..."为什么使用 Base64?
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| URL | 简洁、模型直接获取 | 需公网可访问 | 公开图片、CDN 托管 |
| Base64 | 本地文件、无需托管、离线可用 | 数据量增加 33% | 本地图片、私有图片、批处理 |
常见使用场景
- 本地文件分析 - 上传本地截图、照片让 AI 分析
- 隐私数据处理 - 不需要将图片上传到公网
- 自动化流程 - 程序生成的图片直接发送给模型
- 离线环境 - 无需依赖外部 URL
Data URI 格式
data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...
└──类型──┘ └──Base64 编码数据──┘常见 MIME 类型:
image/png- PNG 图片image/jpeg- JPEG 图片image/gif- GIF 图片image/webp- WebP 图片
最佳实践
- 始终包含系统消息 - 定义 AI 的角色和行为
- 保持消息顺序 - 确保对话流程正确
- 管理上下文长度 - 使用修剪避免超出限制
- 正确处理工具消息 - tool_call_id 必须匹配
上一节:3.2 Models
下一节:3.4 Tools