[LangChain RAG] 04 提示词工程:PromptTemplate、Few-shot 与 ChatPromptTemplate

一、为什么要用提示词模板

提示词优化在模型应用中非常重要。LangChain 提供模板类,用来协助优化提示词:可以构建自定义的基础提示词模板,支持变量注入,最终生成所需提示词。

1.1 三种模板各自管什么

  • PromptTemplate:通用提示词模板,支持动态注入信息(zero-shot)。

  • FewShotPromptTemplate:支持基于模板注入任意数量的示例信息。

  • ChatPromptTemplate:支持注入任意数量的历史会话信息。

1.2 为什么不自己拼字符串

  • 在大型工程中更容易做标准化模板

  • Template 模板类支持 LangChain 框架的链式调用(Runnable 接口)

二、PromptTemplate(zero-shot)

2.1 标准写法:format 出字符串再 invoke

复制代码
from langchain_core.prompts import PromptTemplate
from langchain_community.llms.tongyi import Tongyi

prompt_template = PromptTemplate.from_template(
    "我的邻居姓{lastname}, 刚生了{gender}, 帮忙起名字,请简略回答。"
)

# 变量注入,生成提示词文本
prompt_text = prompt_template.format(lastname="张", gender="女儿")

model = Tongyi(model="qwen-max")
res = model.invoke(input=prompt_text)
print(res)

2.2 基于 chain 链的写法

复制代码
from langchain_core.prompts import PromptTemplate
from langchain_community.llms.tongyi import Tongyi

prompt_template = PromptTemplate.from_template(
    "我的邻居姓{lastname}, 刚生了{gender}, 帮忙起名字,请简略回答。"
)

model = Tongyi(model="qwen-max")
chain = prompt_template | model
res = chain.invoke(input={"lastname": "曹", "gender": "女儿"})
print(res)

zero-shot 思想下,可以基于 PromptTemplate 直接完成。few-shot 思想下,需要更换为 FewShotPromptTemplate。

三、FewShotPromptTemplate

3.1 五个核心参数

复制代码
from langchain_core.prompts import FewShotPromptTemplate

FewShotPromptTemplate(
    examples=None,
    example_prompt=None,
    prefix=None,
    suffix=None,
    input_variables=None
)
参数 含义
examples 示例数据,list,内套字典
example_prompt 示例数据的提示词模板
prefix 组装提示词时,示例数据前的内容
suffix 组装提示词时,示例数据后的内容
input_variables 列表,注入的变量列表

3.2 组装并得到最终提示词

复制代码
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate

example_template = PromptTemplate.from_template("单词:{word}, 反义词:{antonym}")

example_data = [
    {"word": "大", "antonym": "小"},
    {"word": "上", "antonym": "下"}
]

few_shot_prompt = FewShotPromptTemplate(
    example_prompt=example_template,
    examples=example_data,
    prefix="给出给定词的反义词,有如下示例:",
    suffix="基于示例告诉我:{input_word}的反义词是?",
    input_variables=['input_word']
)

prompt_text = few_shot_prompt.invoke(input={"input_word": "左"}).to_string()
print(prompt_text)

3.3 调用模型获得结果

复制代码
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi

example_template = PromptTemplate(
    input_variables=['word', 'antonym'],
    template="word: {word}, antonym: {antonym}"
)

example_data = [
    {"word": "大", "antonym": "小"},
    {"word": "上", "antonym": "下"}
]

few_shot_prompt = FewShotPromptTemplate(
    examples=example_data,
    example_prompt=example_template,
    prefix="给出给定词的反义词,有如下示例:",
    suffix="基于示例告诉我:{input_word}的反义词是?",
    input_variables=['input_word']
)

prompt_text = few_shot_prompt \
    .invoke(input={"input_word": "左"}) \
    .to_string()

model = ChatTongyi(model="qwen3-max")
for chunk in model.stream(input=prompt_text):
    print(chunk.content, end="", flush=True)

四、模板的 format 与 invoke

4.1 谁有这两个方法

在PromptTemplate(通用提示词模板)和FewShotPromptTemplate(FewShot提示词模板)的使用中,我们使用了如下:

PromptTemplate、FewShotPromptTemplate、ChatPromptTemplate 都拥有 format 和 invoke 这两类方法。

继承关系:Runnable 定义 invoke 规范 → BasePromptTemplate 定义 format 规范 → 三个具体模板类继承。

4.2 对照表

区别 format invoke
功能 纯字符串替换,解析占位符生成提示词 Runnable 接口标准方法,解析占位符生成提示词
返回值 字符串 PromptValue 类对象
传参 .format(k=v, k=v, ...) .invoke({"k": v, "k": v, ...})
解析 支持解析 {} 占位符 支持解析 {} 占位符和 MessagesPlaceholder 结构化占位符

后面注入聊天历史时,必须用 invoke ,format 注入不了 MessagesPlaceholder。

五、ChatPromptTemplate

5.1 from_messages 可以接多轮

通过 from_messages 从列表中获取多轮次会话作为聊天的基础模板。from_template 仅能接入一条消息,from_messages 可以接入一个 list 的消息。

复制代码
from langchain_core.prompts import ChatPromptTemplate

ChatPromptTemplate.from_messages(
    [
        ("system", "........"),
        ("ai", "........"),
        # ......
        ("human", "........")
    ]
)

5.2 历史是动态的:MessagesPlaceholder

历史会话并不是静态的,而是随着对话不停积攒,因此需要动态注入 。用 MessagesPlaceholder 占位,必须用 invoke:

复制代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.prompts import MessagesPlaceholder

chat_template = ChatPromptTemplate.from_messages(
    [
        ("system", "........"),
        ("ai", "........"),
        MessagesPlaceholder("history"),
        ("human", "........")
    ]
)

history_data = [
    ("human", "..."),
    ("ai", "..."),
    ("human", "..."),
    ("ai", "...")
]

prompt_value = chat_template.invoke({"history": history_data})

MessagePlaceholder作为占位, 提供history作为占位的key, 基于invoke动态注入历史会话记录 ,必须是invoke,format无法注入。

5.3 结合聊天模型做 few-shot(求反义词)

复制代码
from langchain_community.chat_models import ChatTongyi
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage

prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "给出每个单词的反义词"),
        MessagesPlaceholder("history"),
        ("human", "{question}")
    ]
)
model = ChatTongyi(model="qwen3-max")
# StrOutputParser:内置结果解析器,直接提取结果文本,剔除其余元数据
chain = prompt | model | StrOutputParser()

# 无历史会话的提问
for chunk in chain.stream(input={"history": [], "question": "粗"}):
    print(chunk)
print("*" * 20)

# 带历史的提问
history = [
    HumanMessage(content="开心"),
    AIMessage(content="难过"),
    HumanMessage(content="高"),
    AIMessage(content="矮")
]
# 简化写法:
# history = [
#     ("human", "开心"), ("ai", "难过"),
#     ("human", "高"), ("ai", "矮")
# ]
for chunk in chain.stream(input={"history": history, "question": "粗"}):
    print(chunk)
相关推荐
~kiss~4 小时前
LangChain 基础学习
学习·langchain
制造数据与AI践行者老蒋6 小时前
排坑笔记:LangChain 多工具 Agent 完整性校验 return_intermediate_steps 事后核对方案
langchain·ai agent·工具调用·agent开发·排坑笔记·多工具协同·工程化 质量保障
打工仔折腾 AI8 小时前
System Prompt 替代 Few-shot:用规则约束大模型输出的省钱实践
java·人工智能·python·spring·langchain·prompt·ai agent 实战
镜舟科技9 小时前
从 StarRocks 到 MIP:数据平台的下一步是“理解”
starrocks·sql·ai·prompt·agent·context·mip
空心木偶☜11 小时前
LangChain 概述
python·ai·langchain·ai编程
Maiko Star13 小时前
* LangChain RAG 入门:核心原理、环境准备与多种文档加载器
langchain
“AI国潮设计-小江”1 天前
《Python+SDXL实战:用ControlNet精准控制“英歌舞翻糖吐司”构图,附批量生成脚本》
开发语言·人工智能·python·prompt·aigc
Query*1 天前
深入浅出LangGraph【一】_基础篇
python·ai·langchain
大连好光景1 天前
大模型应用中,如何实现短期记忆与长期记忆
langchain·记忆
Bug收容所1 天前
学习LangChain day1
学习·langchain·llm·agent