主题
消息
消息是 LangChain 中模型上下文的基本单元。它们表示模型的输入和输出,同时携带内容与元数据,用于在与 LLM 交互时表示对话的状态。
消息是包含以下内容的对象:
角色 - 标识消息类型(例如 system、user) *
内容 - 表示消息的实际内容(如文本、图像、音频、文档等) *
•元数据 - 可选字段,例如响应信息、消息 ID 和 token 用量
LangChain 提供了一种标准消息类型,可跨所有模型服务商使用,确保无论调用哪个模型,行为都保持一致。
基本用法
使用消息最简单的方式是创建消息对象,并在调用模型时将它们传给模型。
python
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage, AIMessage, SystemMessage
model = init_chat_model("gpt-5-nano")
system_msg = SystemMessage("You are a helpful assistant.")
human_msg = HumanMessage("Hello, how are you?")
# Use with chat models
messages = [system_msg, human_msg]
response = model.invoke(messages) # Returns AIMessage1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
TIP
多轮智能体会累积很长的消息历史。LangSmith 会记录每一轮、每个工具结果和每个模型响应,以便你查看完整对话。请按照追踪快速入门启用追踪。
我们还建议你设置 LangSmith Engine,它会监控你的追踪、检测问题并提出修复建议。
文本提示词
文本提示词就是字符串——非常适合不需要保留对话历史的简单生成任务。
python
response = model.invoke("Write a haiku about spring")1
在以下情况使用文本提示词:
- 你有一个单一的、独立的请求
- 你不需要对话历史
- 你希望代码复杂度最低
消息提示词
或者,你可以通过提供一个消息对象列表,向模型传入一个消息列表。
python
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)1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
在以下情况使用消息提示词:
- 管理多轮对话
- 处理多模态内容(图像、音频、文件)
- 包含系统指令
字典格式
你也可以直接以 OpenAI 聊天补全格式指定消息。
python
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)1
2
3
4
5
6
2
3
4
5
6
消息类型
系统消息 - 告诉模型应如何表现,并为交互提供上下文 *
•人类消息 - 表示用户输入以及与模型的交互 *
•AI 消息 - 由模型生成的响应,包括文本内容、工具调用和元数据 *
•系统消息
SystemMessage 表示一组初始指令,用于引导模型的行为。你可以使用系统消息来设定语气、定义模型的角色,并确立响应的准则。
python
system_msg = SystemMessage("You are a helpful coding assistant.")
messages = [
system_msg,
HumanMessage("How do I create a REST API?")
]
response = model.invoke(messages)1
2
3
4
5
6
7
2
3
4
5
6
7
python
from langchain.messages import SystemMessage, HumanMessage
system_msg = SystemMessage("""
You are a senior Python developer with expertise in web frameworks.
Always provide code examples and explain your reasoning.
Be concise but thorough in your explanations.
""")
messages = [
system_msg,
HumanMessage("How do I create a REST API?")
]
response = model.invoke(messages)1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
人类消息
HumanMessage 表示用户输入和交互。它们可以包含文本、图像、音频、文件,以及任意数量的其他多模态内容。
文本内容
python
response = model.invoke([
HumanMessage("What is machine learning?")
])1
2
3
2
3
python
# Using a string is a shortcut for a single HumanMessage
response = model.invoke("What is machine learning?")1
2
2
消息元数据
python
human_msg = HumanMessage(
content="Hello!",
name="alice", # Optional: identify different users
id="msg_123", # Optional: unique identifier for tracing
)1
2
3
4
5
2
3
4
5
NOTE
name 字段的行为因服务商而异——有些用它来标识用户,另一些则忽略它。要确认这一点,请参阅模型服务商的参考文档。
AI 消息
AIMessage 表示一次模型调用的输出。它们可以包含多模态数据、工具调用,以及你之后可以访问的服务商特有元数据。
python
response = model.invoke("Explain AI")
print(type(response)) # <class 'langchain.messages.AIMessage'>1
2
2
调用模型时,模型会返回 AIMessage 对象,其中包含响应中所有相关的元数据。
各服务商对各种消息类型的权重/上下文化处理方式不同,这意味着有时手动创建一个新的 AIMessage 对象,并像它来自模型一样插入到消息历史中会很有帮助。
python
from langchain.messages import AIMessage, SystemMessage, HumanMessage
# Create an AI message manually (e.g., for conversation history)
ai_msg = AIMessage("I'd be happy to help you with that question!")
# Add to conversation history
messages = [
SystemMessage("You are a helpful assistant"),
HumanMessage("Can you help me?"),
ai_msg, # Insert as if it came from the model
HumanMessage("Great! What's 2+2?")
]
response = model.invoke(messages)1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
属性
textstring
消息的文本内容。
contentstring | dict[]
消息的原始内容。
content_blocksContentBlock[]
消息标准化后的内容块。
tool_callsdict[] | None
模型发起的工具调用。
如果未调用任何工具则为空。
idstring
消息的唯一标识符(由 LangChain 自动生成,或在服务商响应中返回)
usage_metadatadict | None
消息的用量元数据,在可用时可能包含 token 计数。
response_metadataResponseMetadata | None
消息的响应元数据。
工具调用
当模型发起工具调用时,它们会包含在 AIMessage 中:
python
from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-5-nano")
def get_weather(location: str) -> str:
"""Get the weather at a location."""
...
model_with_tools = model.bind_tools([get_weather])
response = model_with_tools.invoke("What's the weather in Paris?")
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']}")1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
其他结构化数据(例如推理过程或引用)也可能出现在消息内容中。
Token 用量
AIMessage 可以在其 usage_metadata 字段中保存 token 计数和其他用量元数据:
python
from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-5-nano")
response = model.invoke("Hello!")
response.usage_metadata1
2
3
4
5
6
2
3
4
5
6
{'input_tokens': 8,
'output_tokens': 304,
'total_tokens': 312,
'input_token_details': {'audio': 0, 'cache_read': 0},
'output_token_details': {'audio': 0, 'reasoning': 256}}1
2
3
4
5
2
3
4
5
详情请参阅 UsageMetadata。
流式传输与分块
在流式传输期间,你会收到 AIMessageChunk 对象,它们可以合并为一个完整的消息对象:
python
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 + chunk1
2
3
4
5
6
2
3
4
5
6
工具消息
对于支持工具调用的模型,AI 消息可以包含工具调用。工具消息用于将单次工具执行的结果传回模型。
工具 可以直接生成 ToolMessage 对象。下面我们展示一个简单示例。更多内容请阅读工具指南。
python
from langchain.messages import AIMessage
from langchain.messages import ToolMessage
# After a model makes a tool call
# (Here, we demonstrate manually creating the messages for brevity)
ai_message = AIMessage(
content=[],
tool_calls=[{
"name": "get_weather",
"args": {"location": "San Francisco"},
"id": "call_123"
}]
)
# Execute tool and create result message
weather_result = "Sunny, 72°F"
tool_message = ToolMessage(
content=weather_result,
tool_call_id="call_123" # Must match the call ID
)
# Continue conversation
messages = [
HumanMessage("What's the weather in San Francisco?"),
ai_message, # Model's tool call
tool_message, # Tool execution result
]
response = model.invoke(messages) # Model processes the result1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
属性
contentstring必填
工具调用输出的字符串形式。
tool_call_idstring必填
该消息所响应的工具调用的 ID。必须与 AIMessage 中工具调用的 ID 匹配。
namestring必填
被调用的工具的名称。
artifactdict
不会发送给模型、但可以通过编程方式访问的附加数据。
NOTE
artifact 字段用于存储不会发送给模型、但可以通过编程方式访问的补充数据。这对于存储原始结果、调试信息或供下游处理的数据很有用,同时不会弄乱模型的上下文。
示例:使用 artifact 保存检索元数据
例如,一个检索工具可以从文档中检索一段内容供模型参考。消息 content 包含模型将引用的文本,而 artifact 可以包含文档标识符或应用程序可以使用的其他元数据(例如用于渲染页面)。见下面的示例:
python
from langchain.messages import ToolMessage
# Sent to model
message_content = "It was the best of times, it was the worst of times."
# Artifact available downstream
artifact = {"document_id": "doc_123", "page": 0}
tool_message = ToolMessage(
content=message_content,
tool_call_id="call_123",
name="search_books",
artifact=artifact,
)1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
消息内容
你可以把消息的内容理解为发送给模型的数据载荷。消息有一个 content 属性,其类型较为宽松,支持字符串以及由无类型对象(例如字典)组成的列表。这使得 LangChain 聊天模型可以直接支持服务商原生结构,例如多模态内容和其他数据。
此外,LangChain 为文本、推理、引用、多模态数据、服务端工具调用以及其他消息内容提供了专门的内容类型。参见下面的内容块。
LangChain 聊天模型在 content 属性中接受消息内容。
它可以包含以下任意一种:
- 一个字符串
- 以服务商原生格式表示的内容块列表
- LangChain 标准内容块的列表
下面是一个使用多模态输入的示例:
python
from langchain.messages import HumanMessage
# String content
human_message = HumanMessage("Hello, how are you?")
# Provider-native format (e.g., OpenAI)
human_message = 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
human_message = HumanMessage(content_blocks=[
{"type": "text", "text": "Hello, how are you?"},
{"type": "image", "url": "https://example.com/image.jpg"},
])1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TIP
在初始化消息时指定 content_blocks 仍会填充消息的 content,但为这样做提供了类型安全的接口。
标准内容块
LangChain 为消息内容提供了一种可跨服务商使用的标准表示形式。
消息对象实现了 content_blocks 属性,它会将 content 属性延迟解析为标准且类型安全的表示形式。例如,由 ChatAnthropic 或 ChatOpenAI 生成的消息会以各自服务商的格式包含 thinking 或 reasoning 块,但可以延迟解析为一致的 ReasoningContentBlock 表示形式:
python
from langchain.messages import AIMessage
message = AIMessage(
content=[
{"type": "thinking", "thinking": "...", "signature": "WaUjzkyp..."},
{"type": "text", "text": "..."},
],
response_metadata={"model_provider": "anthropic"}
)
message.content_blocks1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
[{'type': 'reasoning',
'reasoning': '...',
'extras': {'signature': 'WaUjzkyp...'}},
{'type': 'text', 'text': '...'}]1
2
3
4
2
3
4
请参阅集成指南,开始使用你所选择的 推理服务商。
NOTE
序列化标准内容
如果 LangChain 之外的应用程序需要访问标准内容块的 表示形式,你可以选择将内容块存储在消息内容中。
为此,你可以将 LC_OUTPUT_VERSION 环境变量设置为 v1。或者, 用 output_version="v1" 初始化任意聊天模型:
python
from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-5-nano", output_version="v1")1
2
3
2
3
多模态
**多模态(Multimodality)**指的是处理以不同形式出现的数据(如文本、音频、图像和视频)的能力。 LangChain 为这些数据提供了标准类型, 这些类型可以跨服务商使用。
聊天模型 可以接受多模态数据作为输入,并生成 多模态数据作为输出。下面我们展示一些包含多模态数据的输入消息的简短示例。
NOTE
额外的键可以放在内容块的顶层,也可以嵌套在 "extras": {"key": value} 中。
python
# 来自 URL
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这张图片的内容。"},
{"type": "image", "url": "https://example.com/path/to/image.jpg"},
]
}
# 来自 base64 数据
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这张图片的内容。"},
{
"type": "image",
"base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
"mime_type": "image/jpeg",
},
]
}
# 来自服务商托管的 File ID
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这张图片的内容。"},
{"type": "image", "file_id": "file-abc123"},
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
python
# 来自 URL
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这篇文档的内容。"},
{"type": "file", "url": "https://example.com/path/to/document.pdf"},
]
}
# 来自 base64 数据
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这篇文档的内容。"},
{
"type": "file",
"base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
"mime_type": "application/pdf",
},
]
}
# 来自服务商托管的 File ID
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这篇文档的内容。"},
{"type": "file", "file_id": "file-abc123"},
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
python
# 来自 base64 数据
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这段音频的内容。"},
{
"type": "audio",
"base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
"mime_type": "audio/wav",
},
]
}
# 来自服务商托管的 File ID
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这段音频的内容。"},
{"type": "audio", "file_id": "file-abc123"},
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
python
# 来自 base64 数据
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这段视频的内容。"},
{
"type": "video",
"base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
"mime_type": "video/mp4",
},
]
}
# 来自服务商托管的 File ID
message = {
"role": "user",
"content": [
{"type": "text", "text": "描述这段视频的内容。"},
{"type": "video", "file_id": "file-abc123"},
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WARNING
并非所有模型都支持所有文件类型。请查阅模型服务商的参考文档了解支持的格式和大小限制。
内容块参考
内容块(无论是在创建消息时,还是访问 content_blocks 属性时)都表示为一组带类型的字典。列表中的每一项都必须符合以下块类型之一:
核心
TextContentBlock
**用途:** 标准文本输出
string必填
始终为 `"text"`
string必填
文本内容
object[]
文本的注解列表
object
额外的服务商特定数据
**示例:**
```python
{
"type": "text",
"text": "Hello world",
"annotations": []
}
```
ReasoningContentBlock
**用途:** 模型推理步骤
string必填
始终为 `"reasoning"`
string
推理内容
object
额外的服务商特定数据
**示例:**
```python
{
"type": "reasoning",
"reasoning": "用户正在询问……",
"extras": {"signature": "abc123"},
}
```
多模态
ImageContentBlock
**用途:** 图片数据
string必填
Always `"image"`
string
指向图片位置的 URL。
string
Base64 编码的图片数据。
string
该内容块的唯一标识符(由服务商或 LangChain 生成)。
string
图片 [MIME 类型](https://www.iana.org/assignments/media-types/media-types.xhtml#image)(例如 `image/jpeg`、`image/png`)。base64 数据必填。
AudioContentBlock
**用途:** 音频数据
string必填
Always `"audio"`
string
指向音频位置的 URL。
string
Base64 编码的音频数据。
string
该内容块的唯一标识符(由服务商或 LangChain 生成)。
string
音频 [MIME 类型](https://www.iana.org/assignments/media-types/media-types.xhtml#audio)(例如 `audio/mpeg`、`audio/wav`)。base64 数据必填。
VideoContentBlock
**用途:** 视频数据
string必填
Always `"video"`
string
指向视频位置的 URL。
string
Base64 编码的视频数据。
string
该内容块的唯一标识符(由服务商或 LangChain 生成)。
string
视频 [MIME 类型](https://www.iana.org/assignments/media-types/media-types.xhtml#video)(例如 `video/mp4`、`video/webm`)。base64 数据必填。
FileContentBlock
**用途:** 通用文件(PDF 等)
string必填
Always `"file"`
string
指向文件位置的 URL。
string
Base64 编码的文件数据。
string
该内容块的唯一标识符(由服务商或 LangChain 生成)。
string
文件 [MIME 类型](https://www.iana.org/assignments/media-types/media-types.xhtml)(例如 `application/pdf`)。base64 数据必填。
PlainTextContentBlock
**用途:** 文档文本(`.txt`、`.md`)
string必填
Always `"text-plain"`
string
文本内容
string
文本的 [MIME 类型](https://www.iana.org/assignments/media-types/media-types.xhtml)(例如 `text/plain`、`text/markdown`)
工具调用
ToolCall
**用途:** 函数调用
string必填
Always `"tool_call"`
string必填
要调用的工具名称
object必填
传给工具的参数
string必填
该工具调用的唯一标识符
**Example:**
```python
{
"type": "tool_call",
"name": "search",
"args": {"query": "weather"},
"id": "call_123"
}
```
ToolCallChunk
**用途:** 流式输出的工具调用片段
string必填
Always `"tool_call_chunk"`
string
正在调用的工具名称
string
部分工具参数(可能是不完整的 JSON)
string
工具调用标识符
number | string
该片段在流中的位置
InvalidToolCall
**用途:** 格式错误的调用,用于捕获 JSON 解析错误。
string必填
Always `"invalid_tool_call"`
string
调用失败的工具名称
object
传给工具的参数
string
对出错原因的描述
服务端工具执行
ServerToolCall
**Purpose:** 在服务端执行的工具调用。
string必填
Always `"server_tool_call"`
string必填
与该工具调用关联的标识符。
string必填
要调用的工具名称。
string必填
部分工具参数(可能是不完整的 JSON)
ServerToolCallChunk
**用途:** 流式输出的服务端工具调用片段
string必填
Always `"server_tool_call_chunk"`
string
与该工具调用关联的标识符。
string
正在调用的工具名称
string
部分工具参数(可能是不完整的 JSON)
number | string
该片段在流中的位置
ServerToolResult
**用途:** 搜索结果
string必填
Always `"server_tool_result"`
string必填
对应的服务端工具调用的标识符。
string
与服务端工具结果关联的标识符。
string必填
服务端工具的执行状态。`"success"`(成功)或 `"error"`(错误)。
已执行工具的输出。
服务商特定块
NonStandardContentBlock
用途: 服务商专属的兜底机制
string必填
始终为 "non_standard"
object必填
服务商特定的数据结构
用法: 用于实验性或服务商独有的功能
更多服务商特定的内容类型可在各模型服务商的参考文档中找到。
TIP
可在 API 参考中查看权威的类型定义。
INFO
内容块在 LangChain v1 中作为消息的新属性被引入,用于在各服务商之间统一内容格式,同时保持与现有代码的向后兼容性。
内容块并不是 content 属性的替代品,而是一个新属性,可用于以标准化格式访问消息的内容。
序列化
你可以将消息序列化为普通对象以便存储,也可以反序列化回消息实例。这对于持久化对话历史和恢复会话非常有用。
python
from langchain.messages import HumanMessage
from langchain_core.load import dumpd, load
message = HumanMessage("What is the capital of France?")
# Serialize to a plain dict
serialized = dumpd(message)
# Deserialize back to a message object
restored = load(serialized)1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
WARNING
load() 会实例化 Python 对象,并可能在反序列化期间触发副作用。切勿对来自不可信或未经身份认证来源的数据调用 load()。
与聊天模型配合使用
聊天模型接受一组消息对象序列作为输入,并返回一个 AIMessage 作为输出。交互通常是无状态的,因此一个简单的对话循环就是不断用一份逐渐增长的消息列表调用模型。
请参阅以下指南了解更多信息:
- 用于持久化和管理对话历史的内置功能
- 管理上下文窗口的策略,包括裁剪与摘要消息