本文深入讲解 LangChain 中的 Prompt 模板系统,探索变量绑定、FewShot 示例构建、格式化策略等关键能力,帮助你构建灵活可控的提示内容生成逻辑。
一、PromptTemplate 是什么?
PromptTemplate
是 LangChain 中用于生成语言模型 输入文本 的标准化模板系统。
它的主要作用是:
- 使用占位变量构造提示内容
- 将动态上下文注入至 prompt 中
- 实现不同输入场景下的统一模板管理与复用
二、基础使用:变量绑定与格式化
PromptTemplate 的核心能力是"模板 + 输入变量 = 生成文本"。
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template("你是谁?我是{identity}。")
print(prompt.format(identity="LangChain"))
# 输出:你是谁?我是LangChain。
也可使用 input_variables
与 template
分开定义:
python
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate(
input_variables=["agent", "topic"],
template="请 {agent} 用一句话总结关于 {topic} 的内容。"
)
print(prompt.format(agent="LLM", topic="LangChain"))
# 输出:请 LLM 用一句话总结关于 LangChain 的内容。
三、进阶功能:FewShotPromptTemplate(示例注入式提示构造)
FewShotPromptTemplate
是 LangChain 中用于构造 带有示例上下文(Few-Shot Examples) 的提示模板系统。它的作用是:在正式提示之前,插入一组"训练样例",让模型更好地理解输入模式,提高生成准确性,常用于分类、问答、意图识别等任务。
✅ 工作机制
它的生成逻辑等价于三段拼接:
css
[样例1模板渲染]
[样例2模板渲染]
...
+
[Suffix(真正的Prompt部分)]
从而构造出如下结构:
输入:狗
输出:动物
输入:苹果
输出:水果
输入:西瓜
输出:
✅ 示例代码解析
python
from langchain.prompts import FewShotPromptTemplate, PromptTemplate
# 定义训练样例
examples = [
{"input": "狗", "output": "动物"},
{"input": "苹果", "output": "水果"},
]
# 定义样例模板:每个样例如何格式化为字符串
example_prompt = PromptTemplate.from_template("输入:{input}\n输出:{output}")
# 构造 FewShotPromptTemplate
prompt = FewShotPromptTemplate(
examples=examples, # 样例数据列表
example_prompt=example_prompt, # 样例模板
suffix="输入:{input}\n输出:", # 正式 Prompt(将在样例之后接上)
input_variables=["input"] # 最终用户提供的变量(传给 suffix)
)
# 渲染 Prompt
print(prompt.format(input="西瓜"))
🧠 核心概念解析
参数名称 | 含义说明 |
---|---|
examples |
提供的示例数据,通常是结构化字典列表 |
example_prompt |
每个样例的渲染模板(可嵌套 PromptTemplate) |
suffix |
实际用户输入部分的 Prompt |
prefix (可选) |
在所有样例之前插入前缀 |
example_separator |
样例之间的分隔符,默认为两个换行 |
📦 FewShotPromptTemplate 的使用场景
- 文本分类:根据几个示例推断目标类别
- 函数映射:输入一个值,模型输出其对应映射
- 意图识别:提供几个句子 → 推断其意图标签
- 少样本 QA/RAG:插入上下文片段作为参考
🧩 进阶用法:动态样例选择器(Selector)
除了手动提供 examples
外,你还可以动态选择最相关的样例:
python
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.prompts import FewShotPromptTemplate, PromptTemplate
# 1. 定义本地 embedding 模型
embedding_model = HuggingFaceEmbeddings(model_name="BAAI/bge-large-zh-v1.5")
# 2. 定义示例
examples = [
{"input": "狗", "output": "汪汪叫"},
{"input": "苹果", "output": "水果"},
{"input": "猫", "output": "喵喵叫"},
{"input": "钢琴", "output": "乐器"},
]
# 3. 构建向量相似度选择器 selector
selector = SemanticSimilarityExampleSelector.from_examples(
examples=examples,
embeddings=embedding_model,
vectorstore_cls=FAISS,
k=2
)
# 4. 构建 Prompt 模板
example_prompt = PromptTemplate.from_template("输入:{input}\n输出:{output}")
prompt = FewShotPromptTemplate(
example_selector=selector,
example_prompt=example_prompt,
suffix="输入:{input}\n输出:",
input_variables=["input"]
)
# 5. 格式化并查看实际 Prompt
print(prompt.format(input="小提琴"))

这可以实现 基于输入动态检索最相似的示例,大大提升上下文精度。
四、进阶控制:自定义格式逻辑(替代 format_func
)
在 LangChain 新版本中,PromptTemplate
已不再支持传入 format_func
参数。但我们依然可以通过封装、继承等方式实现自定义的 Prompt 格式控制逻辑,特别适用于构建动态 Prompt、多语言切换、对话历史注入等复杂场景。
✅ 1. 封装类实现"自定义格式器"
你可以为 PromptTemplate
写一个包装器,对格式化结果进行二次加工:
python
from langchain.prompts import PromptTemplate
class UppercasePrompt:
def __init__(self, template: PromptTemplate):
self.template = template
def format(self, **kwargs) -> str:
base = self.template.format(**kwargs)
return base.upper()
# 示例用法
template = PromptTemplate.from_template("你好,{name}!")
prompt = UppercasePrompt(template)
print(prompt.format(name="tom"))
# 输出:你好,TOM!
✅ 2. 拼接上下文:封装对话历史逻辑
适用于多轮对话中,把历史问答作为 Prompt 的一部分注入:
python
from langchain_core.prompts import PromptTemplate
class ChatHistoryPrompt:
def __init__(self, prompt_template: PromptTemplate):
self.prompt = prompt_template
def format(self, user_input: str, history: list[dict]) -> str:
history_text = "\n".join(f"用户:{h['q']}\n助手:{h['a']}" for h in history)
full_input = f"{history_text}\n用户:{user_input}\n助手:"
return self.prompt.format(input=full_input)
# 用法
prompt_template = PromptTemplate.from_template("{input}")
history_prompt = ChatHistoryPrompt(prompt_template)
chat_history = [
{"q": "今天天气好吗?", "a": "很晴朗。"},
{"q": "那我适合出门吗?", "a": "当然适合。"}
]
print(history_prompt.format(user_input="那我还要带伞吗?", history=chat_history))
📤 输出:

✅ 3. 动态模板切换(根据输入结构)
适用于根据不同任务切换 Prompt 模板结构:
python
from langchain_core.prompts import PromptTemplate
class TaskPrompt:
def __init__(self):
self.qa = PromptTemplate.from_template("问:{question}\n答:")
self.summary = PromptTemplate.from_template("请总结以下内容:{text}")
def format(self, task_type: str, **kwargs) -> str:
if task_type == "qa":
return self.qa.format(**kwargs)
elif task_type == "summary":
return self.summary.format(**kwargs)
else:
raise ValueError("未知的任务类型")
# 使用示例
prompt = TaskPrompt()
print(prompt.format(task_type="qa", question="LangChain 是什么?"))
# 输出:问:LangChain 是什么?
print(prompt.format(task_type="summary",
text="PromptTemplate系统本质上是一个可编程的模板引擎,"
"允许用户在模板注入逻辑中引入复杂行为(如动态示例切换、多语言支持、上下文拼接等)。"))
# 输出:请总结以下内容:PromptTemplate系统本质上是一个可编程的模板引擎,允许用户在模板注入逻辑中引入复杂行为(如动态示例切换、多语言支持、上下文拼接等)。
五、与其他模块组合:PromptTemplate 本身是 Runnable
PromptTemplate
在 LangChain 中不仅仅是一个字符串格式化工具,它本身就是一个可执行模块 ,继承自 RunnableSerializable
,因此你可以像拼积木一样将其与模型、解析器、分支、回退等模块灵活组合。
这也是 LangChain 的核心哲学之一:一切都是 Runnable,一切皆可组合。
✅ 基础用法:PromptTemplate 与 LLM 拼接
python
import os
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
prompt = PromptTemplate.from_template("请解释一下:{input}")
# 或者使用环境变量
llm = ChatOpenAI(
temperature=0.7,
model="glm-4.5",
openai_api_key=os.getenv("ZAI_API_KEY"),
openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
)
# 组合两个 Runnable,构成一个完整链路
chain = prompt | llm
print(chain.invoke({"input": "月亮"}))
📌 说明:
invoke({"input": ...})
会自动传入模板所需字段- 输出为
ChatMessage
对象,通常为AIMessage(content=...)

✅ 输入转换:配合 RunnableLambda 进行字段重构
我们可以通过 RunnableLambda
对输入数据结构进行预处理,例如将外部问答表单结构转换为 Prompt 所需的 {input}
字段:
python
from langchain_core.runnables import RunnableLambda
context_injector = RunnableLambda(lambda d: {"input": d["question"]})
chain = context_injector | prompt | llm
# 原始数据不符合 Prompt 模板格式
input_data = {"question": "什么是日照金山?"}
print(chain.invoke(input_data))

✅ 常用于从工具接收参数、网页表单输入、数据库字段等"非标准格式"转为 Prompt 所需格式。
✅ 中间加工:组合 Parser、后处理、工具调用等模块
你可以在 Prompt → LLM 之间插入处理模块,例如代码高亮、参数注解、消息格式转换等:
python
from langchain_core.runnables import RunnableLambda
post_processor = RunnableLambda(lambda msg: msg.content.upper())
chain = prompt | llm | post_processor
print(chain.invoke({"input": "用10个英文单词概括一下介绍一下LLM"}))

✅ 与其他模块协同:Retry / Fallback / Tagging / LangSmith
所有 Runnable
都支持:
.with_retry(RetryConfig(...))
.with_fallbacks([...])
.with_config(tags=[...], metadata={...})
你可以构建一个"具备鲁棒性与可观测性"的 Prompt 执行链:
python
robust_chain = (prompt | llm).with_config(tags=["分类任务"])
print(robust_chain.invoke({"input": "苹果"}))
✅ 并行执行多个 Prompt:构造多路提示结构(如对比测试)
python
from langchain_core.runnables import RunnableParallel
prompt1 = PromptTemplate.from_template("请用10到20个中文汉字解释:{input}")
prompt2 = PromptTemplate.from_template("请用10到20个英文单词解释:{input}")
multi_chain = RunnableParallel({
"中文回答": prompt1 | llm,
"英文回答": prompt2 | llm
})
print(multi_chain.invoke({"input": "黑洞"}))
六、总结与工程价值
PromptTemplate 是提示工程的基础设施,具备以下价值:
- 保证提示格式一致性,降低出错率
- 支持变量化复用,提升 prompt 管理效率
- 支持示例注入与自定义格式化,增强表达能力
- 可作为 Runnable 单元与链路灵活组合
在构建复杂的 Agent、RAG 或多轮对话系统时,PromptTemplate 是最基本的构建砖块。
接下来我们将进入 LangChain 的 Memory 设计体系,理解如何构建支持上下文记忆的链,支持多轮会话与历史引用等高级功能。