Prompt 工程基础 - 与 LLM 高效对话的技巧 / Prompt Engineering Fundamentals for Effective LLM Interaction
📅 创建时间:2026-04-28 🏷️ 标签:#Prompt #Few-shot #CoT #结构化输出 📚 前置知识:[[05 - 流式输出]]
📋 本章目标
- 理解 Prompt 的本质和作用
- 掌握 Zero-shot 和 Few-shot 的使用场景
- 理解 Chain-of-Thought (CoT) 思维链
- 学会使用结构化输出
- 了解 Prompt 工程的最佳实践和常见陷阱
第1部分:Prompt 的本质
1.1 什么是 Prompt?
Prompt = 给 LLM 的指令/问题
┌─────────────────────────────────────────────────────────────┐
│ Prompt 的构成 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Prompt = 指令(Instruction)+ 上下文(Context)+ 输入(Input)│
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 指令:完成什么任务 │ │
│ │ "将以下中文翻译成英文" │ │
│ │ │ │
│ │ 上下文:提供背景信息 │ │
│ │ "这是一封商务邮件" │ │
│ │ │ │
│ │ 输入:需要处理的具体内容 │ │
│ │ "请尽快完成这个项目" │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘1.2 Prompt vs 传统编程
传统编程:
输入 → [固定规则/代码] → 输出
↑
程序员写的代码决定一切LLM 编程(Prompt 工程):
输入 → [Prompt + 模型] → 输出
↑
Prompt 决定模型行为类比:
传统编程 = 给机器明确的"如果-那么"规则
Prompt工程 = 用自然语言"说服"模型按你的方式工作1.3 Prompt 的重要性
同一问题,不同 Prompt 的效果:
❌ 差劲的 Prompt:
"写代码"
→ 输出:可能生成任何代码,不一定是你想要的
✅ 好的 Prompt:
"用 Python 写一个函数,计算两个数的最大公约数(GCD)。
要求:
1. 使用欧几里得算法
2. 函数名叫 gcd
3. 有类型注解"
→ 输出:准确符合要求的代码第2部分:Zero-shot - 直接提问
2.1 什么是 Zero-shot?
Zero-shot = 不提供任何示例,直接提问
┌─────────────────────────────────────────────────────────────┐
│ Zero-shot 示意图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Prompt = 直接的问题或指令 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ "把'你好'翻译成英文" │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ 模型 │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ "Hello" │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 没有示例,只有指令 │
│ │
└─────────────────────────────────────────────────────────────┘2.2 Zero-shot 的适用场景
适合 Zero-shot 的任务:
1. 简单、明确的任务
• 翻译(语言是明确的)
• 格式转换(JSON ↔ YAML)
• 简单分类(正面/负面)
2. 常见任务
• 总结、解释、列举
• 这些任务有明确的模式
3. 任务本身足够清晰
• 不会产生歧义2.3 Zero-shot 示例
示例1:简单翻译
Prompt:将以下中文翻译成英文:我爱你
Output:I love you示例2:情感分类
Prompt:判断以下评论的情感是正面还是负面:
"这个产品太棒了,完全超出预期!"
Output:正面示例3:格式转换
Prompt:把以下内容转成JSON格式:
姓名:张三
年龄:25
职业:工程师
Output:
{
"name": "张三",
"age": 25,
"job": "工程师"
}2.4 Zero-shot 的局限性
不适用的场景:
1. 任务有特殊要求
• "翻译时要用正式语气"
• "分类时只有A/B/C三类"
2. 输出格式复杂
• 需要多步推理
• 有多个组成部分
3. 模型可能误解
• 任务有歧义
• 需要澄清需求第3部分:Few-shot - 提供示例
3.1 什么是 Few-shot?
Few-shot = 提供 1-N 个示例,让模型学习模式
┌─────────────────────────────────────────────────────────────┐
│ Few-shot 示意图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Prompt = 示例 + 新问题 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 示例1输入 → 示例1输出 │ │
│ │ 示例2输入 → 示例2输出 │ │
│ │ 示例3输入 → 示例3输出 │ │
│ │ ... │ │
│ │ 新问题(需要模型回答) │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ 模型 │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 预测新问题的输出 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘3.2 Few-shot vs Zero-shot
┌─────────────────────────────────────────────────────────────┐
│ 对比:Zero-shot vs Few-shot │
├─────────────────────────────────────────────────────────────┤
│ │
│ Zero-shot(无示例): │
│ Prompt:"把'我喜欢学习'翻译成英文" │
│ Output:I like studying │
│ │
│ Few-shot(有示例): │
│ Prompt: │
│ "翻译成英文: │
│ '早上好' → Good morning │
│ '晚安' → Good night │
│ '我喜欢学习' → ?" │
│ Output:I like learning │
│ │
│ 区别:示例帮助模型理解任务的"模式" │
│ │
└─────────────────────────────────────────────────────────────┘3.3 Few-shot 示例
示例1:翻译任务
Prompt:
将中文翻译成英文,注意使用正式语气:
示例:
"请问这个多少钱?" → "Could you please tell me the price?"
"能帮我一下吗?" → "Would you please help me?"
问题:
"这本书多少钱?"
Output:
"May I ask how much this book costs?"示例2:代码生成
Prompt:
把自然语言描述转成Python代码:
"计算1加1" → print(1 + 1)
"输出Hello World" → print("Hello World")
"求10除以2" → print(10 / 2)
"计算5乘以3"
Output:
print(5 * 3)示例3:复杂分类
Prompt:
判断文本的情感(正面/负面/中性):
"太棒了!完全超出预期!" → 正面
"还行吧,一般般" → 中性
"太差了,完全是浪费钱" → 负面
"服务态度很好,但是质量一般"
Output:
中性3.4 Few-shot 的数量选择
| 示例数量 | 适用场景 | 注意事项 |
|---|---|---|
| 1-2 个 | 简单任务、格式固定 | 避免歧义 |
| 3-5 个 | 中等复杂度 | 覆盖主要情况 |
| 5-10 个 | 复杂任务 | 太多会增加 Token 消耗 |
| 10+ 个 | 复杂模式 | 考虑用微调替代 |
3.5 Few-shot 的最佳实践
1. 示例要多样化
覆盖不同的输入-输出情况
2. 示例要一致
格式、风格、语言要统一
3. 示例要有代表性
不要用极端或特殊的情况
4. 放在 Prompt 的前面
System → Few-shot示例 → 新问题第4部分:Chain-of-Thought (CoT) - 思维链
4.1 什么是 CoT?
CoT = 让模型展示推理过程,而非直接给答案
┌─────────────────────────────────────────────────────────────┐
│ CoT 示意图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 普通问答: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Q: 小明有5个苹果,给了小红3个,还剩几个? │ │
│ │ A: 2个 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ CoT 问答: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Q: 小明有5个苹果,给了小红3个,还剩几个? │ │
│ │ A: 小明开始有5个苹果 │ │
│ │ 给出去3个 │ │
│ │ 所以还剩 5 - 3 = 2 个 │ │
│ │ 答案是2个 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 关键:展示"思考过程"而非直接给答案 │
│ │
└─────────────────────────────────────────────────────────────┘4.2 为什么要用 CoT?
原因1:复杂推理需要中间步骤
问题:鸡和兔子在一个笼子里,有35个头,94只脚,问有几只鸡几只兔?
直接回答:模型可能出错
CoT:
• 假设全是鸡:35 × 2 = 70 只脚
• 实际 94 只脚,多了 24 只
• 每只兔子比鸡多 2 只脚
• 所以兔子数 = 24 ÷ 2 = 12 只
• 鸡数 = 35 - 12 = 23 只原因2:验证推理过程
展示推理过程的好处:
1. 容易发现错误在哪一步
2. 可以针对性地纠正
3. 对用户更有参考价值4.3 Zero-shot CoT
只需加一句"思考一下":
prompt = """
问题:小明有10块钱,买了3块钱的橡皮,又买了5块钱的铅笔,还剩多少钱?
让我们一步步思考:
"""效果:
Output:
小明开始有10块钱
买了橡皮用了3块,还剩 10 - 3 = 7 块
买了铅笔用了5块,还剩 7 - 5 = 2 块
答案是还剩2块钱4.4 Few-shot CoT
提供完整推理示例:
prompt = """
请像数学老师一样,逐步推理并给出答案。
示例:
问题:书店有45本书,卖掉了12本,又进货20本,现在有多少本?
解答:原来有45本,卖掉12本后剩 45 - 12 = 33 本
又进货20本,现在有 33 + 20 = 53 本
答案:53本
问题:小华有8个球,小明给了小华5个球,小华丢掉3个球,现在有几个球?
解答:
"""4.5 CoT 的适用场景
| 适合 CoT | 不适合 CoT |
|---|---|
| 数学计算 | 简单翻译 |
| 逻辑推理 | 事实问答 |
| 代码调试 | 情感分类 |
| 复杂分析 | 列表列举 |
| 决策问题 | 直接回答 |
第5部分:结构化输出
5.1 什么是结构化输出?
结构化输出 = 用 XML/JSON 等格式约束输出
┌─────────────────────────────────────────────────────────────┐
│ 结构化输出示例 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 非结构化输出: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 人工智能是计算机科学的一个分支,企图了解智能的本质... │ │
│ └─────────────────────────────────────────────────────┘ │
│ 难以解析,可能格式不一致 │
│ │
│ 结构化输出(XML): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ <answer> │ │
│ │ <definition>人工智能是...</definition> │ │
│ │ <category>技术</category> │ │
│ │ <keywords>AI, 机器学习, 神经网络</keywords> │ │
│ │ </answer> │ │
│ └─────────────────────────────────────────────────────┘ │
│ 易于程序解析 │
│ │
│ 结构化输出(JSON): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ { │ │
│ │ "definition": "人工智能是...", │ │
│ │ "category": "技术", │ │
│ │ "keywords": ["AI", "机器学习", "神经网络"] │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘5.2 XML 标签包裹
示例:信息提取
prompt = """
从以下文本中提取信息,用XML格式输出:
文本:苹果公司成立于1976年,总部位于加州库比蒂诺,是全球领先的科技公司。
请按以下格式输出:
<information>
<company>公司名称</company>
<founded>成立年份</founded>
<location>总部位置</location>
<description>简要描述</description>
</information>
"""输出:
<information>
<company>苹果公司</company>
<founded>1976年</founded>
<location>加州库比蒂诺</location>
<description>全球领先的科技公司</description>
</information>5.3 JSON 格式
示例:评论分析
prompt = """
分析以下评论,输出JSON格式:
评论:"这个产品很好用,但是包装有点简陋"
JSON格式:
{
"sentiment": "positive" | "negative" | "neutral",
"pros": ["优点列表"],
"cons": ["缺点列表"],
"summary": "一句话总结"
}
"""输出:
{
"sentiment": "positive",
"pros": ["产品好用"],
"cons": ["包装简陋"],
"summary": "整体满意,但包装需改进"
}5.4 Markdown 表格
示例:对比分析
prompt = """
比较 Python 和 JavaScript,用表格输出:
| 特性 | Python | JavaScript |
|------|--------|------------|
| 类型系统 | ? | ? |
| 主要用途 | ? | ? |
| 运行环境 | ? | ? |
| 学习难度 | ? | ? |
"""5.5 结构化输出的好处
1. 易于程序解析
直接用 JSON.parse() 或 XML 解析器
2. 格式一致性
每次输出结构相同
3. 便于提取关键信息
不需要正则匹配
4. 减少解析错误
明确的数据边界第6部分:最佳实践与常见陷阱
6.1 最佳实践
1. 清晰明确的指令
❌ 模糊:"帮我处理这个"
✅ 明确:"从文本中提取所有邮箱地址,格式为JSON数组"2. 具体而非抽象
❌ 抽象:"回答要专业"
✅ 具体:"使用正式语言,避免口语化,每段不超过3句话"3. 使用分隔符
Prompt:
"""
请翻译以下内容:
---
中文:你好世界
---
翻译结果:
"""4. 渐进式要求
如果任务复杂,分步骤进行:
Step 1: 理解任务
Step 2: 执行任务
Step 3: 检查结果5. 预留检查空间
"请检查以下代码的错误,并给出修正建议"
"如果不确定,请说明'我不确定'"6.2 常见陷阱
陷阱1:信息过载
❌ 问题:Prompt 太长,包含太多不相关信息
✅ 解决:只包含与任务相关的信息陷阱2:矛盾指令
❌ 问题:前后指令矛盾
"回答要详细" + "回答要简洁"
✅ 解决:明确优先级,或分成两个任务陷阱3:隐含假设
❌ 问题:假设模型知道你的背景
"按我之前说的做"(但没提供上下文)
✅ 解决:每次都提供完整上下文陷阱4:过度依赖模型
❌ 问题:让模型做需要精确计算的事
"12345 × 67890 = ?"
✅ 解决:模型做推理,计算交给程序6.3 Prompt 模板库
模板1:翻译助手
TRANSLATION_PROMPT = """
你是一个专业翻译。请将{源语言}翻译成{目标语言}。
要求:
1. 翻译要地道,符合目标语言习惯
2. 保持原文的语气和风格
3. 对于专有名词,保留原文或使用通用译法
原文:
{text}
翻译结果:
"""模板2:代码审查
CODE_REVIEW_PROMPT = """
你是一个经验丰富的代码审查员。请审查以下代码:
审查要点:
1. 代码逻辑是否正确
2. 是否有潜在的bug或错误
3. 代码风格是否一致
4. 是否有性能问题
代码语言:{language}
代码:
```{language}
{code}审查结果: """
**模板3:总结助手**
```python
SUMMARY_PROMPT = """
请总结以下文章的核心内容:
要求:
1. 用3-5句话概括
2. 突出最重要的信息
3. 使用简洁易懂的语言
文章:
{article}
总结:
"""核心总结
总结1:Prompt 三要素
Prompt = 指令 + 上下文 + 输入
• 指令:做什么(必须明确)
• 上下文:背景信息(必要时提供)
• 输入:处理对象(具体内容)总结2:Zero-shot vs Few-shot vs CoT
| 方法 | 适用场景 | 示例数量 |
|---|---|---|
| Zero-shot | 简单明确任务 | 0 |
| Few-shot | 需要模式学习 | 1-10 |
| CoT | 复杂推理任务 | 0-5 |
总结3:结构化输出
XML:适合复杂层级结构
JSON:适合键值对结构
Markdown表格:适合对比分析总结4:好 Prompt 的标准
1. 清晰:明确告诉模型要做什么
2. 具体:避免歧义,具体要求
3. 完整:提供必要的上下文
4. 结构化:用分隔符、格式要求章节测试
测试1:Zero-shot 场景
以下哪个任务最适合用 Zero-shot? A. 翻译一段文字 B. 按特定格式写一首诗 C. 调试一段代码并解释每一步 D. 分析文本的情感并给出具体分数
测试2:Few-shot 选择
Few-shot 中应该提供多少个示例?
测试3:CoT 适用场景
以下哪个场景最适合使用 Chain-of-Thought? A. 把"你好"翻译成英文 B. 判断一句话是正面还是负面 C. 计算"25 × 17 = ?" D. 列举水果的名称
测试4:结构化输出
需要程序解析 LLM 输出时,应该使用什么格式?
测试5:Prompt 陷阱
以下哪个是典型的 Prompt 陷阱? A. 指令太模糊:"帮我处理" B. 提供足够的上下文 C. 使用清晰的分隔符 D. 分步骤说明任务
参考答案
测试1答案
答案:A(翻译一段文字)
解析:
A. 翻译:语言对应关系明确,不需要示例 ✓
B. 按特定格式写诗:需要示例说明格式要求
C. 调试代码并解释:需要示例说明解释风格
D. 给出具体分数:需要示例说明评分标准
翻译是最适合 Zero-shot 的任务之一
因为语言对应关系是通用的测试2答案
答案:通常 1-10 个,根据任务复杂度调整
解析:
Few-shot 示例数量选择指南:
• 1-2 个:简单任务,格式固定
• 3-5 个:中等复杂度
• 5-10 个:复杂模式
• 10+ 个:考虑用微调
注意事项:
• 不是越多越好
• 要多样化、有代表性
• 太多会增加 Token 消耗测试3答案
答案:C(计算 "25 × 17 = ?")
解析:
CoT 适合需要推理的任务:
• 数学计算 ✓ 需要一步步推理
• 简单翻译 ✗ 直接对应
• 情感判断 ✗ 直接分类
• 列举名称 ✗ 直接列举
计算 "25 × 17":
思考过程:
25 × 10 = 250
25 × 7 = 175
250 + 175 = 425
答案:425
CoT 展示了这个推理过程测试4答案
答案:JSON 或 XML
解析:
程序解析 LLM 输出,首选:
1. JSON:键值对结构,易于解析
2. XML:层级结构,标签明确
不建议:
• 纯文本:需要正则匹配,容易出错
• Markdown:格式可能不一致
JSON 示例:
{
"name": "张三",
"age": 25
}
可以用 JSON.parse() 直接解析测试5答案
答案:A(指令太模糊:"帮我处理")
解析:
典型的 Prompt 陷阱:
A. 模糊指令 ✓
"帮我处理" 完全没有说明要做什么
B. 提供上下文 ✓ 这是好的做法,不是陷阱
C. 使用分隔符 ✓ 这是好的做法,不是陷阱
D. 分步骤说明 ✓ 这是好的做法,不是陷阱
其他常见陷阱:
• 矛盾指令:"详细但简洁"
• 隐含假设:"按之前说的做"(但没提供之前内容)
• 信息过载:Prompt 太长太杂相关笔记
- [[04 - 消息角色]] - System 消息中的 Prompt 模板
- [[03 - 解码策略]] - Temperature 影响 Prompt 效果
- [[02 - Token 与上下文]] - Prompt 长度与 Token 消耗
下一步学习
- [ ] 阅读 07 - LLM 进化史
学习状态:✅ 已完成