1.认识消息
大模型没有记忆,它的输出只和模型输入有关;很多大模型 API 服务也没有在服务端维护会话历史,是 "无状态"的;因此,如果应用需要"记住"会话历史,就需要在程序中维护消息列表

在 Langchain 中,Message(消息)是模型交互的基础单元
注意:
- 每一轮与大模型的对话,都由一条或多条 Message 构成
- 每个 Message 不仅包含文字内容(content) ,还携带描述上下文状态的元信息(metadata) ,用于保持对话的一致性和可追踪性。比如,模型在多轮交互中理解"谁在说话"、"说了什么"、"这条信息属于哪一轮对话"
LangChain 在 1.0 中提供了**跨模型统一的 Message 标准;**无论使用的是 OpenAI、Anthropic、Gemini 还是本地模型,这一标准都能保持一致的行为。好处:
- 兼容性强:不同模型的消息格式自动对齐。
- 可扩展性高:方便添加多模态内容或自定义字段。
- 可追踪性好:为 LangSmith 等调试工具提供一致的上下文数据结构。
1.1 消息的结构
LangChain 的消息(Message)对象包含三种字段:
- Role:消息所属的角色或类型,有四类角色: system、user、assistant,tool
- Content:消息的文本内容
- Metadata:(可选)元数据,存储额外信息。如:消息 ID、响应时间、token 消耗量、消息标签等
1.2 消息的类型
LangChain 的消息类型通过 role 区分,常用的有四种:
1、系统消息
系统提示词,用于在对话开始时为模型设定角色、行为准则和上下文背景
{"role": "system", "content": "你是个精通编程的软件架构师"}
2、用户消息
用户提示词,在多轮对话中,它**表示用户的一次输入;**可以包含简单的文本问题,也可以是复杂的多模态内容(如图片、音频、文档等)
{"role": "user", "content": "你好啊~"}
3、助手 (AI) 消息
模型的回复,包括生成的文本、工具调用、元数据等
{"role": "assistant", "content": "我也很高兴认识你"}
4、工具调用信息
工具调用结果匹配的消息类型。将此消息返回给模型,让模型基于这个结果继续生成回复。
{"role": "tool", "content": "今天天气很好", "tool_call_id":
"call_00_nUD2NC9QRN5Cg1GaoIkBJQ4s"}
1.3 消息的格式
LangChain支持两种消息格式
格式1:JSON格式
{"role": "system", "content": "你是个善解人意的助手",
"role": "user", "content": "你好啊~",
"role": "assistant", "content": "我也很高兴认识你",
"role": "tool", "content": "<工具输出>", "tool_call_id":
"call_00_nUD2NC9QRN5Cg1GaoIkBJQ4s"
}
格式2:对象格式
SystemMessage(content="你是个善解人意的助手")
HumanMessage(content="你好啊~")
AIMessage("我也很高兴认识你")
ToolMessage(
content="<工具输出>",
tool_call_id="call_00_nUD2NC9QRN5Cg1GaoIkBJQ4s" # 一定要和AI消息中的调用ID匹
配
)
小结:

1.4 消息对象字段说明
1.4.1 SystemMessage
content:消息内容,字段名可省略
SystemMessage("你好")
SystemMessage(content = "你好")
1.4.2 HumanMessage
content:消息内容,字段名可省略
metadata:元数据字段,不限数量,自定义
HumanMessage(
content="你好",
name="朱丽叶",
id="985"
)
name 和 id 都属于元数据字段,当消息类型相同,对消息进行区分。但不是所有模型都支持这一功 能,是否支持取决于模型供应商
1.4.3 AIMessage
content:消息内容,字段名可省略
response_metadata :AIMessage 特有属性,LLM的响应中附加元数据,根据不同模型会有不同,如 可能会包含本次token使用量等信息
tool_calls :AIMessage特有属性,表示**工具调用信息;**当LLM决定调用工具时,在 AIMessage 中就会包含这个属性,没有工具调用则为空,结构如下:
tool_calls=[
{
'name': 'get_weather', // 应调用的工具名
'args': {'city': '杭州'}, // 调用工具的参数
'id': 'call_00_gIXYOD1Q1OkEXmdDBqXR1578', // 工具调用的唯一标识ID
'type': 'tool_call'
},
{
'name': 'get_news',
'args': {},
'id': 'call_01_jD3phD5PEaIZf0mVLhKt0861',
'type': 'tool_call'
}
]
注意:tool_calls 属性是一个 ToolCall 列表,每个 ToolCall 是一个字典,其包含字段如上
usage_metadata:用量信息
1.4.4 ToolMessage
content:消息内容,字段名可省略
name:工具名称
tool_call_id :工具调用唯一 ID,ToolMessage 必须紧邻匹配的 AIMessage,和前者 tool_calls 中的 id 一致
ToolMessage(
content="<工具输出>",
name="get_weather"
tool_call_id="call_00_nUD2NC9QRN5Cg1GaoIkBJQ4s" # 一定要和AI消息中的调用ID匹配
)
1.5 消息属性:content、content_blocks
1.5.1 content
消息的content 可以理解为数据内容,它是弱类型,支持字符串和列表(列表元素通常为字典)
注意:
- 如果只是纯文本内容,直接传递字符串就可以
- 当 content 内容只有字符串时,可以省略参数名称
如果需要发送多模态内容,则需要 content 的字典列表形式
案例:

import base64
from langchain.chat_models import init_chat_model
from langchain.messages import SystemMessage, HumanMessage, AIMessage
from dotenv import load_dotenv
import os
# 将本地图片转换为base64编码的Data URI字符串
def encode_image(img_path, img_type='jpeg'):
"""
将一张本地图片转换成 Base64 编码的 Data URI 字符串,方便在文本中嵌入图片数据
"""
with open(img_path, "rb") as f:
return f"data:image/{img_type};base64,{base64.b64encode(f.read()).decode('utf-8')}"
# 1.加载环境变量
load_dotenv(override=True)
api_key=os.getenv("BAILIAN_API_KEY")
base_url=os.getenv("BAILIAN_API_BASE")
# 2.模型初始化
llm = init_chat_model(
model_provider="openai", # 模型提供商
model="deepseek-v4.1-flash", # 模型名称
api_key=api_key,
base_url=base_url
)
# 3.获取图像base64编码字符串
# 3.1 图像路径
img_path = "./Data/博客封面.jpg"
# 3.2 获取图像base64编码字符串
base64_image = encode_image(img_path, img_type='jpeg')
# 4.调用模型
response = llm.invoke([
HumanMessage(
content=[
{
'type': 'text',
'text': '这张图里有什么?'},
{
'type': 'image_url',
"image_url": base64_image,
}
]
)
])
print(response.content)

1.7.2 content_blocks
在 LangChain 1.2 版本中,新增了 content_blocks属性,可以将 content 解析为标准、类型安全的表示
-
数据结构 :它是一个
list[TypedDict] -
统一格式 :每个 block 都有一个
type字段,用于区分内容类型 -
支持类型 :包括
text(文本)、image(图片)、audio(音频)、video(视频)、tool_call(工具调用)以及reasoning(推理 / 思维链)
支持的字段类型详见: Messages - Docs by LangChain
① 输入格式化
对于复杂的对话(带图片或工具结果),建议使用 content_blocks 列表形式构建 HumanMessage 或 AIMessage
案例:
import base64
from langchain.chat_models import init_chat_model
from langchain.messages import SystemMessage, HumanMessage, AIMessage
from dotenv import load_dotenv
import os
# 将本地图片转换为base64编码的Data URI字符串
def encode_image(img_path, img_type='jpeg'):
"""
将一张本地图片转换成 Base64 编码的 Data URI 字符串,方便在文本中嵌入图片数据
"""
with open(img_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
# 1.加载环境变量
load_dotenv(override=True)
api_key=os.getenv("BAILIAN_API_KEY")
base_url=os.getenv("BAILIAN_API_BASE")
# 2.模型初始化
llm = init_chat_model(
model_provider="openai", # 模型提供商
model="deepseek-v4.1-flash", # 模型名称
api_key=api_key,
base_url=base_url
)
# 3.获取图像base64编码字符串
# 3.1 图像路径
img_path = "./Data/博客封面.jpg"
# 3.2 获取图像base64编码字符串
base64_image = encode_image(img_path, img_type='jpeg')
# 4.调用模型
response = llm.invoke([
HumanMessage(
content_blocks=[
{
'type': 'text',
'text': '这张图里有什么?'},
{
'type': 'image',
'base64': base64_image,
'mime_type': 'image/jpeg'
}
]
)
])
print(response.content)
② 输出格式化
content_blocks 提供了统一的输出格式 ,可以将不同格式的响应统一为标准格式

输出:

注意:content_blocks是 懒加载 的,即调用时才会解析
2. 提示词模板
使用 LangChain 提供 ChatPromptTemplate 类
案例:
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os
from rich import print as rprint
from langchain_core.prompts import ChatPromptTemplate
# 1.加载配置信息
load_dotenv(override=True) # 加载.env文件中的环境变量
api_key = os.getenv("DEEPSEEK_API_KEY") # 获取DEEPSEEK_API_KEY环境变量
base_url = os.getenv("DEEPSEEK_API_BASE") # 获取DEEPSEEK_API_BASE环境
# 2.初始化模型
llm = init_chat_model(
model_provider="openai", # 模型提供商
model="deepseek-flash", # 模型名称
api_key=api_key, # API Key
base_url=base_url, # API Base URL
)
# 3.调用模型
prompt_template = ChatPromptTemplate([
("system", "你是一个AI开发工程师. 你的名字是 {name}."),
("human", "{user_input}")
])
#调用format()方法,返回字符串
prompt = prompt_template.invoke({"name":"小谷AI", "user_input":"你能帮我做什么?"})
rprint(prompt)
结果如下:

2.1 ChatPromptTemplate 的使用
ChatPromptTemplate 是创建消息列表的提示模板,支持 System / Human / AI 等不同角色的消息模板

2.1.1 两种实例化方式
ChatPromptTemplate 可以通过初始化方法 或 from_messages 方法来实例化提示词模板,实例化 时需要传入 messages 参数。常见类型是:tuple构成的列表,参数类型(role : str,content : str )
方式1(推荐):调用 from_messages()
该方法允许传入一个由元组(Tuple)构成的列表,列表中的每一个元组都代表一条具有特定角色的消息
案例:
# 导入相关依赖
from langchain_core.prompts import ChatPromptTemplate
# 定义聊天提示词模版
chat_template = ChatPromptTemplate.from_messages(
[
("system", "你是一个有帮助的AI机器人,你的名字是{name}。"),
("human", "你好,最近怎么样?"),
("ai", "我很好,谢谢!"),
("human", "{user_input}"),
]
)
# 格式化聊天提示词模版中的变量
prompt = chat_template.invoke({"name":"小明", "user_input":"你叫什么名字?"})
# 打印格式化后的聊天提示词模版内容
print(prompt)
注意:from_messages()的底层,也是调用的类的 __init( )__方法
方式2:使用实例初始化方法
from langchain_core.prompts import ChatPromptTemplate
#参数类型这里使用的是tuple构成的list
prompt_template = ChatPromptTemplate([
# 字符串 role + 字符串 content
("system", "你是一个AI开发工程师. 你的名字是 {name}."),
("human", "你能开发哪些AI应用?"),
("ai", "我能开发很多AI应用, 比如聊天机器人, 图像识别, 自然语言处理等."),
("human", "{user_input}")
])
#调用invoke()方法,返回ChatPromptValue
prompt = prompt_template.invoke({"name":"小谷AI", "user_input":"你能帮我做什么?"})
print(prompt)
2.1.2 模型调用的三种方式
方式1:使用 invoke()
返回 ChatPromptValue

方式2:使用 format()
返回字符串
注意:format()要使用关键字传参
方式3:使用 format_messages()
返回消息列表

2.1.3 案例
from urllib import response
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os
from rich import print as rprint
from langchain_core.prompts import ChatPromptTemplate
# 1.加载配置信息
load_dotenv(override=True) # 加载.env文件中的环境变量
api_key = os.getenv("BAILIAN_API_KEY") # 获取BAILIAN_API_KEY环境变量
base_url = os.getenv("BAILIAN_API_BASE") # 获取BAILIAN_API_BASE环境
# 2.初始化模型
llm = init_chat_model(
model_provider="openai", # 模型提供商
model="deepseek-v4.1-flash", # 模型名称
api_key=api_key, # API Key
base_url=base_url, # API Base URL
)
# 3.调用模型
# 3.1 定义聊天提示词模版
chat_template = ChatPromptTemplate([
("system", "你是一个精通Python编程与AI的机器人,你的名字是{name}"),
("human", "{user_input}")
])
prompt = chat_template.format(name="小彤AI", user_input="你能帮我做什么?")
# 3.2 调用模型
response = llm.invoke("什么是面向对象编程?")
print(response.content)
2.1.4 更丰富的初始化参数类型
不管使用实例初始化方法,还是使用 from_messages(),参数类型都是列表类型 ,列表中的元素可以是多种类型
源码如下:


结论:参数是列表类型,列表的元素可以是字符串、字典、字符串构成的元组、消息类型、提示词模板类型、消息提示词模板类型等
类型1:str 列表类型
列表参数格式是 str 类型(不推荐),因为默认角色都是 human
#1.导入相关依赖
from langchain_core.prompts import ChatPromptTemplate
# 2.定义聊天提示词模版
chat_template = ChatPromptTemplate.from_messages(
[
"Hello, {name}!" # 等价于 ("human", "Hello, {name}!")
]
)
# 3. 使用invoke执行
messages = chat_template.invoke({"name":"小谷AI"})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
类型2:tuple列表类型
列表参数格式是元组类型
#1.导入相关依赖
from langchain_core.prompts import ChatPromptTemplate
# 2.定义聊天提示词模版
chat_template = ChatPromptTemplate.from_messages(
[
("human", "Hello, {name}!")
]
)
# 3. 使用invoke执行
messages = chat_template.invoke({"name":"小谷AI"})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
类型3:dict列表类型
列表参数格式是 dict 类型
#1.导入相关依赖
from langchain_core.prompts import ChatPromptTemplate
# 2.定义聊天提示词模版
chat_template = ChatPromptTemplate.from_messages(
[
{"role":"system", "content":"你是一个精通Python编程与AI的机器人,你的名字是{name}"},
{"role":"human", "content":"{user_input}"}
]
)
# 3. 使用invoke执行
messages = chat_template.invoke({"name":"小谷AI", "user_input":"什么是面向对象编程?"})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
类型4:Message列表类型
#1.导入相关依赖
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage
# 2.定义聊天提示词模版
chat_template = ChatPromptTemplate.from_messages(
[
SystemMessage(content="你是一个精通Python编程与AI的机器人,你的名字是{name}"),
HumanMessage(content="{user_input}")
]
)
# 3. 使用invoke执行
messages = chat_template.invoke({"name":"小谷AI", "user_input":"什么是面向对象编程?"})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
注意:在 Message 中不能有占位符
类型5:MessagePromptTemplate列表类型
LangChain提供不同类型的MessagePromptTemplate。
最常用的是 SystemMessagePromptTemplate、 HumanMessagePromptTemplate 和 AIMessagePromptTemplate ,分别创建系统消息、人工消息和AI消息
HumanMessagePromptTemplate,专用于生成用户消息(HumanMessage) 的模板类
- 模板化:支持使用变量占位符,可以在运行时填充具体值
- 格式化:能够将模板与输入变量结合生成最终的聊天消息
- 输出类型:生成 HumanMessage 对象(content + role="human")
- 设计目的:简化用户输入消息的模板化构造,避免重复定义角色
SystemMessagePromptTemplate、AIMessagePromptTemplate 类似
案例:
#1.导入相关依赖
from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage
# 2.定义聊天提示词模版
# 2.1 定义系统消息提示词模版
system_message_prompt = SystemMessagePromptTemplate.from_template("你是一个精通Python编程与AI的机器人,你的名字是{name}")
# 2.2 定义用户消息提示词模版
human_message_prompt = HumanMessagePromptTemplate.from_template("{user_input}")
# 2.3 组合模板
chat_template = ChatPromptTemplate.from_messages(
[
system_message_prompt,
human_message_prompt
]
)
# 3. 使用invoke执行
messages = chat_template.invoke({"name":"小谷AI", "user_input":"什么是面向对象编程?"})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
类型6:BaseChatPromptTemplate列表类型
使用 BaseChatPromptTemplate,可以理解为 ChatPromptTemplate 里嵌套了 ChatPromptTemplate
#1.导入相关依赖
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage
# 2.定义聊天提示词模版
# 2.1 定义系统消息提示词模版
system_message_prompt = ChatPromptTemplate([
("system", "你是一个精通Python编程与AI的机器人,你的名字是{name}")
])
# 2.2 定义用户消息提示词模版
human_message_prompt = ChatPromptTemplate([
("human", "{user_input}")
])
# 2.3 组合模板
chat_template = ChatPromptTemplate.from_messages(
[
system_message_prompt,
human_message_prompt
]
)
# 3. 使用invoke执行
messages = chat_template.invoke({"name":"小谷AI", "user_input":"什么是面向对象编程?"})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
2.2 高级特性
2.2.1 部分变量预填充:partial()
预填充某些固定不变的变量,创建模板的变体
使用场景:
- 某些变量在所有调用中都相同
- 需要为不同用户/场景创建定制模板
案例如下:
#1.导入相关依赖
from os import name
from langchain_core.prompts import ChatPromptTemplate
# 2.定义聊天提示词模版
chat_template = ChatPromptTemplate.from_messages(
[
{"role":"system", "content":"你是一个精通Python编程与AI的机器人,你的名字是{name}"},
{"role":"human", "content":"{user_input}"}
]
)
chat_template_partial = chat_template.partial(name="小谷AI")
# 3. 使用invoke执行
messages = chat_template_partial.invoke({"user_input":"什么是面向对象编程?"})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
2.2.2 消息占位符
当不确定消息提示模板使用什么角色,或者希望在格式化过程中插入消息列表时,需要使用消息占位符,负责在特定位置添加消息列表
使用场景:多轮对话系统存储历史消息以及Agent的中间步骤处理此功能非常有用
使用方式:
方式1:JSON形式
#1.导入相关依赖
from os import name
from langchain_core.prompts import ChatPromptTemplate
# 2.定义聊天提示词模版
chat_template = ChatPromptTemplate.from_messages(
[
{"role":"system", "content":"你是一个精通Python编程与AI的机器人,你的名字是{name}"},
{"role":"human", "content":"{conversation}"}
]
)
chat_template_partial = chat_template.partial(name="小谷AI")
# 3. 使用invoke执行
messages = chat_template_partial.invoke({
"conversation":
[
("human", "你好,最近怎么样?"),
("ai", "我很好,谢谢!"),
("human", "你能帮我做什么?")
]
})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
方式2:MessagesPlaceholder 实例
#1.导入相关依赖
from os import name
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 2.定义聊天提示词模版
chat_template = ChatPromptTemplate.from_messages(
[
{"role":"system", "content":"你是一个精通Python编程与AI的机器人,你的名字是{name}"},
MessagesPlaceholder("conversation")
]
)
chat_template_partial = chat_template.partial(name="小谷AI")
# 3. 使用invoke执行
messages = chat_template_partial.invoke({
"conversation":
[
HumanMessage(content="你好,最近怎么样?")
]
})
# 4.打印格式化后的聊天提示词模版内容
print(messages)
2.2.3 可复用模板库
在实际项目中,推荐创建模板库:即创建一个 template.py 文件专门用来声明相关模板
举例如下:
from langchain_core.prompts import ChatPromptTemplate
class PromptTemplateLibrary:
"""
可复用的提示词模板库
"""
translator = ChatPromptTemplate([
("system", "你是专业翻译,精通{source_lang}和{target_lang}")
("user", f"请翻译以下文本:{user_input}")
])
code_master = ChatPromptTemplate([
("system", "你是一位编程专家,精通编程语言:{code_language}")
("user", f"请回答以下问题:{user_input}")
])
...
然后在其他文件中使用:
from template import PromptTemplateLibrary
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os
from rich import print as rprint
# 1.加载配置信息
load_dotenv(override=True) # 加载.env文件中的环境变量
api_key = os.getenv("BAILIAN_API_KEY") # 获取BAILIAN_API_KEY环境变量
base_url = os.getenv("BAILIAN_API_BASE") # 获取BAILIAN_API_BASE环境
# 2.初始化模型
llm = init_chat_model(
model_provider="openai", # 模型提供商
model="deepseek-v4.1-flash", # 模型名称
api_key=api_key, # API Key
base_url=base_url, # API Base URL
)
# 3.调用提示词模板
prompt = PromptTemplateLibrary.code_master.invoke({
"code_language": "python",
"user_input": "什么是面向对象编程?"
})
# 4.调用模型
response = llm.invoke(prompt)
print(response.content)
2.2.4 模板组合
将多个模板片段组合成复杂的提示词
方式1:字符串组合
# 定义可复用部分
role_part = "你是一个{domain}专家。"
style_part = "回答风格:{style}。"
constraint_part = "限制:{constraint}。"
# 组合
full_system = role_part + style_part + constraint_part
template = ChatPromptTemplate.from_messages([
("system", full_system),
("user", "{question}")
])
方式2:使用 + 运算符
template1 = ChatPromptTemplate.from_messages([
("system", "你是助手")
])
template2 = ChatPromptTemplate.from_messages([
("user", "{input}")
])
# 组合(LangChain 1.0 支持)
combined = template1 + template2