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 仍是合理选择。
  • 安全性不能依赖模板本身,需在应用层做输入过滤、输出校验、权限控制等。
  • 提示工程是迭代过程,模板设计应配合评估指标(如准确率、幻觉率)持续优化。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐