# ===================================
# 学习目标
# ===================================
# 通过本模块,你将学习:
# 1. 为什么需要提示词模板
# 字符串拼接的问题
# 模板的优势
# 2.PromptTemplate
# 基本用法
# 变量替换
# 格式化方法
# 3.ChatPromptTemplate
# 聊天消息模板
# 多角色支持
# 对话历史管理
# 4.高级特性
# 部分变量
# 模板组合
# 可复用模板库
# 5.LCEL 链式调用
# 模板与模型的组合
# 管道运算符
from regex import D, P
from init_model import get_chat_model
chat_model = get_chat_model()
# 使用模板
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
# 1. 为什么需要提示词模板?
# 🔴 问题:字符串拼接的缺点
# ❌ 不推荐的做法
def demo1():
user_name = "张三"
topic = "Python"
prompt = f"你好 {user_name},我来帮你学习 {topic}"
# 问题:
# ❌ 难以维护和修改
# ❌ 容易出现格式错误
# ❌ 不能复用
# ❌ 难以测试
# ❌ 混合了逻辑和数据
def demo2():
template = PromptTemplate.from_template("你好 {user_name},我来帮你学习 {topic}")
prompt = template.format(user_name="张三", topic="Python")
# ✅ 可复用 - 一个模板,多次使用
# ✅ 可维护 - 模板和数据分离
# ✅ 类型安全 - 自动验证变量
# ✅ 可测试 - 更容易编写测试
# ✅ 可组合 - 可以组合多个模板
# 2. PromptTemplate - 简单文本模板
# PromptTemplate 用于创建简单的文本提示词,适合单一提示的场景。
# 方法 1:from_template(最简单,推荐)
def demo3():
template = PromptTemplate.from_template("你的模板文本 {变量名}")
# 方法 2:完整定义
template = PromptTemplate(
input_variables=["变量1", "变量2"], template="你的模板文本 {变量1} 和 {变量2}"
)
##创建模板的三种方法
# 方法 1:from_template(推荐)
def demo4_1():
template = PromptTemplate.from_template("将以下文本翻译成{language}:\n{text}")
# 自动识别变量
print(template.input_variables) # ['language', 'text']
def demo4_2():
template = PromptTemplate(
input_variables=["product", "feature"],
template="为{product}写一句广告语,重点突出{feature}特点。",
)
# 方法 部分变量预填充
def demo4_3():
template = PromptTemplate.from_template("你是一个{role},请{task}")
# 预填充 role
partial_template = template.partial(role="Python 导师")
# 填充 task
prompt = partial_template.format(task="解释一下什么是大模型?")
print(prompt) # 你是一个Python 导师,解释一下什么是大模型?
# 使用模板方法
# 方式 1:format() - 返回字符串
def demo5_1():
temp = PromptTemplate.from_template("你好{name}")
# 返回格式化后的字符串
prompt_str = temp.format(name="张三")
print(prompt_str) # 你好张三
# 直接传递给模型
response = chat_model.invoke(prompt_str)
print(response.content) # 你好张三,我来帮你学习 Python
# 方式 2:invoke() - 返回 PromptValue
def demo5_2():
temp = PromptTemplate.from_template("你好{name}")
# 返回 PromptValue 对象
prompt_value = temp.invoke({"name": "张三"})
# 获取文本
print(prompt_value.text) # "你好 张三"
# ===================================
# 模版实战案例
# ===================================
# 示例 1:翻译模板
def demo6():
translator = PromptTemplate.from_template(
"将以下{source_lang}文本翻译成{target_lang}:\n{text}"
)
promat = translator.format(
source_lang="英文", target_lang="中文", text="Hello, how are you?"
)
# 示例 2:代码生成模板】、
def demo7():
code_template = PromptTemplate.from_template(
"用{language}编写一个{functionality}的函数。\n"
"要求:\n"
"1. {requirement1}\n"
"2. {requirement2}"
)
prompt = code_template.format(
language="Python",
functionality="计算斐波那契数列",
requirement1="使用递归实现",
requirement2="添加类型注解",
)
# 3. ChatPromptTemplate - 聊天消息模板
# ChatPromptTemplate 用于创建聊天格式的消息,支持多种角色(system、user、assistant)。
# 为什么需要 ChatPromptTemplate?
# PromptTemplate vs ChatPromptTemplate:
# 特性 PromptTemplate ChatPromptTemplate
# 输出格式 纯文本字符串 消息列表
# 角色支持 ❌ 无 ✅ system/user/assistant
# 对话历史 ❌ 不支持 ✅ 支持
# 适用场景 简单提示 聊天、对话、多轮交互
# 消息类型
# 角色字符串 含义 用途
# "system" 系统消息 设定 AI 的行为、角色、规则
# "user" / "human" 用户消息 用户的输入/问题
# "assistant" / "ai" AI 消息 AI 的回复(用于对话历史)
# 创建方法
# 方法 1:元组格式(最简单,推荐)
def demo8_1():
chat_template = ChatPromptTemplate.from_messages(
[("system", "你是一个专业的翻译。"), ("user", "{input}")]
)
messages = chat_template.format_messages(
role="Python 导师", question="什么是装饰器?"
)
# 方法 2:字符串简写
# 单独的字符串会被解释为 user 消息
def demo8_2():
template = ChatPromptTemplate.from_messages(
[("system", "你是助手"), "{user_input}"] # 相当于 ("user", "{user_input}")
)
messages = template.format_messages(user_input="你好")
# 方法 3:使用 MessagePromptTemplate(高级)
from langchain_core.prompts import (
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
def demo8_3():
system_template = SystemMessagePromptTemplate.from_template("你是一个{role}")
human_template = HumanMessagePromptTemplate.from_template("{question}")
template = ChatPromptTemplate.from_messages([system_template, human_template])
messages = template.format_messages(role="Python 导师", question="什么是装饰器?")
## 4. 模板的使用场景
# 方式 1:format_messages() - 返回消息列表
def demo9_1():
template = ChatPromptTemplate.from_messages(
[("system", "你是{role}"), ("user", "{input}")]
)
message = template.format_messages(role="Python 导师", input="什么是装饰器?")
# 直接传递给模型
response = chat_model.invoke(message)
print(
response.content
) # 装饰器是 Python 中一种特殊的函数,用于修改其他函数的行为。
# 方式 2:invoke() - 返回 ChatPromptValue
def demo9_2():
template = ChatPromptTemplate.from_messages(
[("system", "你是{role}"), ("user", "{input}")]
)
# 返回 ChatPromptValue 对象
prompt_value = template.invoke({"role": "助手", "input": "你好"})
messages = prompt_value.to_messages()
print(messages)
# ===================================
# 实用案例
# ===================================
# 示例 1:简单聊天
def demo_chat():
template = ChatPromptTemplate.from_messages(
[("system", "你是一个友好的{role},擅长{skill}"), ("user", "{question}")]
)
messages = template.format_messages(
role="编程导师", skill="用简单语言解释复杂概念", question="什么是递归?"
)
response = chat_model.invoke(messages)
# 示例 2:多轮对话
def demo_chat_multi():
template = ChatPromptTemplate.from_messages(
[
("system", "你是一个专业的{role},擅长{skill}"),
("user", "{question}"),
("assistant", "{answer}"),
]
)
messages = template.format_messages(
role="Python 专家",
question1="什么是列表?",
answer1="列表是 Python 的有序可变集合。",
question2="它和元组有什么区别?", # 基于上下文
)
# 示例 3:结构化指令
def demo_chat1():
structured_template = ChatPromptTemplate.from_messages(
[
(
"system",
"你是一个{domain}专家。\n"
"回答风格:{style}\n"
"回答长度:{length}字以内",
),
("user", "{question}"),
]
)
messages = structured_template.format_messages(
domain="机器学习",
style="技术性强、简洁",
length="100",
question="什么是梯度下降?",
)
# 4. 高级特性
# 4.1 部分变量(Partial Variables)
# 预填充某些固定不变的变量,创建模板的变体
# 使用场景:
# 某些变量在所有调用中都相同
# 需要为不同用户/场景创建定制模板
# 语法:
def demo_partial():
# 创建一个初始模板
template = ChatPromptTemplate.from_messages(
[("system", "你是{role},目标用户是{audience}"), ("user", "{task}")]
)
# 预填充模版部分数据
customer_support_template = template.partial(role="客服专员", audience="普通用户")
# 现在只需要提供 task
messages = customer_support_template.format_messages(task="解释退款政策")
response = chat_model.invoke(messages)
# 实用示例:
def demo_chat2():
# 创建一个初始模板
# 基础翻译模板
translator = ChatPromptTemplate.from_messages(
[("system", "你是专业翻译,精通{source}和{target}"), ("user", "翻译:{text}")]
)
# 创建英译中的专用模板
en_to_zh = translator.partial(source="英语", target="中文")
# 创建中译英的专用模板
zh_to_en = translator.partial(source="中文", target="英语")
# 英译中
messages = en_to_zh.format_messages(text="Hello, how are you?")
response = chat_model.invoke(messages)
print(response.content)
# 中译英
messages = zh_to_en.format_messages(text="你好,我很好")
response = chat_model.invoke(messages)
print(response.content)
# 模板组合
# 将多个模板片段组合成复杂的提示词。
# 方法 1:字符串组合
def demo_chat3():
# 定义可复用的部分
# 定义可复用的部分
role_part = "你是一个{domain}专家。"
style_part = "回答风格:{style}。"
constraint_part = "限制:{constraint}。"
# 组合
full_system = role_part + style_part + constraint_part
template = ChatPromptTemplate.from_messages(
[("system", full_system), ("user", "{question}")]
)
# 方法 2:使用 + 运算符
def demo_chat4():
template1 = ChatPromptTemplate.from_messages([("system", "你是助手")])
template2 = ChatPromptTemplate.from_messages([("user", "{input}")])
# 组合(LangChain 1.0 支持)
combined = template1 + template2
# 格式化
messages = combined.format_messages(input="你好")
response = chat_model.invoke(messages)
print(response.content)
# 4.3 可复用模板库
# 在实际项目中,建议创建模板库。
# 示例:模板库
# templates.py
# from langchain_core.prompts import ChatPromptTemplate
# class PromptTemplates:
# """可复用的提示词模板库"""
# TRANSLATOR = ChatPromptTemplate.from_messages(
# [("system", "你是专业翻译,精通{source}和{target}"), ("user", "翻译:{text}")]
# )
# CODE_REVIEWER = ChatPromptTemplate.from_messages(
# [
# ("system", "你是{language}代码审查专家,重点关注{focus}"),
# ("user", "审查代码:\n```{language}\n{code}\n```"),
# ]
# )
# SUMMARIZER = ChatPromptTemplate.from_messages(
# [
# ("system", "你是内容摘要专家"),
# ("user", "将以下内容总结为{num}个要点:\n{content}"),
# ]
# )
# TUTOR = ChatPromptTemplate.from_messages(
# [("system", "你是{subject}导师,学生水平:{level}"), ("user", "{question}")]
# )
# 使用
# from templates import PromptLibrary
# messages = PromptLibrary.TRANSLATOR.format_messages(
# source_lang="英语",
# target_lang="中文",
# text="Hello World"
# )
# 5. LCEL 链式调用(预览)
# LCEL = LangChain Expression Language,LangChain 的表达式语言。
# 什么是链(Chain)?
# 链是将多个组件连接在一起的方式,形成处理流程。
# 输入 → 模板 → 模型 → 输出
# 使用管道运算符 |
def demo_chat5():
# 创建组件
template = ChatPromptTemplate.from_messages(
[("system", "你是{role}"), ("user", "{input}")]
)
# 使用 | 创建链
chain = template | chat_model
response = chain.invoke(
{
"role": "客服专员",
"input": "解释退款政策",
}
)
print(response.content)
# 链的优势
# 优势 说明
# 简洁 一行代码完成多步操作
# 可读 清晰展示数据流向
# 可组合 可以轻松添加/删除组件
# 可复用 链本身可以作为组件
# 详细内容将在后续模块学习。
# 常见问题 (FAQ)
# Q1: PromptTemplate 和 ChatPromptTemplate 有什么区别?
# A:
# 特性 PromptTemplate ChatPromptTemplate
# 输出 字符串 消息列表
# 角色 无 system/user/assistant
# 适用场景 简单提示 聊天、对话
# 建议:
# 简单场景 → PromptTemplate
# 聊天场景 → ChatPromptTemplate(推荐)
# Q2: 什么时候使用部分变量?
# A: 当某些变量在多次调用中保持不变时:
# 场景:为不同部门创建专用模板\
# def demo_chat6():
# base_template = ChatPromptTemplate.from_messages(
# [("system", "你是{department}的{role}"), ("user", "{task}")]
# )
# # IT 部门
# it_template = base_template.partial(department="IT", role="开发工程师")
# # 销售部门
# sales_template = base_template.partial(department="销售部门", role="销售顾问")
# Q3: 如何在模板中使用换行和特殊字符?
# A: 使用三引号字符串:
def demo_chat7():
template = PromptTemplate.from_template(
"""
你是一个{role}。
请完成以下任务:
1. {task1}
2. {task2}
注意事项:
- {note1}
- {note2}
"""
)
# Q4: 模板变量可以是什么类型?
# A: 通常是字符串,但也可以是其他可转换为字符串的类型:
def demo_chat8():
template = PromptTemplate.from_template("生成{count}个关于{topic}的想法")
# count 是整数
prompt = template.format(count=5, topic="创新")
# Q5: 如何处理可选变量?
# A: 使用部分变量或默认值:
def demo_chat9():
# 方法 1:部分变量
template = PromptTemplate.from_template("{greeting} {name},{message}")
template_with_default = template.partial(greeting="你好")
# 方法 2:在应用层处理
def create_prompt(name, message, greeting="你好"):
return template.format(greeting=greeting, name=name, message=message)
# 最佳实践
# 1. 模板命名规范
# ✅ 好的命名
# translator_template = ...
# code_review_template = ...
# customer_support_template = ...
# # ❌ 不好的命名
# template1 = ...
# t = ...
# my_template = ...
# 2.组织模版
# templates/
# ├── __init__.py
# ├── common.py # 通用模板
# ├── translation.py # 翻译相关
# └── coding.py # 编程相关
def demo_chat9_2():
# common.py
FRIENDLY_ASSISTANT = ChatPromptTemplate.from_messages(
[("system", "你是一个友好的助手"), ("user", "{input}")]
)
# 3. 文档化模板
class Templates:
"""项目模板库"""
TRANSLATOR = ChatPromptTemplate.from_messages(
[("system", "你是专业翻译"), ("user", "翻译:{text}")]
)
"""
翻译模板
变量:
- text: 要翻译的文本
示例:
messages = TRANSLATOR.format_messages(text="Hello")
"""
# 4. 测试模板
# def test_translator_template():
# """测试翻译模板"""
# template = PromptLibrary.TRANSLATOR
# # 测试变量识别
# assert "text" in template.input_variables
# # 测试格式化
# messages = template.format_messages(text="Hello")
# assert len(messages) == 2
# assert messages[0].type == "system"
# assert messages[1].type == "user"
def main():
demo9_2()
if __name__ == "__main__":
main()