langchain 消息和消息模版
简单固定场景:如果消息内容不变(比如固定系统指令、单轮固定问题),用或手动写字典都可以,前者是 LangChain 封装好的类,代码更规范;动态变化场景:如果消息内容需要根据变量替换(比如多轮对话、动态参数),必须用,效率更高、更易维护。本质上,Message类是「静态结果」,类是「动态生成工具」—— 前者是后者最终生成的产物之一。方式角色本质等效的字典格式核心特点系统角色硬编码内容,无动态变量人
langchain中有SystemMessagePromptTemplate
和 HumanMessagePromptTemplate
还有
HumanMessage, SystemMessage, AIMessage,对于刚学习langchain的人可能有点蒙,他们有什么区别呢。本文给大家讲清楚。
SystemMessagePromptTemplate
和 HumanMessagePromptTemplate
是 LangChain 中专门用于构建「带角色的聊天消息模板」的工具类,核心作用是给消息内容绑定明确的「角色属性」,让聊天模型(如 GPT、豆包等)能区分消息的来源和意图,从而更准确地生成回应。
1. 先理解「角色」的重要性
现代聊天模型(如 GPT-3.5/4、豆包、Claude 等)的核心交互逻辑是「基于角色的对话」—— 模型会根据消息的「角色」来判断这是谁说的话,以及该如何回应。常见角色有:
- 系统角色(system):通常是给模型的「全局指令」,定义模型的行为模式(比如 “你是一个专业的程序员”“回答要简洁”)。
- 人类角色(human):用户输入的内容(比如 “解释一下什么是函数”)。
- AI 角色(ai):模型之前的回应(用于多轮对话时让模型 “记住” 历史)。
模型会优先遵循「系统角色」的指令,并针对「人类角色」的内容进行回应。
2. 两个类的具体含义和作用
SystemMessagePromptTemplate
- 含义:用于创建「系统角色消息的模板」。
- 作用:定义模型的 “身份”“行为准则” 或 “任务背景”,是给模型的 “全局设定”。
比如:SystemMessagePromptTemplate.from_template("你是一个数学老师,回答要通俗易懂")
生成的系统消息会告诉模型:“你要以数学老师的身份回应,语言要简单”。
HumanMessagePromptTemplate
- 含义:用于创建「人类角色消息的模板」。
- 作用:定义用户输入的内容(可以是静态文本,也可以包含动态变量)。
比如:HumanMessagePromptTemplate.from_template("请解释什么是{concept}")
生成的人类消息会作为用户的提问,其中{concept}
可以动态替换为具体内容(如 “微积分”“变量”)。
3. 为什么需要用「Template」类?
直接手动写死消息内容不行吗?比如:
messages = [
{"role": "system", "content": "你是一个数学老师"},
{"role": "human", "content": "解释什么是函数"}
]
当然可以,但「Template 类」的优势在于支持动态生成内容:
当消息内容需要根据变量变化时(比如多轮对话中的历史记录、用户输入的动态参数),用 from_template()
可以轻松嵌入变量(如 {history}
{question}
),后续通过 format()
方法动态填充,比字符串拼接更简洁、更不易出错。
4. 在代码中的实际作用
chat_prompt = ChatPromptTemplate(
messages=[
# 系统消息模板:定义模型行为(结合历史回答问题)
SystemMessagePromptTemplate.from_template("你是一个耐心的助手,结合历史对话回答问题。"),
# 人类消息模板:内容是动态生成的(历史+当前问题)
HumanMessagePromptTemplate.from_template("{human_content}")
],
input_variables=["human_content"] # 动态填充人类消息的内容
)
这里的两个 Template 类的作用是:
- 用
SystemMessagePromptTemplate
固定模型的行为模式(“结合历史回答”); - 用
HumanMessagePromptTemplate
接收动态生成的用户内容(包含历史对话 + 当前问题); - 最终通过
ChatPromptTemplate
组合成完整的「角色消息列表」,传给模型后,模型能清晰区分 “系统指令” 和 “用户输入”,从而更准确地回应。 SystemMessagePromptTemplate
→ 定义模型的 “行为准则”(系统角色消息模板);HumanMessagePromptTemplate
→ 定义用户的输入内容(人类角色消息模板);- 两者的核心价值是:给消息绑定角色 + 支持动态内容生成,让聊天模型能理解对话上下文和指令,生成更符合预期的回应。
如果系统指令和用户问题都是固定的,用 SystemMessage
或字典完全一样,代码都很简洁:
# 方式1:用Message类
from langchain_core.messages import SystemMessage, HumanMessage
messages = [
SystemMessage(content="只回答'是'或'否'"),
HumanMessage(content="今天下雨了吗?")
]
# 方式2:用字典(和方式1完全等效)
messages = [
{"role": "system", "content": "只回答'是'或'否'"},
{"role": "human", "content": "今天下雨了吗?"}
]
场景 2:内容需要动态变化(必须用「MessagePromptTemplate」类)
如果用户问题里有动态变量(比如要查询不同城市的天气),用「Template」类才能轻松替换变量:
from langchain.prompts import SystemMessagePromptTemplate, HumanMessagePromptTemplate, ChatPromptTemplate
# 1. 定义带变量的模板({city} 是动态变量)
system_template = SystemMessagePromptTemplate.from_template("只回答'是'或'否',针对{city}的天气")
human_template = HumanMessagePromptTemplate.from_template("{city}今天下雨了吗?")
# 2. 组合成聊天模板
chat_prompt = ChatPromptTemplate(
messages=[system_template, human_template],
input_variables=["city"] # 声明需要传入的变量
)
# 3. 动态填充变量(比如查询"北京"或"上海")
final_messages1 = chat_prompt.format_prompt(city="北京").to_messages()
final_messages2 = chat_prompt.format_prompt(city="上海").to_messages()
# 最终生成的消息(和手动写字典等效,但动态变量已替换)
# final_messages1 会是:
# [{"role": "system", "content": "只回答'是'或'否',针对北京的天气"}, {"role": "human", "content": "北京今天下雨了吗?"}]
总结:什么时候用哪种?
- 简单固定场景:如果消息内容不变(比如固定系统指令、单轮固定问题),用
SystemMessage
/HumanMessage
或手动写字典都可以,前者是 LangChain 封装好的类,代码更规范; - 动态变化场景:如果消息内容需要根据变量替换(比如多轮对话、动态参数),必须用
SystemMessagePromptTemplate
/HumanMessagePromptTemplate
+ChatPromptTemplate
,效率更高、更易维护。
本质上,Message
类是「静态结果」,MessagePromptTemplate
类是「动态生成工具」—— 前者是后者最终生成的产物之一。
方式 | 角色 | 本质等效的字典格式 | 核心特点 |
---|---|---|---|
SystemMessage(content="...") |
系统角色 | {"role": "system", "content": "..."} |
硬编码内容,无动态变量 |
HumanMessage(content="...") |
人类角色 | {"role": "human", "content": "..."} |
硬编码内容,无动态变量 |
手动写字典 | 任意角色 | {"role": "...", "content": "..."} |
硬编码内容,无动态变量 |
更多推荐
所有评论(0)