Langchain学习(3):提示词模板
建议:实践建议:
·
1. 为什么需要 Prompt Template?
| 层面 | 直接写字符串 | 使用 PromptTemplate / ChatPromptTemplate |
|---|---|---|
| 可读性 | 较差,变量硬拼接易出错、难维护 | 较好,使用清晰的占位符,结构明确 |
| 安全性 | 更容易受到提示注入(prompt injection)攻击 | 不自动提供安全防护,但结构化模板有助于统一输入校验和过滤 |
| 可维护性 | 较差,修改需遍历所有拼接点 | 较好,集中管理模板逻辑,一处修改全局生效 |
| 复用性 | 低,通常与业务逻辑耦合 | 高,支持模块化、组合、版本控制 |
| 调试性 | 困难,需手动拼接后才能查看最终提示 | 便捷,可通过 .format() 或 .invoke() 预览完整提示 |
| 工程化程度 | 适合快速原型或脚本 | 更适合生产环境,便于测试、监控和迭代 |
📌 说明:虽然现代 LLM 应用中直接字符串拼接较少见,但在简单脚本或临时实验中仍可能使用。关键在于根据场景权衡开发效率与长期可维护性。
2. 三类模板对比
| 模板类型 | 主要用途 | 输出类型 | 是否支持角色 | 是否适合多轮对话 |
|---|---|---|---|---|
PromptTemplate |
适用于传统 completion 接口或简单任务 | str |
不显式支持 | 不推荐,但可通过外部拼接模拟 |
FewShotPromptTemplate |
需要上下文示例(in-context learning)的任务 | str |
不支持 | 一般不适合,因缺乏对话历史结构 |
ChatPromptTemplate |
适用于现代聊天接口(如 OpenAI、Anthropic、Claude、Qwen 等) | List[BaseMessage] |
支持 system/human/ai 等角色 |
非常适合,原生支持对话历史 |
📌 注意:是否“支持角色”指的是模板本身是否能区分消息发送者身份。
PromptTemplate生成纯文本,无法表达角色语义;而ChatPromptTemplate生成的消息列表可被聊天模型正确解析。
3. 三类模板代码示例
3.1 PromptTemplate
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import PromptTemplate
from langchain_ollama import OllamaLLM
prompt_template = PromptTemplate.from_template(
"我的邻居是一个{profession},他每天都在{activity}。我觉得他很{adjective}。你分析一下我了解他的那些信息。"
)
model = Tongyi(
model="qwen3-max-preview"
)
# model = OllamaLLM(
# model="qwen3:4b",
# )
chain = prompt_template | model
for chunk in chain.stream({"profession": "医生", "activity": "看病", "adjective": "友好"}):
print(chunk, end="", flush=True)
建议:
- 优先使用
from_template(),自动推导变量,减少出错。 - 模板尽量使用多行字符串(
"""..."""),提升可读性。 - 可在末尾添加输出格式约束(如“请以 JSON 格式返回…”),但需注意:仅靠自然语言指令无法保证格式稳定性。
- 若需强结构化输出,应配合
PydanticOutputParser或模型的with_structured_output()(后者要求模型支持函数调用或 JSON 模式)。
3.2 FewShotPromptTemplate
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_ollama import OllamaLLM
example_template = PromptTemplate.from_template("单词:{word},反义词:{antonym}")
example_data = [
{"word": "高兴", "antonym": "难过"},
{"word": "大", "antonym": "小"},
{"word": "快", "antonym": "慢"},
]
few_shot_prompt = FewShotPromptTemplate(
example_prompt=example_template, # 示例数据模版
examples=example_data, # 示例数据
prefix="给出给定词的反义词,有如下示例", # 提示词前缀
suffix="基于实例告诉我,{input_word}的反义词是什么?", # 提示词后缀
input_variables=["input_word"] # 声明前缀或后缀中所需要注入的变量名
)
# 生成提示词
prompt = few_shot_prompt.invoke(input={"input_word": "高"}).to_string()
# print(prompt)
# 交给大模型并输出
model = Tongyi(
model="qwen3-max-preview"
)
# model = OllamaLLM(
# model="qwen3:4b"
# )
for chunk in model.stream(prompt):
print(chunk, end="", flush=True)
实践建议:
- 示例质量远比数量重要,3–5 个高质量、代表性强的示例通常优于大量噪声示例。
- 语义相似度选择器在 RAG 或问答场景中效果显著,但需额外基础设施支持。
- 避免示例与当前问题领域不匹配,否则可能引入干扰。
3.3 ChatPromptTemplate
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_ollama import ChatOllama
# 示例:定义一个更完整的 ChatPromptTemplate
chat_template = ChatPromptTemplate.from_messages(
[
("system", "你是一个乐于助人的 AI 编程助手,请用中文回答问题。"),
MessagesPlaceholder(variable_name="history"), # 用于存放多轮对话历史
("human", "{user_input}"), # 用户最新输入
]
)
# 使用示例
messages = chat_template.invoke(
input={
"history": [
("human", "你好,请介绍一下 Python。"),
("ai", "Python 是一种高级编程语言,以简洁易读著称。"),
],
"user_input": "它有哪些常用数据结构?"
}
).to_string()
# model = ChatTongyi(
# model="qwen3-max-preview"
# )
model = ChatOllama(
model="qwen3:4b"
)
for chunck in model.stream(messages):
print(chunck.content, end="", flush=True)
4. 快速对照表 – 如何选择模板?
| 你的场景 | 推荐模板 | 说明 |
|---|---|---|
| 使用传统 completion 接口(如旧版 Llama、某些本地模型) | PromptTemplate |
若模型不接受消息列表,则只能用字符串 |
| 需要少量高质量示例引导模型行为(如分类、抽取) | FewShotPromptTemplate |
优先结合 SemanticSimilarityExampleSelector 动态选例 |
| 使用现代聊天模型(OpenAI、Claude、Qwen、Gemini 等) | ChatPromptTemplate |
绝大多数 2024 年后的新模型均采用聊天接口 |
| 构建多轮对话系统 | ChatPromptTemplate + Memory |
利用 MessagesPlaceholder 注入历史 |
| 开发 ReAct / Function Calling Agent | ChatPromptTemplate + agent_scratchpad |
agent_scratchpad 是中间推理的关键占位符 |
| 要求严格结构化输出(JSON / Pydantic) | ChatPromptTemplate + .with_structured_output() |
前提是模型支持结构化输出能力 |
💡 总结:
- 不要因为“新”就盲目用
ChatPromptTemplate—— 如果你的模型只接受纯文本输入(如某些开源模型的 base 版本),PromptTemplate仍是合理选择。- 安全性不能依赖模板本身,需在应用层做输入过滤、输出校验、权限控制等。
- 提示工程是迭代过程,模板设计应配合评估指标(如准确率、幻觉率)持续优化。
更多推荐


所有评论(0)