共计 3165 个字符,预计需要花费 8 分钟才能阅读完成。
本节课会学到:
- PromptTemplate:纯文本模板(传统"补全式"模型风格,也适合拼长文本);
- ChatPromptTemplate:聊天消息模板,支持 system / human 多角色(最常用);
- FewShotChatMessagePromptTemplate:少样本示例,用几个例子"教"模型按格式输出;
- 模板本身不会调用模型,它只负责"拼提示词",拼好后再交给 LLM。
"""
02 提示词模板(Prompt Template)—— LangChain 学习第 2 课
==========================================================
本节课你会学到:
1. PromptTemplate:纯文本模板(传统"补全式"模型风格,也适合拼长文本);
2. ChatPromptTemplate:聊天消息模板,支持 system / human 多角色(最常用);
3. FewShotChatMessagePromptTemplate:少样本示例,用几个例子"教"模型按格式输出;
4. 模板本身不会调用模型,它只负责"拼提示词",拼好后再交给 LLM。
运行方式:
.venv\\Scripts\\python examples\\02_prompt_template.py
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from langchain_core.prompts import ( # 提示词模板全家桶
ChatPromptTemplate,
FewShotChatMessagePromptTemplate,
PromptTemplate,
)
from langchain_core.output_parsers import StrOutputParser # 把 AIMessage 转成纯字符串
from config import get_chat_model, print_sub, print_title
def demo_prompt_template() -> None:
"""PromptTemplate:纯文本变量替换,用 {} 占位。"""
print_sub("1. PromptTemplate:纯文本模板")
# input_variables 会从 {占位符} 自动推断,也可以显式声明
prompt = PromptTemplate.from_template(
"我正在学习{language},请给我 3 个适合初学者的练手项目,每个一句话说明。"
)
# format() 只是本地字符串替换,不花钱、不调模型
text = prompt.format(language="Python")
print(f"拼出来的提示词:\n{text}\n")
# 真正调用模型(模板 | 模型 是 LCEL 管道写法,第 4 课详讲)
chain = prompt | get_chat_model(temperature=0.5) | StrOutputParser()
print("模型回答:")
print(chain.invoke({"language": "Python"}))
def demo_chat_prompt_template() -> None:
"""ChatPromptTemplate:多角色聊天模板,真实项目 90% 用它。"""
print_sub("2. ChatPromptTemplate:system + human 多角色模板")
prompt = ChatPromptTemplate.from_messages(
[
# (角色, 内容) 元组形式;角色支持 system / human / ai / placeholder
("system", "你是一位资深{role},回答必须通俗易懂,并举一个生活中的类比。"),
("human", "{question}"),
]
)
# invoke 时把所有变量一次性传进去
messages = prompt.format_messages(
role="后端架构师",
question="什么是消息队列?不用它会怎样?",
)
print("拼出来的消息列表:")
for m in messages:
print(f" [{type(m).__name__}] {m.content}")
chain = prompt | get_chat_model(temperature=0.4) | StrOutputParser()
print("\n模型回答:")
print(chain.invoke({"role": "后端架构师", "question": "什么是消息队列?不用它会怎样?"}))
def demo_few_shot() -> None:
"""FewShot:给模型看几个标准问答示例,让它"照葫芦画瓢"。"""
print_sub("3. FewShotChatMessagePromptTemplate:少样本示例(统一输出风格)")
# 示例数据:每个元素是一组 human 提问 + ai 标准回答
examples = [
{"input": "这电影看得我睡着了", "output": "情感:负面 | 理由:观众感到无聊,说明影片不够吸引人"},
{"input": "特效还行,剧情一塌糊涂", "output": "情感:负面 | 理由:明确批评剧情质量差"},
{"input": "值回票价,结尾反转没想到", "output": "情感:正面 | 理由:认为值得且赞赏剧情反转"},
]
# 单条示例的模板
example_prompt = ChatPromptTemplate.from_messages(
[("human", "{input}"), ("ai", "{output}")]
)
# 把示例组装进 few-shot 模板
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt, # 每条示例长什么样
examples=examples, # 全部示例数据
)
# 最终模板:系统指令 + 几个示例 + 真正的用户输入
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "你是影评情感分析器,严格模仿示例的格式输出,不要说废话。"),
few_shot_prompt, # 把少样本示例插在这里
("human", "{input}"),
]
)
chain = final_prompt | get_chat_model(temperature=0.0) | StrOutputParser()
user_review = "演员演技在线,但是三个小时实在太长了,中间玩了半小时手机"
print(f"用户评论:{user_review}")
print(f"模型输出:{chain.invoke({'input': user_review})}")
def main() -> None:
print_title("02 提示词模板:PromptTemplate / ChatPromptTemplate / FewShot")
demo_prompt_template()
demo_chat_prompt_template()
demo_few_shot()
print_sub("本课小结")
print("模板 = 提示词的可复用模具:变量用 {name} 占位,format/invoke 时填值。")
print("聊天场景优先用 ChatPromptTemplate;想强制输出格式/风格时用 FewShot 给示例。")
print("模板只负责拼字符串,调用模型是下一步的事(见 03、04 课)。")
if __name__ == "__main__":
main()
正文完