跳到主要内容

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 工程的核心技巧,接下来学习: