提示工程:掌握LangChain中的提示模板和技巧
提示工程基础 🎯
1. 什么是提示工程?
提示工程就像是与AI对话的艺术:
- 如何提问(输入设计)
- 如何引导(上下文控制)
- 如何获得期望的答案(输出控制)
2. 为什么需要提示工程?
- 提高回答质量
- 确保输出格式
- 控制生成内容
- 优化交互效果
提示模板 📝
1. 基础模板
from langchain.prompts import PromptTemplate
# 简单模板
template = PromptTemplate.from_template(
"请给我一个关于{topic}的{length}字简介"
)
# 使用模板
prompt = template.format(
topic="人工智能",
length="100"
)
print(prompt)
# 输出: 请给我一个关于人工智能的100字简介
2. 带验证的模板
from langchain.prompts import PromptTemplate
# 创建带验证的模板
template = PromptTemplate(
input_variables=["product_name", "price"],
template="产品名称:{product_name}\n价格:{price}元\n请生成一个产品推广文案。",
# 验证器确保价格是数字
validate_template=True
)
try:
# 正确使用
prompt1 = template.format(
product_name="智能手表",
price="1999"
)
print("正确示例:")
print(prompt1)
# 错误使用
prompt2 = template.format(
product_name="智能手表",
price="很贵" # 这会引发错误
)
except ValueError as e:
print("\n错误示例:")
print(f"错误:{str(e)}")
3. 聊天提示模板
from langchain.prompts import ChatPromptTemplate
from langchain.prompts.chat import SystemMessage, HumanMessage
# 创建聊天模板
chat_template = ChatPromptTemplate.from_messages([
SystemMessage(content="你是一位专业的{role}"),
HumanMessage(content="请问{question}")
])
# 格式化消息
messages = chat_template.format_messages(
role="Python教师",
question="什么是装饰器?"
)
for message in messages:
print(f"{message.type}: {message.content}")
# 输出:
# system: 你是一位专业的Python教师
# human: 请问什么是装饰器?
示例学习(Few-Shot Learning)📚
1. 基本示例学习
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts import PromptTemplate
# 定义示例
examples = [
{"word": "开心", "antonym": "难过"},
{"word": "高兴", "antonym": "沮丧"},
{"word": "兴奋", "antonym": "平静"}
]
# 创建示例格式模板
example_template = """
词语: {word}
反义词: {antonym}
"""
example_prompt = PromptTemplate(
input_variables=["word", "antonym"],
template=example_template
)
# 创建Few-Shot提示模板
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="请根据以下示例,给出词语的反义词:",
suffix="词语: {input}\n反义词:",
input_variables=["input"]
)
# 使用模板
prompt = few_shot_prompt.format(input="快乐")
print(prompt)
# 输出:
# 请根据以下示例,给出词语的反义词:
#
# 词语: 开心
# 反义词: 难过
#
# 词语: 高兴
# 反义词: 沮丧
#
# 词语: 兴奋
# 反义词: 平静
#
# 词语: 快乐
# 反义词:
2. 动态示例选择
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
# 准备更多示例
examples = [
{"word": "开心", "antonym": "难过"},
{"word": "高兴", "antonym": "沮丧"},
{"word": "兴奋", "antonym": "平静"},
{"word": "勇敢", "antonym": "胆怯"},
{"word": "聪明", "antonym": "愚笨"},
{"word": "勤奋", "antonym": "懒惰"}
]
# 创建示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
examples,
OpenAIEmbeddings(),
FAISS,
k=2 # 选择2个最相关的示例
)
# 创建动态Few-Shot提示模板
dynamic_prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
prefix="请根据以下示例,给出词语的反义词:",
suffix="词语: {input}\n反义词:",
input_variables=["input"]
)
# 使用动态模板
prompt = dynamic_prompt.format(input="智慧")
print(prompt)
# 输出会包含最相关的示例(如"聪明")
提示优化技巧 💡
1. 结构化输出
# 定义JSON输出格式的提示模板
json_template = PromptTemplate.from_template("""
分析以下文本的情感,返回JSON格式:
文本: {text}
要求返回格式如下:
{
"sentiment": "positive/negative/neutral",
"confidence": 0.0-1.0,
"keywords": ["关键词1", "关键词2"]
}
""")
# 使用模板
prompt = json_template.format(
text="这家餐厅的服务态度很好,食物也很美味,就是价格有点贵。"
)
2. 分步骤提示
# 创建分步骤提示模板
step_template = PromptTemplate.from_template("""
请按照以下步骤分析这个编程问题:
问题描述:{problem}
1. 理解问题
- 输入是什么?
- 输出应该是什么?
- 有什么限制条件?
2. 设计解决方案
- 可以使用什么算法?
- 需要什么数据结构?
- 时间和空间复杂度是多少?
3. 编写代码
- 提供Python代码实现
- 包含必要的注释
- 处理边界情况
4. 测试验证
- 给出测试用例
- 验证代码正确性
- 考虑极端情况
请按照上述步骤,详细分析并解决这个问题。
""")
# 使用模板
prompt = step_template.format(
problem="实现一个函数,找出数组中第K大的数字"
)
3. 角色设定
# 创建带角色设定的模板
role_template = ChatPromptTemplate.from_messages([
SystemMessage(content="""你是一位经验丰富的{role},具有以下特点:
1. {trait_1}
2. {trait_2}
3. {trait_3}
在回答问题时,请始终保持这个角色定位。
"""),
HumanMessage(content="{question}")
])
# 使用模板
messages = role_template.format_messages(
role="Python技术面试官",
trait_1="深入理解Python原理和最佳实践",
trait_2="擅长引导候选人思考和分析问题",
trait_3="注重代码质量和设计模式",
question="请评估一下这段代码的优缺点:\n```python\ndef process_data(data):\n return [x*2 for x in data if x > 0]```"
)
高级应用 🚀
1. 提示链组合
from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI
# 创建多个专门的提示模板
analysis_template = PromptTemplate.from_template(
"分析以下文本的主要观点:{text}"
)
summary_template = PromptTemplate.from_template(
"基于以下分析生成总结:{analysis}"
)
suggestion_template = PromptTemplate.from_template(
"基于以下总结提供改进建议:{summary}"
)
# 创建链
llm = ChatOpenAI(temperature=0)
analysis_chain = LLMChain(
llm=llm,
prompt=analysis_template
)
summary_chain = LLMChain(
llm=llm,
prompt=summary_template
)
suggestion_chain = LLMChain(
llm=llm,
prompt=suggestion_template
)
# 组合使用
async def process_text(text):
# 1. 分析
analysis = await analysis_chain.arun(text=text)
# 2. 总结
summary = await summary_chain.arun(analysis=analysis)
# 3. 建议
suggestions = await suggestion_chain.arun(summary=summary)
return {
"analysis": analysis,
"summary": summary,
"suggestions": suggestions
}
2. 动态提示生成
class PromptGenerator:
def __init__(self):
self.templates = {
"formal": "尊敬的{title}{name},{content}",
"casual": "嗨,{name}!{content}",
"business": "亲爱的{title}{name}:\n\n{content}\n\n此致\n敬礼"
}
def generate_prompt(self, style, **kwargs):
"""根据场景生成合适的提示"""
if style not in self.templates:
raise ValueError(f"不支持的样式:{style}")
template = PromptTemplate.from_template(
self.templates[style]
)
return template.format(**kwargs)
# 使用示例
generator = PromptGenerator()
# 正式场合
formal_prompt = generator.generate_prompt(
"formal",
title="张",
name="总",
content="感谢您参加我们的年度会议。"
)
# 日常场合
casual_prompt = generator.generate_prompt(
"casual",
name="小明",
content="周末要不要一起打球?"
)
print("正式场合:")
print(formal_prompt)
print("\n日常场合:")
print(casual_prompt)
3. 提示模板管理
class PromptManager:
def __init__(self):
self._templates = {}
self._load_default_templates()
def _load_default_templates(self):
"""加载默认模板"""
self._templates = {
"translation": PromptTemplate.from_template(
"将以下{source_lang}文本翻译成{target_lang}:\n{text}"
),
"summary": PromptTemplate.from_template(
"用{length}字总结以下内容:\n{text}"
),
"analysis": PromptTemplate.from_template(
"从{aspect}角度分析以下内容:\n{text}"
)
}
def add_template(self, name, template):
"""添加新模板"""
if name in self._templates:
raise ValueError(f"模板 {name} 已存在")
self._templates[name] = template
def get_template(self, name):
"""获取模板"""
if name not in self._templates:
raise ValueError(f"模板 {name} 不存在")
return self._templates[name]
def list_templates(self):
"""列出所有可用模板"""
return list(self._templates.keys())
def format_prompt(self, template_name, **kwargs):
"""使用指定模板格式化提示"""
template = self.get_template(template_name)
return template.format(**kwargs)
# 使用示例
manager = PromptManager()
# 使用翻译模板
translation_prompt = manager.format_prompt(
"translation",
source_lang="中文",
target_lang="英文",
text="人工智能正在改变世界"
)
# 使用总结模板
summary_prompt = manager.format_prompt(
"summary",
length="100",
text="这是一段很长的文本..."
)
# 添加自定义模板
manager.add_template(
"email",
PromptTemplate.from_template(
"主题:{subject}\n收件人:{recipient}\n\n{content}"
)
)
# 列出所有模板
print("可用模板:", manager.list_templates())
最佳实践 ✨
1. 提示设计原则
- 明确性:清晰指定要求和期望
- 结构化:使用格式化的结构
- 示例性:提供具体的示例
- 可测试性:便于验证输出
2. 常见问题解决
- 输出不稳定:降低temperature值
- 格式不统一:使用结构化模板
- 内容不相关:加强上下文约束
- 质量不高:使用Few-Shot示例
3. 性能优化
- 模板缓存:重用常用模板
- 批量处理:合并相似请求
- 异步处理:并行处理多个请求
小结 📝
本章我们学习了:
- 提示工程的基础概念
- 各类提示模板的使用
- Few-Shot学习的应用
- 高级提示技巧和优化方法
关键点:
- 选择合适的模板类型
- 设计清晰的提示结构
- 使用示例提升质量
- 注意性能和可维护性
下一步:
- 实践不同类型的提示
- 优化提示模板
- 构建模板库
- 应用到实际项目