按 关键参数、方法接口、适用边界、中文场景优化、核心方法使用 这 5 个角度,系统介绍 LangChain 的 PromptTemplate 官方类 。(LangChain 参考文档)
1. 先说结论:PromptTemplate 是什么
PromptTemplate 本质上是一个"字符串提示词模板类 "。你先定义一段带变量占位符的模板,例如 "请总结这段文本:{text}",再在运行时传入 text,它就会产出最终 prompt。官方文档明确说明它支持三种模板格式:f-string、mustache、jinja2;其中默认是 f-string,官方也明确更推荐 f-string,并对 jinja2 给出了安全警告。(LangChain 参考文档)
你给的源码里也能直接看到这一点:类注释写明它是 "Prompt template for a language model",template_format 默认值是 "f-string",并且在 from_template() 与类说明里重复提示:不要把不可信来源的 jinja2 模板直接拿来执行。
2. 关键参数
2.1 template
这是最核心的参数,表示模板正文。比如:
python
template = "你是一个客服助手,请回答:{question}"
官方定义里,template 就是 "The prompt template"。没有它,这个类就没有意义。(LangChain 参考文档)
2.2 template_format
可选值是:
f-stringmustachejinja2
默认是 f-string。官方文档与源码都写得很明确。对于一般业务提示词,优先用 f-string ;这是官方推荐路线,因为它简单、直观,而且安全面更可控。(LangChain 参考文档)
2.3 input_variables
表示调用模板时必须传入的变量名列表。
例如模板是:
python
"把 {topic} 用 {style} 风格解释"
那么 input_variables 通常就是:
python
["topic", "style"]
不过要注意一个官方实现细节:如果你使用 from_template(),这些变量通常可以从模板中自动推断 出来;不一定要手写。源码中 from_template() 就是先用 get_template_variables() 抽取变量名,再构造实例。(LangChain 参考文档)
2.4 partial_variables
这是非常实用的参数。它表示"先提前固化一部分变量 ",剩下的变量等调用时再传。官方文档举了类似例子:如果模板是 '{variable1} {variable2}',而 partial_variables={"variable1": "foo"},那最后就只需要再传 variable2。(LangChain 参考文档)
这在业务里特别适合固化这些内容:
- 系统角色
- 输出规范
- 固定品牌术语
- 长期不变的格式要求
| 概念 | 作用 |
|---|---|
input_variables |
调用 .format() 时必须提供的变量(调用时上传参数) |
partial_variables |
已经预先固定好的变量,不需要再传(固定) |
2.5 validate_template
这个参数控制是否校验模板。源码里写得很清楚:
- 若启用校验,
mustache不能做模板校验,会抛错 - 若启用校验,但没提供
input_variables,也会抛错 - 校验时会检查模板变量与输入变量是否一致。
所以它的意义是:在开发阶段提前发现变量拼错、漏传、模板不匹配的问题。生产里做复杂模板治理时很有价值。
3. 方法接口
官方和源码里,PromptTemplate 常用接口主要有以下几个。(LangChain 参考文档)
3.1 from_template():最推荐的构造方式
这是最常用、也是源码注释里明确推荐的方式。
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template(
"请把下面内容翻译成英文:{text}"
)
特点:
- 自动提取变量
- 写法最短
- 最符合官方示例习惯。(LangChain 参考文档)
3.2 format(**kwargs):把模板渲染成最终字符串
这是最核心的调用方法。
python
result = prompt.format(text="今天天气不错")
返回值是一个普通字符串。源码里可以直接看到它先合并 partial variables,再调用对应模板格式的 formatter 去渲染。
3.3 from_examples()
这个方法适合 few-shot prompt 场景:把多个示例拼成一个大 prompt,再接一个 suffix。官方文档说明得很明确,它的用途就是 "dynamically create a prompt from examples"。(LangChain 参考文档)
典型结构是:
prefix:任务说明examples:示例列表suffix:用户真实输入入口example_separator:示例之间的分隔符
3.4 from_file()
从文件加载模板。适合这些情况:
- prompt 很长,不想写在代码里
- 需要把 prompt 独立版本化
- 团队协作时让算法、产品、开发共同维护模板文件。(LangChain 参考文档)
3.5 __add__():模板拼接
源码中重载了 + 运算符,因此你可以把两个 PromptTemplate 拼起来,或者模板和字符串拼起来。
但有两个明显约束:
- 两边模板格式必须一致
partial_variables不能重复 partial 同一个变量,否则报错。
这个接口适合做"模块化 prompt 组装",例如:
- 角色设定模板
- 输出约束模板
- 用户任务模板
最后组合成一个完整 prompt。
4. 适用边界
这个部分最容易在项目里踩坑。
4.1 适合用 PromptTemplate 的场景
PromptTemplate 更适合 单段字符串 prompt,例如:
- 文本改写
- 摘要
- 分类
- 抽取
- 翻译
- 固定格式生成
因为它的输出就是一段字符串,跟普通 LLM 文本输入天然匹配。官方对它的描述也是 string template。(LangChain 参考文档)
4.2 不太适合的场景
如果你是做 多消息角色对话,比如要显式区分:
- system
- human
- ai
- message history
那么通常应优先考虑 ChatPromptTemplate,而不是把所有内容硬塞进一个字符串模板里。官方 prompts 体系本身就是把 string prompt 和 chat prompt 分开的。(LangChain 参考文档)
4.3 对模板引擎能力的边界
三种格式能力不同:
f-string:最简单,适合大多数业务场景mustache:更适合结构化填充jinja2:表达能力更强,但安全风险也更高。(LangChain 参考文档)
项目里我的建议很明确:
- 80% 业务场景:用
f-string - 需要复杂模板逻辑再考虑
mustache jinja2只在你完全可控模板来源时使用
4.4 校验边界
源码里写明:
mustache模板不能走validate_template=True的校验路径- 模板校验需要显式提供
input_variables。
也就是说,别指望所有模板格式都能"同等强度地自动校验"。
5. 中文场景优化
官方不会专门替你优化中文业务表达,但 PromptTemplate 很适合做中文 prompt 规范化。这里给你一些项目里很实用的优化思路。
5.1 把"角色、目标、约束、输出格式"拆成变量
中文业务 prompt 最大的问题往往不是不会写,而是"写成一大坨"。推荐拆成结构化变量:
python
template = """
你是{role}。
任务目标:
{task}
约束条件:
{constraints}
请按以下格式输出:
{output_format}
输入内容:
{text}
"""
这样做的好处是:
-
便于 A/B 测试不同约束
-
便于把中文业务规则沉淀成模板资产
-
更适合后续接 LangSmith 或配置中心做版本管理。
这与官方强调的"prompt template 用变量来复用结构化提示词"的思路是一致的。(LangChain 文档)
5.2 中文里尽量显式写输出格式
中文任务尤其容易出现"答非所问"或"格式漂移"。建议把输出格式直接作为模板的一部分固定下来,而不是只写"请简要回答"。
例如:
python
template = """
请阅读以下内容并输出 JSON:
{
"主题": "...",
"摘要": "...",
"风险点": ["...", "..."]
}
文本:
{text}
"""
这类"结构先行"的 prompt,稳定性通常比自然语言要求更高。官方文档也强调了 prompt variables 与 structured output 的配合价值。(LangChain 文档)
5.3 中文内容里避免变量名含糊
变量名最好不要叫:
inputcontentdata
这种太泛。
建议改成:
user_questionsource_textmeeting_notesrewrite_style
这样模板维护成本会低很多。虽然这是工程实践层建议,但和官方 input_variables 机制天然契合。(LangChain 参考文档)
5.4 固化中文系统约束到 partial_variables
比如你做中文客服、工单摘要、会议纪要,很适合把长期稳定的中文规范固化掉:
python
prompt = PromptTemplate.from_template(
template="""
你是一个{domain}助手。
请使用{language}输出。
遵循以下风格:
{style_guide}
用户问题:
{question}
""",
partial_variables={
"language": "简体中文",
"style_guide": "准确、简洁、避免口语化、结论先行"
}
)
这样业务方只需要传 domain 和 question,模板一致性会高很多。partial_variables 官方就是为这种"部分预填充"设计的。(LangChain 参考文档)
5.5 中文里优先用 f-string
因为中文业务 prompt 大多数只是"变量替换 + 固定格式",不需要复杂逻辑。此时 f-string:
- 可读性最好
- 团队最容易维护
- 安全上比
jinja2更稳。(LangChain 参考文档)
6. 核心方法的使用
下面给你几个最实用的官方类用法。
6.1 最基础:from_template() + format()
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template(
"请用中文总结以下内容:{text}"
)
final_prompt = prompt.format(text="LangChain is a framework for building LLM apps.")
print(final_prompt)
适合:
- 快速起步
- 单轮任务
- 文本摘要/改写/分类。(LangChain 参考文档)
6.2 使用 partial_variables
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template(
"""
你是一个{role}。
请使用{language}回答。
问题:
{question}
""",
partial_variables={
"language": "简体中文"
}
)
print(prompt.format(role="技术支持助手", question="如何重置密码?"))
适合:
- 固化语言
- 固化身份
- 固化输出规则。(LangChain 参考文档)
6.3 用 from_examples() 组织 few-shot
python
from langchain_core.prompts import PromptTemplate
examples = [
"输入:苹果\n输出:水果",
"输入:西红柿\n输出:蔬菜"
]
prompt = PromptTemplate.from_examples(
examples=examples,
prefix="请判断以下词语所属类别:",
suffix="输入:{word}\n输出:",
input_variables=["word"]
)
print(prompt.format(word="香蕉"))
实际生成的 prompt 是:
请判断以下词语所属类别:
输入:苹果
输出:水果
输入:西红柿
输出:蔬菜
输入:香蕉
输出:
然后模型补全:
水果
适合:
- 分类
- 抽取
- 风格仿写
- 少样本学习。
6.4 用 from_file() 管理长 prompt
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_file("prompt.txt")
print(prompt.format(question="请总结这份会议纪要"))
把 prompt 模板从"代码里"搬到"文件里",实现解耦和可管理。
适合:
- 长 prompt
- 版本管理
- 非研发同学共同维护提示词。(LangChain 参考文档)
6.5 与模型直接串起来用
官方文档在集成示例中展示了这种 Runnable 风格的串联:prompt | llm。例如集成页面里就展示了 PromptTemplate.from_template("What is the meaning of {thing}?") 再与模型链式调用。(LangChain 文档)
示意写法:
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template(
"请解释 {topic} 的含义"
)
chain = prompt | llm
result = chain.invoke({"topic": "向量数据库"})
这也是现在 LangChain 体系里很常见的用法:PromptTemplate 不是孤立对象,而是 Runnable 链上的一个节点 。(LangChain 文档)
7. 一个面向中文项目的推荐写法
这是我更建议在中文业务里采用的模板方式:
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template(
"""
你是一个专业的{domain}助手。
任务:
{task}
要求:
1. 使用简体中文
2. 先给结论,再给依据
3. 不要编造信息
4. 输出控制在{max_words}字以内
输入内容:
{text}
""",
partial_variables={
"max_words": "200"
}
)
print(
prompt.format(
domain="项目管理",
task="总结风险并给出应对建议",
text="本周项目延期主要由于接口联调和测试资源不足。"
)
)
这个写法的优点是:
-
模板结构稳定
-
中文可读性高
-
业务变量和固定规则清晰分离
-
后续做配置化很方便。
这正是
PromptTemplate在企业项目里最有价值的用法:把 prompt 从"写死字符串"升级成"可治理模板" 。(LangChain 参考文档)
8. 你可以这样理解它的选型位置
一个很实用的判断方法:
- 只是做"单段文本模板替换" →
PromptTemplate - 需要 system/human/ai 多消息组织 →
ChatPromptTemplate - 需要固定部分变量 →
PromptTemplate + partial_variables - 需要 few-shot →
from_examples() - 需要模板外置文件 →
from_file()。(LangChain 参考文档)