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": "..."} 硬编码内容,无动态变量

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐