LangChain - 提示模板
目录+
为什么需要提示模板
直接给模型写死一段提示词有两个问题:① 提示词固定,无法根据不同输入灵活变化;② 复制粘贴拼字符串,难以复用和维护。
提示模板(Prompt Template) 就是带 {变量} 占位符的提示字符串。它接收原始用户输入,把变量填进去,生成一段「准备好发给模型」的提示词。好处是:清晰可读、可复用、易维护、参数化生成。
四种常见模板
| 模板 | 适用场景 |
|---|---|
PromptTemplate | 单条字符串提示,最基础 |
ChatPromptTemplate | 多角色对话提示(system / human / ai),聊天模型首选 |
FewShotPromptTemplate | 给几个示例「教」模型怎么答 |
部分填充 partial | 先固定一部分变量,其余后续再填(不是独立模板,是通用能力) |
一、PromptTemplate
最基础的字符串模板:一段含 {变量} 的文本,填充后得到完整提示词。
1. 两种用法对比
模板本身只负责「把变量填进字符串」。填好之后既可以手动调用模型,也可以用 LCEL 管道串起来。
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from models import DEEPSEEK_URL, DEEPSEEK_V4_PRO
load_dotenv()
llm = ChatOpenAI(
api_key=os.getenv("MY_DEEPSEEK_API_KEY"),
base_url=DEEPSEEK_URL,
model=DEEPSEEK_V4_PRO,
)
# 创建模板:{text} 是占位符
template = PromptTemplate.from_template("你是一名专业的程序员,请描述这个概念:{text}")
# 用法 A:LCEL 管道(推荐)—— 模板 | 模型 | 输出解析器
chain = template | llm | StrOutputParser()
print(chain.invoke({"text": "递归算法"}))
# 用法 B:手动 format —— 先把模板渲染成普通字符串,再自己喂给模型
text_prompt = template.format(text="递归算法") # 得到一段填好变量的字符串
print(llm.invoke(text_prompt).content)
format()的作用就是把模板里的{变量}替换成真实值,返回一个普通字符串——常用来打印检查最终发给模型的内容。
2. 多变量
模板里可以有多个占位符,format 时按关键字一一传入即可。
prompt = PromptTemplate.from_template("请把下面的内容翻译成 {language}:\n\n{text}")
print(prompt.format(language="英文", text="你好世界"))
3. 部分填充 partial
先固定一部分变量(比如角色设定),之后只需传剩下的,适合复用同一套设定。
prompt = PromptTemplate.from_template("{role},请回答:{question}")
# 先预填 role,得到一个新的模板
assistant = prompt.partial(role="你是一位专业的直播运营助手")
# 之后只需传 question
print(assistant.format(question="如何提高观众停留时长?"))
4. 关键点速记
| 概念 | 说明 |
|---|---|
template | 含 {变量} 占位符的字符串 |
input_variables | 变量名列表(用 from_template 创建时可自动推断,无需手写) |
.format(**kwargs) | 填充变量,返回普通字符串 |
.partial(**kwargs) | 预填部分变量,返回新模板 |
prompt | llm | parser | LCEL 管道:模板 → 模型 → 输出解析器 |
PromptTemplate 处理的是单条字符串提示;如果是多角色的对话模型,用 ChatPromptTemplate 更合适。
二、ChatPromptTemplate
聊天模型的输入不是一段字符串,而是一个带角色的消息列表(system / human / ai)。ChatPromptTemplate 就是用来生成这种消息列表的模板。
1. 三种创建方式
import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from models import DEEPSEEK_URL, DEEPSEEK_V4_PRO
llm = ChatOpenAI(
api_key=os.getenv("MY_DEEPSEEK_API_KEY"),
base_url=DEEPSEEK_URL,
model=DEEPSEEK_V4_PRO,
)
# 方式 1:多条消息,带 system 角色(最常用)
template = ChatPromptTemplate.from_messages([
("system", "你是一名专业的翻译助手"),
("human", "请将以下内容翻译成英文:{text}"),
])
# 方式 2:单条 human 消息
# template = ChatPromptTemplate.from_messages([("human", "请将以下内容翻译成英文:{text}")])
# 方式 3:from_template,等价于只有一条 human 消息
# template = ChatPromptTemplate.from_template("请将以下内容翻译成英文:{text}")
message = template.invoke({"text": "我是程序员"}) # 渲染成消息列表
aimessage = llm.invoke(message) # 调用模型,返回 AI 回复
print(aimessage.content)
2. 消息列表的写法
from_messages 接收一个列表,列表里每个元素是一个 (角色, 内容) 元组,每个元组就是一条消息:
[("system", "你是一名专业的程序员"), ("human", "{input}")]
- 第一个元素:角色,固定字符串
"system"/"human"/"ai"("user"、"assistant"也兼容)。 - 第二个元素:消息内容,可以包含
{变量名}占位符。
也可以用
SystemMessagePromptTemplate/HumanMessagePromptTemplate/AIMessagePromptTemplate这类对象来写每条消息,效果和上面的元组写法一样,元组写法更简洁。
三、FewShotPromptTemplate
少样本提示:先给模型几个示例(examples),让它学会输出的格式和风格,再回答真正的问题。适合「靠规则说不清、给几个例子一看就懂」的任务。
1. 组成
| 参数 | 作用 |
|---|---|
examples | 示例列表,每个示例是一个 dict |
example_prompt | 单个示例怎么渲染(一个 PromptTemplate) |
prefix | 示例前的引导语(角色、任务说明) |
suffix | 示例后的正式提问,含待填变量 |
input_variables | suffix 中的变量名列表 |
最终提示词 = prefix + 所有示例渲染结果 + suffix,拼成一整段发给模型。
2. 基本用法
import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from models import DEEPSEEK_URL, DEEPSEEK_V4_PRO
llm = ChatOpenAI(
api_key=os.getenv("MY_DEEPSEEK_API_KEY"),
base_url=DEEPSEEK_URL,
model=DEEPSEEK_V4_PRO,
)
# 示例:每个都是一个 dict
examples = [
{"input": "2+2", "output": "4", "description": "加法运算"},
{"input": "5-2", "output": "3", "description": "减法运算"},
]
# 单个示例如何渲染(占位符要和 examples 的键对应)
example_prompt = PromptTemplate.from_template(
"算式:{input} 值:{output} 类型:{description}"
)
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="你是一个数学专家,能准确说出算式的类型。",
suffix="现在给你算式:{input},值:{output},告诉我类型:",
input_variables=["input", "output"],
)
# 先打印出来检查最终提示词长什么样
print(prompt.format(input="2*5", output="10"))
# 再发给模型
print(llm.invoke(prompt.format(input="2*5", output="10")).content) # 乘法运算
3. 要点
prompt.format(...)可以把拼好的完整提示词打印出来,方便检查。- 示例 dict 的键,必须和
example_prompt模板里的占位符一致。 - 多角色对话场景用
FewShotChatMessagePromptTemplate:把示例渲染成消息列表,配合ChatPromptTemplate使用。