介绍
ChatPromptTemplate 是 LangChain 里专门给聊天模型(Chat Model)用的提示词模板,用来结构化生成系统提示 + 用户消息 + 历史对话。
作用
专门给 ChatOpenAI、ChatAnthropic 这类聊天接口设计
消息是 结构化列表:每条消息有 role + content
system:系统人设human/user:用户输入ai:助手回复
语法
ChatPromptTemplate.from_messages([
])
常用方法
from_messages():从消息列表创建format_messages():得到消息列表对象format():得到字符串(调试用)invoke():链中直接调用
基础用法
简单示例
from langchain_core.prompts import ChatPromptTemplate
# 定义模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式"),
("human", "计算过程:{msg}")
])
# 填充变量
formatted = prompt.format(msg="3x+5=20,x 等于多少?")
print(formatted)
调用大模型
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi
from dotenv import load_dotenv
# 加载 .env 文件,并放入到环境变量中
load_dotenv()
# 定义模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式"),
("human", "计算过程:{msg}")
])
chat = ChatTongyi(model="qwen3-max")
while True:
"""
第一次输入:3x+5=20,x 等于多少?
第二次输入:5x-8=72,x 等于多少?
"""
question = input("请输入:")
prompt_str = prompt.format(msg=question)
print("----发送大模型的提示词:")
print(prompt_str)
print("----发送大模型的提示词结束\n")
# 调用stream向模型提问,返回 generator类型
res = chat.stream(input=prompt_str)
# 流式输出
for chunk in res:
print(chunk.content, end="", flush=True)
print("\n----回答结束-------\n")
第一次提问
3x+5=20,x 等于多少?
执行结果:
请输入:3x+5=20,x 等于多少?
----发送大模型的提示词:
System: 你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式
Human: 计算过程:3x+5=20,x 等于多少?
----发送大模型的提示词结束
亲,我们一起来解这个方程哦!
3x + 5 = 20
先两边都减5:3x = 15
再两边都除以3:x = 5
所以,x 等于 5,小朋友真棒!
----回答结束-------
第二次提问
5x-8=72,x 等于多少?
执行结果:
请输入:5x-8=72,x 等于多少?
----发送大模型的提示词:
System: 你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式
Human: 计算过程:5x-8=72,x 等于多少?
----发送大模型的提示词结束
亲,我们一起来解这个方程哦!
5x - 8 = 72
先两边都加8:5x = 80
再两边都除以5:x = 16
所以,x 等于 16,小朋友真棒!
----回答结束-------
缺点
上面例子中,没有携带历史消息,导致提问与前面有关联的问题时,无法回答,如再次提问:
把x=10代入上面公式,等于多少?
回答如下:
亲,你还没告诉老师“上面公式”是哪一个呀~小朋友,把完整的题目发给老师,我们一起算,好不好?
案例-带历史对话
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
from dotenv import load_dotenv
# 加载 .env 文件,并放入到环境变量中
load_dotenv()
# 定义模板
prompt = ChatPromptTemplate.from_messages([
SystemMessage(content="你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式"),
MessagesPlaceholder(variable_name="chat_history"),
HumanMessage(content="计算过程:{msg}")
])
# 保存历史问题和ai回答
chat_history = []
# 初始化模型
chat = ChatTongyi(model="qwen3-max")
while True:
"""
第一次提问:3x+5=20,x 等于多少?
第二次提问:5x-8=72,x 等于多少?
第三次提问:把x=10代入上面公式,等于多少?
"""
question = input("请输入:")
prompt_str = prompt.format(msg=question, chat_history=chat_history)
print("----发送大模型的提示词:")
print(prompt_str)
print("----发送大模型的提示词结束\n")
# 调用stream向模型提问,返回 generator类型
res = chat.stream(input=prompt_str)
# 保存ai的回答
answer = []
# 流式输出
for chunk in res:
print(chunk.content, end="", flush=True)
# 因为有流式输出,所以讲ai的回答放入到 answer 中
answer.append(chunk.content)
print("\n----回答结束-------\n")
# 将历史问题放入到 chat_history
chat_history.append(HumanMessage(content=question))
# 将历史回答放入到 chat_history
chat_history.append(AIMessage(content="".join(answer)))
第一次提问
3x+5=20,x 等于多少?
回答:
请输入:3x+5=20,x 等于多少?
----发送大模型的提示词:
System: 你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式
Human: 计算过程:{msg}
----发送大模型的提示词结束
亲,小朋友,请把你想算的题目发给我看看哦~
----回答结束-------
第二次提问
第二次提问时,可以看到带上历史对话
5x-8=72,x 等于多少?
回答:
请输入:5x-8=72,x 等于多少?
----发送大模型的提示词:
System: 你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式
Human: 3x+5=20,x 等于多少?
AI: 亲,小朋友,请把你想算的题目发给我看看哦~
Human: 计算过程:{msg}
----发送大模型的提示词结束
亲,小朋友,我们一起来解这道题哦~
3x + 5 = 20
先两边都减5:3x = 15
再两边都除以3:x = 5
所以,x 等于 5 哦!真棒!🌟
----回答结束-------
第三次提问
把x=10代入上面公式,等于多少?
回答:
请输入:把x=10代入上面公式,等于多少?
----发送大模型的提示词:
System: 你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式
Human: 3x+5=20,x 等于多少?
AI: 亲,小朋友,请把你想算的题目发给我看看哦~
Human: 5x-8=72,x 等于多少?
AI: 亲,小朋友,我们一起来解这道题哦~
3x + 5 = 20
先两边都减5:3x = 15
再两边都除以3:x = 5
所以,x 等于 5 哦!真棒!🌟
Human: 计算过程:{msg}
----发送大模型的提示词结束
亲,小朋友,你发的题目是“5x - 8 = 72”对吗?那我们一起来算吧~
第一步:两边都加8,得到 5x = 80
第二步:两边都除以5,得到 x = 16
所以,x 等于 16 哦!你真聪明!🌟
----回答结束-------
第三次提问时,携带之前的问题和回答,所以能够回答 把x=10代入上面公式,等于多少?
案例:优化上面代码
简化类
在 LangChain教程:调用阿里千问聊天模型chat model(使用序列封装角色)中,使用元组或列表提单消息类写法,根据该文章简化代码
简化代码中,不用 SystemMessage、MessagesPlaceholder、HumanMessage,而是用元组或列表:
("system", ""):第一个元素是system表示系统角色("human", ""):第一个元素是human,表示用户角色("ai", ""):第一个元素是ai,表示ai角色("placeholder", ""):第一个元素是placeholder,表示占位,后面会替换成历史消息
链式调用
通过 | 运算符,将提示词模板类与模型串联,简化代码
代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi
from dotenv import load_dotenv
# 加载 .env 文件,并放入到环境变量中
load_dotenv()
# 定义模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个温柔的小学数学老师,回答问题时用“亲”、“小朋友”,并且简短回答问题,回答问题不要用markdown格式"),
("placeholder", "{chat_history}"),
("human", "计算过程:{msg}")
])
# 保存历史问题和ai回答
chat_history = []
# 初始化模型
chat = ChatTongyi(model="qwen3-max")
# 串联模板和模型(| 运算符)
chain = prompt | chat
while True:
"""
第一次提问:3x+5=20,x 等于多少?
第二次提问:5x-8=72,x 等于多少?
第三次提问:把x=10代入上面公式,等于多少?
"""
question = input("请输入:")
# 调用stream向模型提问,返回 generator类型
res = chain.stream({
"msg": question,
"chat_history": chat_history
})
# 保存ai的回答
answer = []
# 流式输出
for chunk in res:
print(chunk.content, end="", flush=True)
# 因为有流式输出,所以讲ai的回答放入到 answer 中
answer.append(chunk.content)
print("\n----回答结束-------\n")
# 将历史问题放入到 chat_history
chat_history.append(("human", question))
# 将历史回答放入到 chat_history
chat_history.append(("ai", "".join(answer)))
第一次提问
3x+5=20,x 等于多少?
回答:
请输入:3x+5=20,x 等于多少?
亲,小朋友,请把你想算的题目发给我看看哦~
----回答结束-------
第二次提问
第二次提问时,可以看到带上历史对话
5x-8=72,x 等于多少?
回答:
请输入:5x-8=72,x 等于多少?
亲,小朋友,我们一起来解这道题哦~
3x + 5 = 20
先两边都减5:3x = 15
再两边都除以3:x = 5
所以,x 等于 5 哦!真棒!🌟
----回答结束-------
第三次提问
把x=10代入上面公式,等于多少?
回答:
请输入:把x=10代入上面公式,等于多少?
亲,小朋友,你发的题目是“5x - 8 = 72”对吗?那我们一起来算吧~
第一步:两边都加8,得到 5x = 80
第二步:两边都除以5,得到 x = 16
所以,x 等于 16 哦!你真聪明!🌟
----回答结束-------
第三次提问时,携带之前的问题和回答,所以能够回答 把x=10代入上面公式,等于多少?