在上一期文章中,我们已经完成了 LangChain 的基本环境搭建并成功运行了一个基础示例程序。本篇将继续深入介绍LangChain 的核心模块之一 :PromptTemplate(提示词模板)。
在与大语言模型交互时,通常不会直接将用户的原始输入直接传递给大模型,而是会先进行一系列包装、组织和格式化操作。这样做的目的是:更清晰地表达用户意图,更好地利用模型能力。
这套结构化的提示词构建方式,就是 LangChain 中的 提示词模板(PromptTemplate) 。对于 LLM 应用来说,好的提示词就是成功的一半。本文将深入讲解提示词模板的使用方法与技巧。
一、提示词模板分类
LangChain 提供了多种不同的提示词模板,下面介绍几种常用的提示词模板:
PromptTemplate
:文本生成模型提示词模板,用字符串拼接变量生成提示词
ChatPromptTemplate
:聊天模型提示词模板,适用于如 gpt-3.5-turbo
、gpt-4
等聊天模型
HumanMessagePromptTemplate
:人类消息提示词模板
SystemMessagePromptTemplate
:系统消息提示词模板
FewShotPromptTemplate
:少量示例提示词模板,自动拼接多个示例到提示词中,例:1+1=2,2+2=4,让大模型去计算5+5等于多少。
二、提示词模板用法
2.1 PromptTemplate文本提示词模板
PromptTemplate
针对文本生成模型的提示词模板,也是LangChain提供的最基础的模板,通过格式化字符串生成提示词,在执行invoke时将变量格式化到提示词模板中,示例如下:
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template("你是一个专业的律师,请你回答我提出的法律问题,并给出法律条文依据,我的问题是:{question}")
prompt_value = prompt.invoke({"question": "婚姻法是在哪一年颁布的?"})
print(prompt_value)
执行结果:
python
text='你是一个专业的律师,请你回答我提出的法律问题,并给出法律条文依据,我的问题是:婚姻法是在哪一年颁布的?'
2.2 ChatPromptTemplate聊天消息提示词模板
ChatPromptTemplate
是专为聊天模型(如 gpt-3.5-turbo
、gpt-4
等)设计的提示词模板,它支持构造多轮对话的消息结构,每条消息可指定角色(如系统、用户、AI)。
代码示例如下,提示词模板中包含两条消息,第一条是系统消息,无需做提示词渲染,第二条是人类消息,在执行invoke时,需要把变量question渲染进去。
python
from langchain_core.prompts import ChatPromptTemplate
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误"),
("human", "请写一个Python程序,关于{question}")
])
print(chat_prompt.invoke({"question": "冒泡排序"}))
执行结果:
python
messages=[SystemMessage(content='你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题'), HumanMessage(content='请写一个Python程序,关于冒泡排序')]
2.3 Prompt三个常用方法区别
上述的代码示例中,我们使用了invoke方法,除了invoke方法能够格式化提示词模板,format()和partial()方法也可以做到,以下是它们的作用:
format
:格式化提示词模板为字符串
partial
:格式化提示词模板为一个新的提示词模板,可以继续进行格式化
invoke
:格式化提示词模板为PromptValue
format() 方法用法如下,将 question
参数格式化到提示词模板中,返回一个字符串:
python
from langchain_core.prompts import ChatPromptTemplate
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误"),
("human", "请写一个Python程序,关于{question}")
])
print(chat_prompt.format(question="冒泡排序"))
执行结果:
python
System: 你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误
Human: 请写一个Python程序,关于冒泡排序
partial()方法用法如下,可以格式化部分变量,并且继续返回一个模板
python
from datetime import datetime
from langchain_core.prompts import ChatPromptTemplate
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误"),
("system", "当前时间是:{currentTime}"),
("human", "请写一个Python程序,关于{question}")
]).partial(currentTime=datetime.now())
print(chat_prompt.invoke({"question": "写一个插入排序"}).to_string())
执行结果:
python
System: 你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误
System: 当前时间是:2025-07-19 09:37:38.084382
Human: 请写一个Python程序,关于写一个插入排序
2.4 MessagesPlaceholder消息占位符
如果我们不确定消息何时生成,也不确定要插入几条消息 ,比如在提示词中添加聊天历史记忆这种场景,可以在ChatPromptTemplate添加MessagesPlaceholder
占位符,在调用invoke时,在占位符处插入消息。
python
prompt = ChatPromptTemplate.from_messages([
MessagesPlaceholder("memory"),
SystemMessage("你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题"),
("human", "{question}")
])
prompt_value = prompt.invoke({"memory": [HumanMessage("我的名字叫大志,是一名程序员"),
AIMessage("好的,大志你好")],
"question": "请问我的名字叫什么?"})
print(prompt_value.to_string())
执行结果:
python
Human: 我的名字叫大志,是一名程序员
AI: 好的,大志你好
System: 你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题
Human: 请问我的名字叫什么?
隐式使用MessagesPlaceholder方法
python
prompt = ChatPromptTemplate.from_messages([
("placeholder", "{memory}"),
SystemMessage("你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题"),
("human", "{question}")
])
prompt_value = prompt.invoke({"memory": [HumanMessage("我的名字叫大志,是一名程序员"),
AIMessage("好的,大志你好")],
"question": "请问我的名字叫什么?"})
print(prompt_value.to_string())
执行结果:
python
Human: 我的名字叫大志,是一名程序员
AI: 好的,大志你好
System: 你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题
Human: 请问我的名字叫什么?
2.5 PromptValue提示值
PromptValue
是提示词模板 .invoke()
执行后返回的中间对象,支持将提示词转换为字符串或消息列表传递给 LLM。主要包含两个方法:
to_string
:将提示词转换为字符串
to_messages
:将提示词转换为消息列表。普通 PromptValue 调用该方法会将整个字符串包装成一条人类消息;ChatPromptValue是PromptValue的子类,ChatPromptValue 会返回完整的消息列表(系统、人类、AI消息 等)
PromptValue这个中间类的存在的作用在于:适配不同LLM的输入要求,因为聊天模型需要输入消息,文本生成模型则需要输入字符串,PromptValue能够自由转换为字符串或消息,以适配不同 LLM 的输入要求,并且保持接口一致、逻辑清晰、易于维护。
2.6 加号连接提示词模板
PromptTemplate重载了+
号运算符,因此可以使用+将两个提示词模板进行连接,连接成一个提示词模板,通过 +
操作符将多个提示词模板组合,可以实现提示词的模块化、动态拼接,提升代码复用率和维护性。
python
from langchain_core.prompts import ChatPromptTemplate
first_chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是OpenAI开发的大语言模型,下面所有提问你扮演小米雷军的角色,对我的提问进行回答")
])
second_chat_prompt = ChatPromptTemplate.from_messages([
("human", "{question}")
])
all_chat_prompt = first_chat_prompt + second_chat_prompt
print(all_chat_prompt.invoke({"question": "Are you OK?"}).to_string())
执行结果:
python
System: 你是OpenAI开发的大语言模型,下面所有提问你扮演小米雷军的角色,对我的提问进行回答
Human: Are you OK?
或者直接使用模板和字符串进行连接
python
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是OpenAI开发的大语言模型,下面所有提问你扮演小米雷军的角色,对我的提问进行回答")
]) + "{question}"
print(chat_prompt.invoke({"question": "Are you OK?"}).to_string())
执行结果:
python
System: 你是OpenAI开发的大语言模型,下面所有提问你扮演小米雷军的角色,对我的提问进行回答
Human: Are you OK?
三、完整示例
下面是一个完整的案例,使用了ChatPromptTemplate的用法,目前只需要关注Prompt相关的代码即可,其他相关代码后续文章会展开讲解。
python
from datetime import datetime
import dotenv
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI
# 读取env配置
dotenv.load_dotenv()
# 1.构建提示词
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是OpenAI开发的大语言模型,对我的提问进行回答"),
MessagesPlaceholder("memory"),
("human", "{question}"),
("human", "{currentTime}")
]).partial(currentTime=datetime.now())
# 2.构建GPT-3.5模型
llm = ChatOpenAI(model="gpt-3.5-turbo")
# 3.创建输出解析器
parser = StrOutputParser()
# 4.执行链
chain = chat_prompt | llm | parser
print(chain.invoke({"question": "你是谁,现在是哪一年,请问今年最好的手机品牌是什么?",
"memory": [HumanMessage("你是小米公司的雷军,你扮演雷军的身份和我对话"),
AIMessage("好的我是小米公司的雷军,下面将会以雷军的身份和口吻回答你的问题")]}))
执行结果如下,是不是很有雷军内味?
python
你好,我是雷军。现在是2025年7月19日,感谢你对小米的关注!
至于今年最好的手机品牌,其实这个问题没有固定答案。每个品牌都有自己的优势和特点。在我看来,作为小米的创始人,我们的小米系列无论是在技术创新、性价比还是用户体验方面都走在行业的前沿。当然,苹果、三星等品牌也在不断推陈出新,各有各的魅力。
从整体来看,2025年5G、AI、影像技术、屏幕表现等方面仍然是手机的核心竞争力。小米在这些领域持续投入,尤其是在AI相机和超快充电技术上,我们的创新和突破都得到了不少用户的认可。
你觉得现在最注重手机的哪个方面?
四、总结
本文介绍了用来构建文本生成模型的提示词模板 PromptTemplate
、 构建对话模型的提示词模板 ChatPromptTemplate
,在ChatPromptTemplate中还可以使用MessagesPlaceholder
占位符灵活的插入动态信息。
还介绍了PromptTemplate类中三种方法的作用 invoke
、format
、partial
,最后介绍了用+号连接多个PromptTemplate。
提示词模板是LangChain 中非常核心的模块,它可以让AI能够更加清晰理解我们的意图,通过提示词模板的复用、拼接,能大大简化使用LLM的工作量,通过本文,相信你应该已经掌握了如何使用提示词模板,后续将继续深入介绍LangChain的核心模块和高级用法,敬请期待。