一、LangChain Prompt 模板概述
LangChain 提供了两种主要的提示模板类:
ChatPromptTemplate:用于构建多轮对话式提示(聊天格式)PromptTemplate:用于构建简单的文本提示模板
两者都支持变量填充和参数化处理,但适用场景不同。
二、ChatPromptTemplate
🔹 功能简介
- 专为聊天机器人设计,遵循通用聊天消息格式(如 OpenAI API 格式)。
- 每条消息必须包含
role和content字段。 - 支持多轮对话结构,适合复杂交互任务。
🔹 支持的角色类型(大小写敏感)
| 角色名 | 含义 |
|---|---|
"system" |
系统指令或角色设定(如"你是一名物理老师") |
"human" 或 "user" |
用户输入的消息 |
"ai" 或 "assistant" |
模型生成的回答 |
注意:
from_messages()方法会自动映射别名:
"user"→"human""assistant"→"ai"
🔹 常用角色含义
ai: LLM 返回的内容(模型输出)human: 人类用户的输入system: 系统级别的配置或角色定义
示例代码:创建聊天消息模板
from langchain_core.prompts import ChatPromptTemplate
# 创建一个多轮对话模板
template = ChatPromptTemplate.from_messages([
("system", "你是一名物理老师,你正在教学{state}。"),
("human", "你好!"),
("ai", "好的,请问有什么我可以帮您解答的吗?"),
("human", "帮我解释一下{per_input}量子力学。")
])
# 只保留用户提问部分的简化版本
template_1 = ChatPromptTemplate.from_messages([
("system", "你是一名物理老师,你正在教学{state}。"),
("human", "帮我解释一下{per_input}量子力学。")
])
格式化模板内容
messages1 = template.format_messages(state="大学生", per_input="大学二年级")
print(f"messages1类型: {type(messages1)}") # 输出: List[BaseMessage]
print(messages1)
print("*" * 100)
messages2 = template.format_prompt(state="大学生", per_input="大学二年级")
print(f"messages2类型: {type(messages2)}") # 输出: PromptValue
print(messages2)
关键区别:format_messages() vs format_prompt()
| 方法 | 返回值 | 用途 |
|---|---|---|
format_messages() |
List[BaseMessage](如 SystemMessage, HumanMessage) |
直接用于 LLM 输入 |
format_prompt() |
PromptValue 对象 |
可通过 .to_messages() 转为消息列表,也可 .to_string() 得到纯文本 |
三、PromptTemplate
🔹 功能简介
- 适用于单次文本提示,不涉及对话历史。
- 支持变量插值
{variable},可动态替换内容。 - 可显式声明变量,也可自动推断。
🔹 构造方式
方式1:显式声明变量
from langchain_core.prompts import PromptTemplate
prompt1 = PromptTemplate(
template="你是物理{system_name}老师。解释一下什么是量子计算,你好{name}?请用json格式输出",
input_variables=["system_name", "name"] # 显式声明需要的变量
)
message1 = prompt1.format(system_name="高级", name="张三")
print(message1)
方式2:自动推断变量(推荐)
prompt2 = PromptTemplate.from_template(
"你是物理{system_name}老师。解释一下什么是量子计算,你好{name}?请用json格式输出"
)
message2 = prompt2.format(system_name="高级", name="张三")
print(message2)
from_template()自动从{xxx}中识别变量名,无需手动指定input_variables。
🔹 示例汇总
示例1:带两个变量的提示
prompt = PromptTemplate(
template="你是物理{system_name}老师。解释一下什么是量子计算,你好{name}?请用json格式输出",
input_variables=["system_name", "name"]
)
message = prompt.format(system_name="高级", name="张三")
print(message)
示例2:无输入变量的提示
no_input_prompt = PromptTemplate(input_variables=[], template="给我讲个笑话。")
message = no_input_prompt.format()
print(message)
输出:
给我讲个笑话。
示例3:一个输入变量
one_input_prompt = PromptTemplate(
input_variables=["adjective"],
template="给我讲个{adjective}的笑话。"
)
message = one_input_prompt.format(adjective="把肚子笑痛")
print(message)
输出:
给我讲个把肚子笑痛的笑话。
示例4:多个输入变量
multiple_input_prompt = PromptTemplate(
input_variables=["adjective", "content"],
template="给我讲一个{adjective}的关于{content}的笑话。"
)
message = multiple_input_prompt.format(adjective="有趣的", content="足球")
print(message)
输出:
给我讲一个有趣的关于足球的笑话。
🔹 高级功能:partial() ------ 预填充变量
示例5:预填充部分变量
from langchain_core.prompts import PromptTemplate
import datetime
def get_datetime():
now = datetime.datetime.now()
return now.strftime("%m/%d/%Y, %H:%M:%S")
prompt = PromptTemplate(
template="告诉我{city}在{year}年{date}的平均气温",
input_variables=["city", "year", "date"]
)
# 完整调用
message1 = prompt.format(city="上海", year=2025, date=get_datetime())
print(message1)
print("*" * 100)
# 使用 partial 先填入部分变量
partial_prompt = prompt.partial(city="成都", date=get_datetime(), year="2025")
print(partial_prompt.format()) # 不需要再传参
print("\n" * 2)
print("原始变量:", prompt.input_variables) # ['city', 'date', 'year']
print("partial后变量:", partial_prompt.input_variables) # []
partial() 的优势:简化链式调用
chain = partial_prompt | llm
response = chain.invoke({}) # 空字典即可
解释:
prompt是"带空格的模板"partial_prompt是"填好空格的成品"- 使用
partial()后,后续不再需要重复传递相同参数
总结对比表
| 特性 | ChatPromptTemplate |
PromptTemplate |
|---|---|---|
| 用途 | 多轮对话、聊天场景 | 单次文本提示 |
| 必需字段 | role, content |
仅 template |
| 支持角色 | system / human / ai | 无角色概念 |
| 输出形式 | List[BaseMessage] 或 PromptValue |
str 或 PromptValue |
是否支持 partial() |
支持 | 支持 |
| 推荐使用场景 | 对话系统、客服机器人 | 简单问答、指令生成 |
最佳实践建议
-
选择合适的模板类型
- 若有对话历史 → 使用
ChatPromptTemplate - 若是简单文本指令 → 使用
PromptTemplate
- 若有对话历史 → 使用
-
优先使用
from_template()- 自动识别变量,减少出错
-
善用
partial()- 减少重复参数输入,提升代码复用性
-
注意角色大小写敏感
"Human"❌,必须是"human"✅
-
理解返回类型差异
format_messages()→ 消息对象(适合 LLM 输入)format_prompt()→ PromptValue(灵活转换)