LangChain 大模型调用:PromptTemplate 用法全景对比

版本:Python 3.9+、LangChain 0.1.x
目标:一份代码即可复制运行,快速看懂不同 PromptTemplate 的差异与选型要点


1. 环境 30 秒就绪

# 建议先建虚拟环境
pip install -U langchain langchain-openai python-dotenv

.env 文件(同级目录)

OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://api.openai.com/v1   # 如需转发,可改

2. 统一 LLM 实例(下文全部复用)

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

3. PromptTemplate 六边形对比

模板类型典型场景变量声明风格是否支持 DSL链式调用辅助备注
基础 PromptTemplate单轮、变量少{}❌❌最早版本,最轻量
ChatPromptTemplate多轮、角色区分("role", "content")❌✅推荐用于对话
FewShotPromptTemplate动态少样本模板里再嵌模板❌✅把示例也当成变量
PipelinePrompt超长 prompt 模块化分片拼接❌✅适合团队协作
MessagesPlaceholder运行时动态追加 Message占位符❌✅把历史记录直接“塞”进去
自定义 Template领域 DSL随便定✅✅自己写 parse_template

4. 代码实战:一行差异看清用法

导包准备:

from langchain.prompts import (
    PromptTemplate,
    ChatPromptTemplate,
    FewShotPromptTemplate,
    PipelinePromptTemplate,
    MessagesPlaceholder
)
from langchain_core.messages import HumanMessage, AIMessage

4.1 基础 PromptTemplate

适用:单轮、变量少、无需角色区分

basic_prompt = PromptTemplate.from_template(
    "把下面的英文单词翻译成中文:{word}"
)
print("1. 基础模板结果:", llm.invoke(basic_prompt.format(word="apple")).content)

4.2 ChatPromptTemplate(带 system + user)

适用:system / user / assistant 区分

chat_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个专业翻译助手,直接给出译文即可,不要解释。"),
    ("user", "翻译:{word}")
])
print("2. 对话模板结果:", llm.invoke(chat_prompt.format_messages(word="banana"))[0].content)

4.3 FewShotPromptTemplate(动态示例)

适用:示例想运行时换,无需硬编码

examples = [
    {"en": "cat", "zh": "猫"},
    {"en": "dog", "zh": "狗"}
]
example_template = PromptTemplate.from_template("EN: {en}  ->  ZH: {zh}")
fewshot_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_template,
    suffix="EN: {input}  ->  ZH:",
    input_variables=["input"]
)
print("3. 少样本结果:", llm.invoke(fewshot_prompt.format(input="rabbit")).content)
4.4 PipelinePromptTemplate(分块拼接)

适用:多人维护、分块复用

intro = PromptTemplate.from_template("你叫{name},{age}岁,")
hobby = PromptTemplate.from_template("平时喜欢{hobby}。")
full_prompt = PipelinePromptTemplate(
    final_prompt=PromptTemplate.from_template("{intro}{hobby}请自我介绍。"),
    pipeline_prompts=[("intro", intro), ("hobby", hobby)]
)
print("4. Pipeline结果:",
      llm.invoke(full_prompt.format(name="小K", age=18, hobby="写代码")).content)

4.5 MessagesPlaceholder(把历史记录直接插进去)

适用:把任意 List[Message] 整体“塞”进 promp

dynamic_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是客服助手,根据上下文回答用户问题。"),
    MessagesPlaceholder(variable_name="history"),
    ("user", "{question}")
])
history = [
    HumanMessage(content="我订单号 12345 没收到"),
    AIMessage(content="已帮你催促,24 小时内答复")
]
print("5. MessagesPlaceholder结果:",
      llm.invoke(dynamic_prompt.format_messages(history=history, question="现在几点了?"))[0].content)

5. 选型速查表(直接截图即可)

需求首选模板
简单字符串变量PromptTemplate
多轮对话、角色区分ChatPromptTemplate
示例想动态换FewShotPromptTemplate
Prompt >2k tokens、多人维护PipelinePromptTemplate
运行时插入任意消息列表MessagesPlaceholder

6. 常见坑

  1. 用 ChatOpenAI 一定配 ChatPromptTemplate,否则 messages 格式不对会 400
  2. FewShotPromptTemplate 的 examples 必须是字典列表,且 key 与 example_prompt 中的变量名完全一致
  3. PipelinePromptTemplate 的 pipeline_prompts 顺序会影响最终字符串拼接顺序
  4. 如果想把 prompt 打印调试,直接 print(prompt.format(...)) 即可,无需真正调用 llm

更多推荐