Prompt Engineering 完整指南:从入门到精通
系统学习提示工程的核心技巧,掌握 Few-shot、Chain-of-Thought、ReAct 等高级 prompting 方法,提升 LLM 应用效果。
· 更新于 Mar 8, 2025
什么是 Prompt Engineering?
Prompt Engineering(提示工程)是设计和优化输入提示以获得 LLM 期望输出的技术。一个好的 prompt 可以显著提升模型的表现,在某些场景下甚至比模型本身更重要。
一、基础原则
1.1 清晰明确
❌ 不好的提示:
"写点东西"
✅ 好的提示:
"请撰写一篇 800 字的博客文章,主题是'人工智能在教育领域的应用'。要求:
- 包含 3 个实际案例
- 使用通俗易懂的语言
- 以教师为主要读者对象
- 结尾给出未来展望"
1.2 提供上下文
❌ 模糊的上下文:
"总结这篇文章"
✅ 清晰的上下文:
"你是一位专业的科技评论员。请阅读以下文章(关于 GPT-4 的技术报告),
然后写一份 300 字的摘要,突出技术亮点和创新点,语言风格要专业但易懂。"
1.3 指定输出格式
"请分析以下代码的复杂度:
- 使用大 O 表示法
- 说明时间复杂度和空间复杂度
- 如果有优化建议,一并提出
代码:
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)"
二、核心技巧
2.1 Role Prompting(角色扮演)
# 给 LLM 赋予特定角色
role_prompts = {
"teacher": "你是一位经验丰富的中文教师,擅长用生动的例子解释复杂概念。",
"coder": "你是一位资深软件工程师,遵循 Clean Code 原则,注重代码质量。",
"doctor": "你是一位三甲医院的主治医师,具有丰富的临床经验。",
"lawyer": "你是一位专业律师,熟悉中国法律法规,擅长法律文书写作。",
"copywriter": "你是一位广告文案策划,创意丰富,文笔优美。",
}
prompt = f"""{role_prompts['teacher']}
请用比喻的方式向小学生解释什么是光合作用。
要求:
1. 使用 2-3 个生活中的类比
2. 避免专业术语
3. 控制在 200 字以内"""
2.2 Few-shot Prompting(少样本提示)
few_shot_template = """
请将以下中文句子翻译成英文:
示例 1:
中文:我今天去了超市买了一袋苹果。
英文:I went to the supermarket today and bought a bag of apples.
示例 2:
中文:她的生日是下个星期五,我们打算给她一个惊喜派对。
英文:Her birthday is next Friday, and we plan to throw her a surprise party.
现在请翻译:
中文:{chinese_sentence}
英文:
"""
# 使用示例
prompt = few_shot_template.format(
chinese_sentence="这本书很有趣,我已经读了两遍了。"
)
2.3 Chain-of-Thought(思维链)
cot_prompt = """
问题:一个水池有两个水管。A 管单独注满需要 4 小时,B 管单独注满需要 6 小时。
如果两个水管同时打开,需要多长时间注满水池?
逐步思考:
1. A 管每小时注满 1/4 水池
2. B 管每小时注满 1/6 水池
3. 两管同时打开,每小时注满 1/4 + 1/6 = 3/12 + 2/12 = 5/12 水池
4. 注满整个水池需要 1 ÷ (5/12) = 12/5 = 2.4 小时
答案:2.4 小时(2 小时 24 分钟)
"""
# 引导模型模仿这种推理模式
question = "一辆车以 60km/h 的速度行驶 2 小时,然后又以 80km/h 的速度行驶 3 小时,总路程是多少?"
prompt = f"{cot_prompt}\n\n问题:{question}\n\n逐步思考:"
2.4 ReAct(Reasoning + Acting)
react_prompt = """
你是一个可以思考和行动的 AI 助手。遵循以下格式:
思考:分析问题,确定需要采取的行动
行动:调用工具 [工具名]
观察:工具返回的结果
...(重复以上步骤)
答案:最终答案
可用工具:
1. Search[query] - 搜索网络
2. Calculator[expression] - 计算表达式
3. Python[code] - 执行 Python 代码
问题:北京到上海的距离是多少?如果开车以平均 100km/h 的速度,需要多长时间?
开始:
"""
# 期望输出:
# 思考:需要知道北京到上海的距离,然后计算时间
# 行动:Search[北京到上海距离]
# 观察:约 1200 公里
# 思考:距离已知,计算时间 = 距离/速度
# 行动:Calculator[1200/100]
# 观察:12 小时
# 答案:约 12 小时
2.5 Instruction Following(指令遵循)
instruction_template = """
请严格遵循以下格式要求:
# 输入
{input}
# 输出格式
标题:[简短标题] 摘要:[2-3 行概述] 关键点:
- [关键点 1]
- [关键点 2]
- [关键点 3] 结论:[最终结论]
请严格按照上述格式输出,不要添加额外内容。
输入内容:
{content}
"""
三、高级技术
3.1 Self-Consistency(自一致性)
def self_consistency(question, n_samples=5):
"""多次采样,选择最一致的答案"""
responses = []
for _ in range(n_samples):
prompt = f"""
问题:{question}
请独立思考和回答,不要受到之前回答的影响。
"""
response = llm(prompt)
responses.append(extract_answer(response))
# 聚类并投票
most_common = Counter(responses).most_common(1)[0]
return most_common[0]
3.2 Tree of Thoughts(思维树)
# 在关键决策点生成多个推理路径
tot_prompt = """
问题:{problem}
步骤 1:列出至少 3 种不同的解决思路
思路:
1.
2.
3.
对于每种思路,请评估:
- 可行性
- 复杂度
- 潜在风险
然后选择最优方案并执行。
"""
3.3 Automatic Prompt Engineering
# 使用 LLM 自动优化 prompt
def optimize_prompt(task_description, initial_prompt, examples):
"""通过迭代优化 prompt"""
optimization_prompt = f"""
任务:{task_description}
当前 prompt:
{initial_prompt}
训练示例:
{format_examples(examples)}
问题:当前 prompt 在某些示例上表现不佳。
请分析失败的示例,并提出改进建议。
返回格式:
- 问题分析
- 修改建议
- 优化后的完整 prompt
"""
optimized = llm(optimization_prompt)
return extract_prompt(optimized)
四、领域特定 Prompt
4.1 代码生成
code_gen_prompt = """
你是一位资深 {language} 开发工程师。
要求:
1. 编写可运行的代码
2. 遵循 PEP8 / ESLint 等规范
3. 添加类型注解(TypeScript/Python)
4. 编写单元测试
5. 代码要有清晰注释
问题:
{problem_description}
请提供:
1. 完整实现
2. 使用示例
3. 复杂度分析
4. 可能的优化方向
"""
4.2 文本摘要
summarization_prompt = """
请对以下文本进行摘要:
[文本开始]
{document}
[文本结束]
摘要要求:
- 长度:原文的 20-30%
- 保留核心论点和关键数据
- 使用客观中立的语调
- 输出格式:段落形式
"""
4.3 情感分析
sentiment_prompt = """
分析以下文本的情感倾向:
文本:"{text}"
请按以下 JSON 格式输出:
{{
"sentiment": "positive/negative/neutral",
"confidence": 0.0-1.0,
"key_phrases": ["短语1", "短语2"],
"summary": "情感简述"
}}
"""
五、常见陷阱与解决方案
5.1 幻觉问题
# ❌ 容易引发幻觉
prompt = "介绍量子计算机的最新进展"
# ✅ 降低幻觉
prompt = """仅基于以下信息回答问题:
[提供的参考资料]
如果资料中未提及,请回答"无法从给定资料中找到相关信息"。
问题:[具体问题]
"""
5.2 指令忽略
# ❌ 模型可能忽略格式要求
prompt = "回答问题。输出 JSON。"
# ✅ 强化格式约束
prompt = """
你**必须**严格按照以下 JSON Schema 输出:
```json
{
"type": "object",
"properties": {
"answer": {"type": "string"},
"confidence": {"type": "number"}
},
"required": ["answer", "confidence"]
}
任何偏离此格式的回复都是错误的。 """
### 5.3 长度控制
```python
# 精确控制输出长度
prompt = """
请用 **恰好 3 句话** 总结以下文章。
文章:{content}
回复格式:
[第 1 句]
[第 2 句]
[第 3 句]
"""
六、Prompt 测试与评估
import pandas as pd
from sklearn.metrics import accuracy_score, rouge_score
def evaluate_prompt(prompt_template, test_cases):
"""评估 prompt 效果"""
results = []
for case in test_cases:
prompt = prompt_template.format(**case["input"])
response = llm(prompt)
score = calculate_metrics(response, case["expected"])
results.append({
"input": case["input"],
"expected": case["expected"],
"actual": response,
"score": score
})
df = pd.DataFrame(results)
print(f"平均得分: {df['score'].mean():.3f}")
return df
def calculate_metrics(prediction, ground_truth):
"""自定义评分函数"""
# BLEU、ROUGE、BERTScore 等
from rouge import Rouge
rouge = Rouge()
scores = rouge.get_scores(prediction, ground_truth)
return scores[0]["rouge-l"]["f"]
七、最佳实践清单
✅ 一定要做的事:
- 提供清晰的示例:如果可能,提供正例和反例
- 分解复杂任务:将大任务拆成小步骤
- 指定角色:给模型设定一个专业角色
- 定义输出格式:明确要求 JSON、列表、表格等结构
- 使用分隔符:用 ``` 或 --- 分隔不同部分
- 控制长度:明确字数或句子数要求
- 添加约束:如”不要编造”、“如果不确定请说明”
- 迭代测试:在小样本集上快速测试优化
- 记录版本:保存每次 prompt 及其效果
- 保持简洁:删除不必要的指令
❌ 避免做的事:
- 不要过度复杂:太多指令会让模型困惑
- 不要术语混用:保持术语一致性
- 不要模糊表述:避免”可能”、“也许”等词
- 不要忽视安全:添加安全过滤和检查机制
- 不要忽略用户画像:根据目标用户调整语气和深度
八、实用工具
# Prompt 模板管理
pip install promptlayer langsmith
# 版本追踪
pip install dvc
# 评估框架
pipackage evals openai
总结
Prompt Engineering 是一门实验科学,没有一成不变的”最佳 practice”。关键是:
- 理解模型特性:了解你使用的 LLM 的能力边界
- 持续迭代:通过 A/B 测试不断优化
- 记录实验:追踪每次修改的效果
- 领域适配:针对特定任务定制策略
记住:好的 prompt = 清晰的指令 + 丰富的示例 + 合理的约束
参考资源
- OpenAI Prompt Engineering Guide
- LangChain Prompt Templates
- “The Art of Asking ChatGPT for High-Quality Answers”