Prompt 工程
Prompt 工程是构建有效 LLM 应用的核心技能。本章将详细介绍如何在 LangChain 中设计和优化提示词。
什么是 Prompt?
Prompt(提示词) 是输入给 LLM 的文本内容,它告诉模型要做什么、怎么做。一个好的 Prompt 能够显著提升模型的输出质量。
Prompt 的组成
通常一个完整的 Prompt 包含:
系统提示词(System Prompt):设定AI的角色、行为规范
│
└─ 用户提示词(User Prompt):具体的任务要求
LangChain Prompt 组件
1. PromptTemplate
用于创建可复用的提示词模板:
from langchain.prompts import PromptTemplate
# 创建模板
template = PromptTemplate.from_template(
"请用{language}编写一个函数,实现{function_name}功能"
)
# 使用模板
prompt = template.format(
language="Python",
function_name="冒泡排序"
)
print(prompt)
输出:
请用Python编写一个函数,实现冒泡排序功能
2. ChatPromptTemplate
用于聊天模型的结构化提示词:
from langchain.prompts import ChatPromptTemplate
# 创建聊天模板
template = ChatPromptTemplate.from_messages([
("system", "你是一个专业的{field}专家"),
("user", "请解释{concept}是什么"),
("assistant", "好的,我来解释..."),
("user", "那么{application}场景中如何使用?")
])
# 使用模板
prompt = template.format(
field="编程",
concept="装饰器",
application="Web开发"
)
3. MessagesPlaceholder
用于动态插入消息列表:
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.schema import HumanMessage, SystemMessage
template = ChatPromptTemplate.from_messages([
SystemMessage(content="你是一个有帮助的助手"),
MessagesPlaceholder(variable_name="chat_history", optional=True),
HumanMessage(content="{question}")
])
# 使用模板
prompt = template.format(
chat_history=[
HumanMessage(content="什么是Python?"),
("assistant", "Python是一种高级编程语言")
],
question="它有什么特点?"
)
Prompt 设计原则
1. 明确任务
# ❌ 不够明确
template1 = PromptTemplate.from_template("解释{topic}")
# ✅ 明确具体
template2 = PromptTemplate.from_template("""
作为Python编程专家,请解释{topic}:
1. 基本定义
2. 核心概念
3. 使用场景
4. 代码示例
请用易懂的语言解释,适合初学者理解
""")
2. 提供上下文
# ❌ 缺少上下文
template1 = PromptTemplate.from_template("写一个函数")
# ✅ 提供上下文
template2 = PromptTemplate.from_template("""
背景:在一个数据处理系统中,需要对大量数值进行统计分析
任务:编写一个Python函数,计算给定数值列表的:
1. 平均值
2. 中位数
3. 标准差
请提供完整的实现代码和说明
""")
3. 使用格式指令
# 添加格式指令
template = PromptTemplate.from_template("""
请分析以下数据:{data}
请按以下JSON格式输出结果:
{{
"平均值": <数值>,
"最大值": <数值>,
"最小值": <数值>,
"分析结论": "<一句话总结>"
}}
""")
4. Few-shot 学习
通过示例帮助模型理解任务:
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector
# 定义示例
examples = [
{"input": "苹果", "output": "水果"},
{"input": "胡萝卜", "output": "蔬菜"},
{"input": "牛肉", "output": "肉类"},
]
# 创建示例选择器
example_selector = LengthBasedExampleSelector(
examples=examples,
prompt_template=PromptTemplate.from_template("输入: {input}\n输出: {output}"),
max_length=100,
)
# 创建 Few-shot 模板
prompt_template = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=PromptTemplate.from_template("输入: {input}\n输出: {output}"),
prefix="请根据以下示例,将输入分类:",
suffix="输入: {word}\n输出:",
input_variables=["word"],
)
# 使用
prompt = prompt_template.format(word="鸡蛋")
print(prompt)
高级技巧
1. 链式 Prompt
将复杂任务分解为多个步骤:
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 步骤1:分析问题
step1_template = ChatPromptTemplate.from_template("""
分析以下问题,确定需要哪些信息:
{question}
""")
# 步骤2:生成回答
step2_template = ChatPromptTemplate.from_template("""
基于以下分析,回答原始问题:
分析:{analysis}
原始问题:{question}
请给出详细回答
""")
# 执行步骤
analysis = model.invoke(step1_template.format(question="如何学习Python?"))
print(f"分析结果: {analysis.content}")
response = model.invoke(step2_template.format(
analysis=analysis.content,
question="如何学习Python?"
))
print(f"最终回答: {response.content}")
2. 输出解析
指定输出的结构化格式:
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
# 定义输出结构
class Recipe(BaseModel):
name: str = Field(description="菜名")
ingredients: list[str] = Field(description="食材列表")
steps: list[str] = Field(description="烹饪步骤")
# 创建解析器
parser = PydanticOutputParser(pydantic_object=Recipe)
# 创建模板
template = ChatPromptTemplate.from_template("""
请提供一个简单菜谱的JSON格式:
{format_instructions}
菜谱要求:简单易做,适合初学者
""")
# 使用模板(包含格式指令)
prompt = template.format(format_instructions=parser.get_format_instructions())
# 调用模型
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
response = model.invoke(prompt)
# 解析输出
recipe = parser.parse(response.content)
print(f"菜名: {recipe.name}")
print(f"食材: {recipe.ingredients}")
3. 自定义指令
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate
# 定义系统消息
system_message = SystemMessagePromptTemplate.from_template("""
你是一个专业的编程助手,擅长解释技术概念。
回答规则:
1. 用通俗易懂的语言解释
2. 提供代码示例
3. 指出常见误区
4. 保持友好、耐心的语气
回答格式:
- 先给出简单定义
- 再详细解释
- 最后给出示例
""")
# 创建完整模板
template = ChatPromptTemplate.from_messages([
system_message,
HumanMessagePromptTemplate.from_template("{topic}是什么?")
])
4. 条件分支
from langchain.prompts import ChatPromptTemplate
template = ChatPromptTemplate.from_template("""
任务:{task_type}
{#if equals(task_type, "解释")#}
请用通俗易懂的语言解释以下概念:{concept}
{#else if equals(task_type, "代码")#}
请提供实现以下功能的Python代码:{concept}
{#else if equals(task_type, "对比")#}
请对比分析以下两个概念:{concept}
{#/if#}
""")
最佳实践
1. 系统提示词
# 好的系统提示词
system_template = """
你是 {role},一个专业、友好的AI助手。
核心原则:
- {principle1}
- {principle2}
回答风格:
- 简洁明了
- 使用易懂的语言
- 适当使用例子
注意:
- 不知道的问题如实说不知道
- 避免过度确定性的表述
"""
2. 用户提示词
# 好的用户提示词
user_template = """
背景:{background}
任务:{task}
要求:
1. {requirement1}
2. {requirement2}
约束:
- {constraint}
请开始执行
"""
3. 提示词版本管理
# 使用版本号
PROMPTS = {
"v1": "原始提示词...",
"v2": "改进后的提示词...",
"v3": "添加了上下文...",
}
# A/B 测试
def test_prompt(prompt_version, test_cases):
results = []
for case in test_cases:
prompt = PROMPTS[prompt_version].format(**case)
response = model.invoke(prompt)
results.append({
"prompt": prompt,
"response": response.content,
"expected": case["expected"]
})
return results
在 LangChain 中使用
完整示例
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate, SystemMessage, HumanMessage
# 初始化模型
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 创建提示词模板
prompt = ChatPromptTemplate.from_messages([
SystemMessage(content="""你是一个Python编程助手。
你的特点是:
1. 回答简洁准确
2. 提供代码示例
3. 指出注意事项
"""),
HumanMessage(content="""请解释Python中的装饰器是什么?
要求:
1. 用通俗语言解释
2. 提供一个实际使用例子
3. 说明使用场景
""")
])
# 生成提示词
formatted_prompt = prompt.format()
print("生成的提示词:")
print(formatted_prompt)
# 调用模型
response = model.invoke(formatted_prompt)
print("\n模型响应:")
print(response.content)
使用 LCEL
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 使用 LCEL 组合
chain = (
{"topic": lambda x: x["topic"]}
| ChatPromptTemplate.from_template("请解释{topic}并提供示例")
| model
)
# 调用
result = chain.invoke({"topic": "Python生成器"})
print(result.content)
常见问题
1. Prompt 不起作用
- 检查是否有语法错误
- 确认模型是否正确理解了指令
- 尝试更明确、更具体的描述
2. 输出格式错误
- 使用 Pydantic 等解析器强制约束输出
- 提供更多示例(Few-shot)
- 在 Prompt 中包含更多格式说明
3. 模型忽略指令
- 将重要指令放在 Prompt 开头
- 使用强调词("非常重要"、"必须"等)
- 避免与系统提示词冲突
下一步
现在你已经掌握了 Prompt 工程的核心技巧,接下来学习: