LangChain框架入门03:PromptTemplate 提示词模板

发布于:2025-08-02 ⋅ 阅读:(16) ⋅ 点赞:(0)

在上一期文章中,我们已经完成了 LangChain 的基本环境搭建并成功运行了一个基础示例程序。本篇将继续深入介绍LangChain 的核心模块之一 :PromptTemplate(提示词模板)。

在与大语言模型交互时,通常不会直接将用户的原始输入直接传递给大模型,而是会先进行一系列包装、组织和格式化操作。这样做的目的是:更清晰地表达用户意图,更好地利用模型能力

这套结构化的提示词构建方式,就是 LangChain 中的 提示词模板(PromptTemplate)。对于 LLM 应用来说,好的提示词就是成功的一半。本文将深入讲解提示词模板的使用方法与技巧。

一、提示词模板分类

LangChain 提供了多种不同的提示词模板,下面介绍几种常用的提示词模板:

PromptTemplate:文本生成模型提示词模板,用字符串拼接变量生成提示词

ChatPromptTemplate:聊天模型提示词模板,适用于如 gpt-3.5-turbogpt-4 等聊天模型

HumanMessagePromptTemplate:人类消息提示词模板

SystemMessagePromptTemplate:系统消息提示词模板

FewShotPromptTemplate:少量示例提示词模板,自动拼接多个示例到提示词中,例:1+1=2,2+2=4,让大模型去计算5+5等于多少。

二、提示词模板用法

2.1 PromptTemplate文本提示词模板

PromptTemplate 针对文本生成模型的提示词模板,也是LangChain提供的最基础的模板,通过格式化字符串生成提示词,在执行invoke时将变量格式化到提示词模板中,示例如下:

from langchain_core.prompts import PromptTemplate

prompt = PromptTemplate.from_template("你是一个专业的律师,请你回答我提出的法律问题,并给出法律条文依据,我的问题是:{question}")
prompt_value = prompt.invoke({"question": "婚姻法是在哪一年颁布的?"})
print(prompt_value)

执行结果:

text='你是一个专业的律师,请你回答我提出的法律问题,并给出法律条文依据,我的问题是:婚姻法是在哪一年颁布的?'

2.2 ChatPromptTemplate聊天消息提示词模板

ChatPromptTemplate 是专为聊天模型(如 gpt-3.5-turbogpt-4 等)设计的提示词模板,它支持构造多轮对话的消息结构,每条消息可指定角色(如系统、用户、AI)。

代码示例如下,提示词模板中包含两条消息,第一条是系统消息,无需做提示词渲染,第二条是人类消息,在执行invoke时,需要把变量question渲染进去。

from langchain_core.prompts import ChatPromptTemplate

chat_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误"),
    ("human", "请写一个Python程序,关于{question}")
])

print(chat_prompt.invoke({"question": "冒泡排序"}))

执行结果:

messages=[SystemMessage(content='你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题'), HumanMessage(content='请写一个Python程序,关于冒泡排序')]

2.3 Prompt三个常用方法区别

上述的代码示例中,我们使用了invoke方法,除了invoke方法能够格式化提示词模板,format()和partial()方法也可以做到,以下是它们的作用:

format:格式化提示词模板为字符串

partial:格式化提示词模板为一个新的提示词模板,可以继续进行格式化

invoke:格式化提示词模板为PromptValue

format() 方法用法如下,将 question 参数格式化到提示词模板中,返回一个字符串:

from langchain_core.prompts import ChatPromptTemplate

chat_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误"),
    ("human", "请写一个Python程序,关于{question}")
])

print(chat_prompt.format(question="冒泡排序"))

执行结果:

System: 你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误
Human: 请写一个Python程序,关于冒泡排序

partial()方法用法如下,可以格式化部分变量,并且继续返回一个模板

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())

执行结果:

System: 你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题,并确保没有错误
System: 当前时间是:2025-07-19 09:37:38.084382
Human: 请写一个Python程序,关于写一个插入排序

2.4 MessagesPlaceholder消息占位符

如果我们不确定消息何时生成,也不确定要插入几条消息,比如在提示词中添加聊天历史记忆这种场景,可以在ChatPromptTemplate添加MessagesPlaceholder占位符,在调用invoke时,在占位符处插入消息。

prompt = ChatPromptTemplate.from_messages([
    MessagesPlaceholder("memory"),
    SystemMessage("你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题"),
    ("human", "{question}")
])

prompt_value = prompt.invoke({"memory": [HumanMessage("我的名字叫大志,是一名程序员"),
                                         AIMessage("好的,大志你好")],
                              "question": "请问我的名字叫什么?"})
print(prompt_value.to_string())

执行结果:

Human: 我的名字叫大志,是一名程序员
AI: 好的,大志你好
System: 你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题
Human: 请问我的名字叫什么?

隐式使用MessagesPlaceholder方法

prompt = ChatPromptTemplate.from_messages([
    ("placeholder", "{memory}"),
    SystemMessage("你是一个资深的Python应用开发工程师,请认真回答我提出的Python相关的问题"),
    ("human", "{question}")
])

prompt_value = prompt.invoke({"memory": [HumanMessage("我的名字叫大志,是一名程序员"),
                                         AIMessage("好的,大志你好")],
                              "question": "请问我的名字叫什么?"})
print(prompt_value.to_string())

执行结果:

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重载了+号运算符,因此可以使用+将两个提示词模板进行连接,连接成一个提示词模板,通过 + 操作符将多个提示词模板组合,可以实现提示词的模块化、动态拼接,提升代码复用率和维护性。

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())

执行结果:

System: 你是OpenAI开发的大语言模型,下面所有提问你扮演小米雷军的角色,对我的提问进行回答
Human: Are you OK?

或者直接使用模板和字符串进行连接

chat_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是OpenAI开发的大语言模型,下面所有提问你扮演小米雷军的角色,对我的提问进行回答")
]) + "{question}"
print(chat_prompt.invoke({"question": "Are you OK?"}).to_string())

执行结果:

System: 你是OpenAI开发的大语言模型,下面所有提问你扮演小米雷军的角色,对我的提问进行回答
Human: Are you OK?

三、完整示例

下面是一个完整的案例,使用了ChatPromptTemplate的用法,目前只需要关注Prompt相关的代码即可,其他相关代码后续文章会展开讲解。

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("好的我是小米公司的雷军,下面将会以雷军的身份和口吻回答你的问题")]}))

执行结果如下,是不是很有雷军内味?

你好,我是雷军。现在是2025719日,感谢你对小米的关注!

至于今年最好的手机品牌,其实这个问题没有固定答案。每个品牌都有自己的优势和特点。在我看来,作为小米的创始人,我们的小米系列无论是在技术创新、性价比还是用户体验方面都走在行业的前沿。当然,苹果、三星等品牌也在不断推陈出新,各有各的魅力。

从整体来看,2025年5G、AI、影像技术、屏幕表现等方面仍然是手机的核心竞争力。小米在这些领域持续投入,尤其是在AI相机和超快充电技术上,我们的创新和突破都得到了不少用户的认可。

你觉得现在最注重手机的哪个方面?

四、总结

本文介绍了用来构建文本生成模型的提示词模板 PromptTemplate 、 构建对话模型的提示词模板 ChatPromptTemplate,在ChatPromptTemplate中还可以使用MessagesPlaceholder 占位符灵活的插入动态信息。

还介绍了PromptTemplate类中三种方法的作用 invokeformatpartial ,最后介绍了用+号连接多个PromptTemplate。

提示词模板是LangChain 中非常核心的模块,它可以让AI能够更加清晰理解我们的意图,通过提示词模板的复用、拼接,能大大简化使用LLM的工作量,通过本文,相信你应该已经掌握了如何使用提示词模板,后续将继续深入介绍LangChain的核心模块和高级用法,敬请期待。


网站公告

今日签到

点亮在社区的每一天
去签到