什么是 Prompt 工程?
Prompt 工程(Prompt Engineering)是设计和优化输入提示(Prompt)以引导大语言模型(LLM)产生期望输出的技术和方法。
┌─────────────────────────────────────────────────────────────┐
│ Prompt 工程的核心 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输入 (Prompt) 输出 (Response) │
│ ┌───────────────────┐ ┌───────────────────┐ │
│ │ 指令 │ │ │ │
│ │ 上下文 │ → │ LLM │ │
│ │ 示例 │ │ │ │
│ │ 格式要求 │ │ 生成结果 │ │
│ │ 约束条件 │ │ │ │
│ └───────────────────┘ └───────────────────┘ │
│ │
│ Prompt 工程 = 设计最优输入结构 + 优化输出质量 │
│ │
└─────────────────────────────────────────────────────────────┘
为什么 Prompt 工程重要?
- 成本效益:比微调模型成本低得多
- 快速迭代:无需重新训练即可优化
- 通用性强:适用于各种 LLM
- 效果可观:好的 Prompt 能显著提升输出质量
Prompt 的基本结构
1. 核心组件
# prompt_structure.py
class PromptComponents:
"""Prompt 核心组件"""
@staticmethod
def create_basic_prompt(
instruction: str,
context: str = "",
examples: list = None,
output_format: str = "",
constraints: list = None
) -> str:
"""创建基础 Prompt"""
prompt_parts = []
# 1. 指令(必需)
prompt_parts.append(f"指令:{instruction}")
# 2. 上下文(可选)
if context:
prompt_parts.append(f"\n背景信息:\n{context}")
# 3. 示例(可选)
if examples:
prompt_parts.append("\n示例:")
for i, example in enumerate(examples, 1):
prompt_parts.append(f"\n示例{i}:")
prompt_parts.append(f"输入:{example['input']}")
prompt_parts.append(f"输出:{example['output']}")
# 4. 输出格式(可选)
if output_format:
prompt_parts.append(f"\n输出格式:\n{output_format}")
# 5. 约束条件(可选)
if constraints:
prompt_parts.append("\n约束条件:")
for constraint in constraints:
prompt_parts.append(f"- {constraint}")
# 6. 实际输入
prompt_parts.append("\n现在请处理以下输入:")
return "\n".join(prompt_parts)
# 使用示例
prompt = PromptComponents.create_basic_prompt(
instruction="将以下中文文本翻译成英文",
context="这是一段技术文档",
examples=[
{
"input": "人工智能是计算机科学的一个分支",
"output": "Artificial intelligence is a branch of computer science"
}
],
output_format="只输出翻译结果,不要解释",
constraints=["保持专业术语准确", "语句通顺自然"]
)
print(prompt)
2. System Prompt
System Prompt 用于设定 AI 的角色和行为准则。
# system_prompt_examples.py
SYSTEM_PROMPTS = {
"technical_writer": """你是一位资深技术文档工程师。你的职责是:
- 将复杂的技术概念解释得清晰易懂
- 使用准确的技术术语
- 提供具体的代码示例
- 保持客观中立的语气
- 结构清晰,层次分明""",
"code_reviewer": """你是一位经验丰富的代码审查专家。请:
- 检查代码的正确性和效率
- 指出潜在的错误和风险
- 提供改进建议
- 关注代码可读性和维护性
- 遵循最佳实践""",
"creative_writer": """你是一位创意写作助手。请:
- 提供富有创意的想法
- 使用生动的语言
- 保持内容的原创性
- 根据用户需求调整风格
- 鼓励创新思维""",
"data_analyst": """你是一位数据分析师。请:
- 准确解读数据
- 提供数据驱动的见解
- 使用统计方法分析
- 可视化数据趋势
- 给出 actionable 的建议""",
}
def create_chat_prompt(system_prompt: str, user_message: str) -> list:
"""创建聊天格式的 Prompt"""
return [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message}
]
Zero-shot Learning
Zero-shot 是指不提供示例,直接让模型完成任务。
1. 基础 Zero-shot
# zero_shot_prompts.py
class ZeroShotPrompts:
"""Zero-shot Prompt 模板"""
@staticmethod
def classify_sentiment(text: str) -> str:
"""情感分类"""
return f"""分析以下文本的情感倾向(正面/负面/中性):
文本:{text}
情感:"""
@staticmethod
def extract_entities(text: str, entity_types: list) -> str:
"""实体抽取"""
return f"""从以下文本中提取指定的实体类型:{', '.join(entity_types)}
文本:{text}
请以 JSON 格式返回提取结果。"""
@staticmethod
def summarize(text: str, max_length: int = 100) -> str:
"""文本摘要"""
return f"""请对以下文本进行摘要,不超过{max_length}字:
{text}
摘要:"""
@staticmethod
def translate(text: str, target_lang: str) -> str:
"""文本翻译"""
return f"""将以下文本翻译成{target_lang}:
{text}
翻译结果:"""
@staticmethod
def generate_code(description: str, language: str) -> str:
"""代码生成"""
return f"""请用{language}编写代码实现以下功能:
功能描述:{description}
要求:
- 代码清晰易读
- 添加必要的注释
- 包含错误处理
- 遵循最佳实践
代码:"""
# 使用示例
prompt = ZeroShotPrompts.classify_sentiment(
"这款手机的电池续航太棒了,可以用一整天!"
)
2. 结构化 Zero-shot
# structured_zero_shot.py
def create_structured_prompt(task: str, input_data: dict, output_schema: dict) -> str:
"""创建结构化 Zero-shot Prompt"""
prompt = f"""任务:{task}
输入数据:
{json.dumps(input_data, indent=2, ensure_ascii=False)}
请按照以下 JSON Schema 格式输出结果:
{json.dumps(output_schema, indent=2)}
要求:
1. 严格遵循 Schema 格式
2. 所有字段必须填写
3. 不要添加额外说明
输出:"""
return prompt
# 使用示例
output_schema = {
"type": "object",
"properties": {
"product_name": {"type": "string"},
"category": {"type": "string"},
"price": {"type": "number"},
"features": {"type": "array", "items": {"type": "string"}},
"pros": {"type": "array", "items": {"type": "string"}},
"cons": {"type": "array", "items": {"type": "string"}}
},
"required": ["product_name", "category", "price", "features"]
}
prompt = create_structured_prompt(
task="分析产品信息",
input_data={"description": "iPhone 15 Pro,售价7999元,钛金属设计,A17 Pro芯片"},
output_schema=output_schema
)
Few-shot Learning
Few-shot 通过提供少量示例来引导模型理解任务模式。
1. 基础 Few-shot
# few_shot_prompts.py
class FewShotPrompts:
"""Few-shot Prompt 模板"""
@staticmethod
def create_prompt(
task_description: str,
examples: list,
test_input: str,
num_examples: int = 3
) -> str:
"""创建 Few-shot Prompt"""
prompt_parts = [f"任务:{task_description}\n"]
# 添加示例
for i, example in enumerate(examples[:num_examples], 1):
prompt_parts.append(f"示例{i}:")
prompt_parts.append(f"输入:{example['input']}")
prompt_parts.append(f"输出:{example['output']}\n")
# 添加测试输入
prompt_parts.append("现在请处理:")
prompt_parts.append(f"输入:{test_input}")
prompt_parts.append("输出:")
return "\n".join(prompt_parts)
# 情感分析 Few-shot
sentiment_examples = [
{
"input": "这部电影太精彩了,强烈推荐!",
"output": "正面"
},
{
"input": "服务态度很差,等了一个小时",
"output": "负面"
},
{
"input": "今天天气不错",
"output": "中性"
}
]
prompt = FewShotPrompts.create_prompt(
task_description="判断文本的情感倾向(正面/负面/中性)",
examples=sentiment_examples,
test_input="这个产品的质量超出预期,性价比很高"
)
2. 多样本 Few-shot
# diverse_few_shot.py
def create_diverse_few_shot(
task: str,
examples: list,
test_input: str
) -> str:
"""创建多样化的 Few-shot Prompt"""
# 按类别组织示例
categories = {}
for ex in examples:
cat = ex.get("category", "default")
if cat not in categories:
categories[cat] = []
categories[cat].append(ex)
prompt_parts = [f"任务:{task}\n"]
prompt_parts.append("以下是不同类型的示例:\n")
for category, cat_examples in categories.items():
prompt_parts.append(f"\n【{category}类型】")
for i, ex in enumerate(cat_examples[:2], 1):
prompt_parts.append(f"示例{i}:")
prompt_parts.append(f"输入:{ex['input']}")
prompt_parts.append(f"输出:{ex['output']}")
prompt_parts.append(f"\n现在请处理:")
prompt_parts.append(f"输入:{test_input}")
prompt_parts.append("输出:")
return "\n".join(prompt_parts)
# 文本转换任务示例
text_transform_examples = [
{
"input": "把这段文字改写成正式的商业邮件",
"output": "尊敬的合作伙伴:\n\n您好!关于我们之前讨论的合作事宜...",
"category": "正式化"
},
{
"input": "用简洁的方式总结这段内容",
"output": "核心要点:1. 提高效率 2. 降低成本 3. 改善体验",
"category": "简化"
},
{
"input": "把技术文档改写成通俗易懂的说明",
"output": "简单来说,这个功能就像是...",
"category": "通俗化"
}
]
3. 动态 Few-shot
# dynamic_few_shot.py
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
class DynamicFewShot:
"""动态选择示例的 Few-shot"""
def __init__(self, examples: list):
self.examples = examples
self.vectorizer = TfidfVectorizer()
# 预计算示例的向量
example_texts = [ex['input'] for ex in examples]
self.example_vectors = self.vectorizer.fit_transform(example_texts)
def get_similar_examples(self, query: str, k: int = 3) -> list:
"""获取与查询最相似的 k 个示例"""
# 计算查询的向量
query_vector = self.vectorizer.transform([query])
# 计算相似度
similarities = cosine_similarity(
query_vector,
self.example_vectors
).flatten()
# 获取最相似的 k 个索引
top_k_indices = np.argsort(similarities)[-k:][::-1]
return [self.examples[i] for i in top_k_indices]
def create_prompt(self, task: str, query: str, k: int = 3) -> str:
"""创建动态 Few-shot Prompt"""
similar_examples = self.get_similar_examples(query, k)
prompt_parts = [f"任务:{task}\n"]
for i, example in enumerate(similar_examples, 1):
prompt_parts.append(f"\n相似示例{i}:")
prompt_parts.append(f"输入:{example['input']}")
prompt_parts.append(f"输出:{example['output']}")
prompt_parts.append(f"\n现在请处理:")
prompt_parts.append(f"输入:{query}")
prompt_parts.append("输出:")
return "\n".join(prompt_parts)
# 使用示例
all_examples = [
{"input": "帮我写一封请假邮件", "output": "..."},
{"input": "写一封商务合作邮件", "output": "..."},
# ... 更多示例
]
dynamic_fs = DynamicFewShot(all_examples)
prompt = dynamic_fs.create_prompt(
task="撰写专业邮件",
query="帮我写一封辞职邮件"
)
Prompt 设计原则
1. 清晰性原则
# clarity_principles.py
BAD_PROMPT = "写点东西"
GOOD_PROMPT = """请撰写一篇关于人工智能在医疗领域应用的技术博客文章。
要求:
- 字数:1000-1500字
- 结构:引言、3个应用案例、未来展望、结论
- 风格:专业但易懂,适合技术人员阅读
- 包含:具体的应用场景和数据支持"""
2. 具体性原则
# specificity_principles.py
VAGUE_PROMPT = "分析这段代码"
SPECIFIC_PROMPT = """请对以下 Python 函数进行代码审查:
```python
def calculate_average(numbers):
total = sum(numbers)
return total / len(numbers)
请从以下维度分析:
- 正确性:是否存在逻辑错误
- 健壮性:是否处理了边界情况
- 效率:时间复杂度和空间复杂度
- 可读性:命名和结构是否清晰
- 改进建议:具体的优化方案"""
### 3. 一致性原则
```python
# consistency_principles.py
CONSISTENT_PROMPT = """将以下句子翻译成法语。保持格式一致:
示例:
英文:Hello, how are you?
法文:Bonjour, comment allez-vous?
英文:{input}
法文:"""
常见任务模板
1. 文本分类
# classification_template.py
CLASSIFICATION_TEMPLATE = """请对以下文本进行分类。
分类类别:{categories}
示例:
{examples}
待分类文本:{text}
分类结果(只输出类别名称):"""
# 使用示例
classification_prompt = CLASSIFICATION_TEMPLATE.format(
categories="科技、体育、娱乐、政治、经济",
examples="""
文本:苹果公司发布新款iPhone
类别:科技
文本:湖人队赢得总冠军
类别:体育
""",
text="特斯拉股价创新高"
)
2. 信息抽取
# extraction_template.py
EXTRACTION_TEMPLATE = """从以下文本中提取指定信息。
需要提取的字段:{fields}
示例:
文本:张三,电话:13800138000,邮箱:zhangsan@example.com
提取结果:
{example_output}
待处理文本:{text}
请以 JSON 格式输出提取结果:"""
# 使用示例
extraction_prompt = EXTRACTION_TEMPLATE.format(
fields="姓名、电话、邮箱、地址",
example_output='{"姓名": "张三", "电话": "13800138000", "邮箱": "zhangsan@example.com"}',
text="李四,联系方式:13900139000,li si@company.com,地址:北京市海淀区"
)
3. 问答生成
# qa_template.py
QA_TEMPLATE = """基于以下上下文,回答问题。
上下文:
{context}
问题:{question}
请根据上下文提供准确的答案。如果上下文中没有相关信息,请回答"根据提供的信息无法回答"。
答案:"""
Prompt 优化技巧
1. 迭代优化
# iterative_optimization.py
def iterative_prompt_refinement(
initial_prompt: str,
test_cases: list,
max_iterations: int = 5
) -> str:
"""迭代优化 Prompt"""
prompt = initial_prompt
for iteration in range(max_iterations):
print(f"\n迭代 {iteration + 1}:")
# 测试当前 Prompt
results = []
for test_case in test_cases:
# 这里调用 LLM
# result = llm.generate(prompt.format(**test_case['input']))
# results.append(result)
pass
# 评估结果
# score = evaluate_results(results, [tc['expected'] for tc in test_cases])
# 根据评估结果优化 Prompt
# prompt = refine_prompt(prompt, results)
print(f"当前 Prompt:\n{prompt}\n")
return prompt
2. A/B 测试
# ab_testing.py
import random
def ab_test_prompts(
prompt_a: str,
prompt_b: str,
test_cases: list,
evaluation_func
) -> dict:
"""A/B 测试两个 Prompt"""
results = {
"A": {"scores": [], "examples": []},
"B": {"scores": [], "examples": []}
}
for test_case in test_cases:
# 随机分配
variant = random.choice(["A", "B"])
prompt = prompt_a if variant == "A" else prompt_b
# 生成结果
# output = llm.generate(prompt.format(**test_case['input']))
# 评估
# score = evaluation_func(output, test_case['expected'])
# results[variant]["scores"].append(score)
# results[variant]["examples"].append({
# "input": test_case['input'],
# "output": output,
# "expected": test_case['expected']
# })
# 计算平均得分
results["A"]["avg_score"] = sum(results["A"]["scores"]) / len(results["A"]["scores"])
results["B"]["avg_score"] = sum(results["B"]["scores"]) / len(results["B"]["scores"])
return results
最佳实践总结
Prompt 设计检查清单
- 明确任务:清楚地描述需要模型做什么
- 提供上下文:给出必要的背景信息
- 使用示例:Few-shot 比 Zero-shot 更稳定
- 指定格式:明确输出的结构和格式
- 添加约束:说明限制条件和要求
- 测试验证:用多个案例测试 Prompt 效果
- 迭代优化:根据结果持续改进
常见错误
- 过于模糊:“写点东西” → “写一篇关于 X 的 Y 字文章”
- 缺乏示例:直接要求复杂任务而不给示例
- 忽略边界:没有说明异常情况的处理
- 格式混乱:输出格式要求不清晰
- 过度复杂:Prompt 过长,重点不突出
相关资源: