Skip to content

第16天:Prompt Engineering

学习目标

  • 理解Prompt Engineering的核心原理
  • 掌握Prompt设计的基本原则
  • 掌握Few-shot Learning
  • 掌握CoT(Chain of Thought)
  • 能够优化Prompt提升任务效果

课程内容

1. Prompt Engineering基础

1.1 什么是Prompt Engineering

定义

  • Prompt Engineering是设计和优化输入提示的技术
  • 目的是引导LLM生成期望的输出
  • 是提升LLM性能的关键技术

核心思想

好的Prompt = 清晰的指令 + 充足的上下文 + 合适的格式

1.2 Prompt的基本结构

标准结构

1. 系统提示(System Prompt)
2. 用户指令(User Instruction)
3. 上下文信息(Context)
4. 示例(Examples)
5. 输出格式(Output Format)

示例

python
prompt = """
你是一个专业的Python编程助手。

请帮我写一个快速排序算法。

要求:
1. 使用Python语言
2. 添加详细注释
3. 包含测试代码

输出格式:
```python
# 你的代码

"""


#### 1.3 Prompt设计原则

**原则1:清晰明确**
```python
# 不好的Prompt
prompt = "写个排序"

# 好的Prompt
prompt = """
请用Python写一个快速排序算法,要求:
1. 使用递归实现
2. 添加详细注释
3. 包含时间复杂度分析
"""

原则2:提供上下文

python
# 不好的Prompt
prompt = "解释这个代码"

# 好的Prompt
prompt = """
请解释以下Python代码的功能和工作原理:

```python
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

请从以下几个方面解释:

  1. 算法名称
  2. 工作原理
  3. 时间复杂度
  4. 空间复杂度 """

**原则3:指定输出格式**
```python
# 不好的Prompt
prompt = "分析这段文本"

# 好的Prompt
prompt = """
请分析以下文本,并以JSON格式输出结果:

文本:人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。

输出格式:
{
    "主题": "文本主题",
    "关键词": ["关键词1", "关键词2"],
    "情感": "正面/负面/中性",
    "摘要": "文本摘要"
}
"""

原则4:使用分隔符

python
# 使用分隔符区分不同部分
prompt = """
系统提示:
你是一个专业的文本分析助手。

用户指令:
请分析以下文本。

文本:
---
人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。

---

输出格式:
---
JSON格式
---
"""

2. Few-shot Learning

2.1 什么是Few-shot Learning

定义

  • Few-shot Learning是提供少量示例来引导模型学习
  • 相比Zero-shot(无示例),Few-shot通常效果更好
  • 示例数量通常在1-10个之间

2.2 Few-shot Prompt设计

示例1:文本分类

python
prompt = """
你是一个文本分类助手。请根据文本内容判断其类别。

示例:
文本:今天天气真好,阳光明媚。
类别:正面

文本:这个产品太差了,完全不值得购买。
类别:负面

文本:这部电影还可以,不算太好也不算太差。
类别:中性

现在请分类以下文本:
文本:这家餐厅的菜品味道不错,服务也很好。
类别:
"""

示例2:情感分析

python
prompt = """
你是一个情感分析助手。请判断文本的情感倾向。

示例:
输入:我非常喜欢这个产品,它超出了我的预期!
输出:正面

输入:这个服务太糟糕了,我等了两个小时都没解决问题。
输出:负面

输入:这个产品还可以,价格合理,质量一般。
输出:中性

现在请分析:
输入:这个手机的外观设计很漂亮,但是电池续航不太理想。
输出:
"""

示例3:命名实体识别

python
prompt = """
你是一个命名实体识别助手。请从文本中提取人名、地名、组织名等实体。

示例:
输入:苹果公司的CEO蒂姆·库克访问了北京。
输出:
人名:蒂姆·库克
组织:苹果公司
地名:北京

输入:马云在杭州创立了阿里巴巴集团。
输出:
人名:马云
组织:阿里巴巴集团
地名:杭州

现在请识别:
输入:马斯克在纽约宣布成立SpaceX公司。
输出:
"""

2.3 Few-shot最佳实践

最佳实践1:示例多样化

python
# 好的Prompt(示例多样化)
prompt = """
你是一个文本分类助手。

示例:
文本:今天天气真好!
类别:正面

文本:这个产品太差了。
类别:负面

文本:这部电影还可以。
类别:中性

文本:我对这个服务非常满意。
类别:正面

文本:完全浪费我的时间。
类别:负面

文本:没什么特别的。
类别:中性

现在请分类:
文本:这个餐厅的菜品味道不错。
类别:
"""

最佳实践2:示例质量

python
# 好的Prompt(高质量示例)
prompt = """
你是一个代码生成助手。请根据需求生成代码。

示例:
需求:写一个函数计算两个数的和
代码:
def add(a, b):
    """
    计算两个数的和
    
    Args:
        a: 第一个数
        b: 第二个数
    
    Returns:
        两个数的和
    """
    return a + b

需求:写一个函数计算列表的平均值
代码:
def average(lst):
    """
    计算列表的平均值
    
    Args:
        lst: 数字列表
    
    Returns:
        平均值
    """
    if not lst:
        return 0
    return sum(lst) / len(lst)

现在请生成:
需求:写一个函数判断一个数是否为质数
代码:
"""

最佳实践3:示例顺序

python
# 好的Prompt(从简单到复杂)
prompt = """
你是一个数学问题解决助手。

示例:
问题:1 + 1 = ?
答案:2

问题:5 × 6 = ?
答案:30

问题:15 ÷ 3 = ?
答案:5

问题:如果一个三角形的底是6,高是4,面积是多少?
答案:三角形的面积公式是 (底 × 高) / 2
所以面积 = (6 × 4) / 2 = 12

现在请解决:
问题:一个长方形的长是8,宽是5,周长是多少?
答案:
"""

3. Chain of Thought(CoT)

3.1 什么是CoT

定义

  • CoT(Chain of Thought)是让模型逐步推理的技术
  • 通过展示推理过程,提高复杂任务的准确性
  • 特别适合数学、逻辑推理等任务

3.2 CoT Prompt设计

示例1:数学推理

python
prompt = """
你是一个数学问题解决助手。请逐步推理并给出答案。

示例:
问题:一个商店卖苹果,3个苹果5元,12个苹果多少钱?

推理过程:
1. 首先计算1个苹果的价格:5元 ÷ 3 = 1.67元
2. 然后计算12个苹果的价格:1.67元 × 12 = 20.04元
3. 所以12个苹果大约是20元

答案:20元

现在请解决:
问题:一个工厂生产零件,8小时生产96个零件,12小时能生产多少个零件?

推理过程:
"""

示例2:逻辑推理

python
prompt = """
你是一个逻辑推理助手。请逐步推理并给出结论。

示例:
问题:如果所有的猫都是动物,而且Tom是一只猫,那么Tom是动物吗?

推理过程:
1. 前提1:所有的猫都是动物
2. 前提2:Tom是一只猫
3. 结论:根据前提1和前提2,Tom属于猫的类别,而猫属于动物,因此Tom是动物

答案:是的,Tom是动物

现在请推理:
问题:如果所有的程序员都懂Python,而且Alice是一个程序员,那么Alice懂Python吗?

推理过程:
"""

示例3:代码调试

python
prompt = """
你是一个代码调试助手。请逐步分析代码问题并给出解决方案。

示例:
问题:以下代码为什么不能正确计算平均值?

```python
def average(lst):
    return sum(lst) / len(lst)

测试数据:average([])

推理过程:

  1. 分析代码:代码计算列表的总和除以列表长度
  2. 分析问题:当列表为空时,len(lst) = 0,导致除以零错误
  3. 解决方案:添加空列表检查

修正代码:

python
def average(lst):
    if not lst:
        return 0
    return sum(lst) / len(lst)

现在请调试: 问题:以下代码为什么不能正确反转列表?

python
def reverse_list(lst):
    result = []
    for i in range(len(lst)):
        result.append(lst[i])
    return result

推理过程: """


#### 3.3 CoT最佳实践

**最佳实践1:明确要求推理过程**
```python
# 好的Prompt
prompt = """
你是一个数学问题解决助手。

重要:请逐步展示你的推理过程,不要直接给出答案。

示例:
问题:一个农场有鸡和兔子共20只,共有56条腿,鸡和兔子各有多少只?

推理过程:
1. 设鸡有x只,兔子有y只
2. 根据题意:x + y = 20
3. 鸡有2条腿,兔子有4条腿:2x + 4y = 56
4. 从第一个方程:x = 20 - y
5. 代入第二个方程:2(20 - y) + 4y = 56
6. 展开:40 - 2y + 4y = 56
7. 简化:40 + 2y = 56
8. 解方程:2y = 16,y = 8
9. 所以兔子有8只,鸡有12只

答案:鸡12只,兔子8只

现在请解决:
问题:一个班级有30个学生,男生比女生多4人,男生和女生各有多少人?

推理过程:
"""

最佳实践2:使用思维链标记

python
# 好的Prompt
prompt = """
你是一个逻辑推理助手。请使用思维链逐步推理。

思维链格式:
<思考>
步骤1:...
步骤2:...
步骤3:...
</思考>

<答案>
最终答案
</答案>

示例:
问题:如果今天是星期三,那么100天后是星期几?

<思考>
步骤1:一周有7天
步骤2:计算100天包含多少周:100 ÷ 7 = 14周余2天
步骤3:14周后还是星期三
步骤4:再过2天:星期三 + 2天 = 星期五
</思考>

<答案>
星期五
</答案>

现在请推理:
问题:如果现在是上午10点,那么500小时后是几点?

<思考>
"""

最佳实践3:分步骤提示

python
# 好的Prompt
prompt = """
你是一个复杂问题解决助手。请按照以下步骤解决问题:

步骤1:理解问题
- 明确问题的要求
- 识别已知条件
- 确定求解目标

步骤2:分析问题
- 找出关键信息
- 确定解题思路
- 选择合适的方法

步骤3:解决问题
- 逐步计算或推理
- 检查中间结果
- 验证最终答案

示例:
问题:一个水池有两个进水管和一个出水管。单独打开A管,6小时注满;单独打开B管,8小时注满;单独打开C管,12小时放空。如果同时打开三管,多久注满水池?

步骤1:理解问题
- 目标:计算三管同时打开的注满时间
- 已知:A管6小时注满,B管8小时注满,C管12小时放空

步骤2:分析问题
- A管速度:1/6(每小时注满比例)
- B管速度:1/8
- C管速度:-1/12(放空)
- 合并速度:1/6 + 1/8 - 1/12

步骤3:解决问题
- 合并速度 = 4/24 + 3/24 - 2/24 = 5/24
- 注满时间 = 1 ÷ (5/24) = 24/5 = 4.8小时

答案:4.8小时

现在请解决:
问题:甲、乙两人合作完成一项工作,甲单独做需要10天,乙单独做需要15天。如果甲先做2天,然后两人合作,还需要多少天完成?

步骤1:理解问题
"""

4. 高级Prompt技巧

4.1 角色扮演

python
prompt = """
你现在是一位经验丰富的Python编程专家,拥有10年的开发经验。

你的特点:
1. 代码风格优雅、高效
2. 注释详细清晰
3. 考虑边界情况
4. 遵循Python最佳实践

请根据以下需求编写代码:

需求:实现一个LRU缓存

要求:
1. 使用OrderedDict实现
2. 包含get和put方法
3. 缓存容量可配置
4. 自动淘汰最近最少使用的项
"""

4.2 思维树(Tree of Thoughts)

python
prompt = """
你是一个复杂问题解决助手。请使用思维树方法解决问题。

思维树方法:
1. 生成多个可能的解决方案
2. 评估每个方案的优缺点
3. 选择最佳方案
4. 详细说明理由

示例:
问题:如何提高网站的性能?

方案1:优化数据库查询
- 优点:直接有效,成本低
- 缺点:提升空间有限
- 适用:数据库是瓶颈的情况

方案2:使用CDN加速
- 优点:显著提升静态资源加载速度
- 缺点:需要额外成本
- 适用:静态资源多的情况

方案3:增加服务器数量
- 优点:提升并发能力
- 缺点:成本高,维护复杂
- 适用:高并发的情况

最佳方案:方案2(CDN)
理由:大多数网站的性能瓶颈在于静态资源加载,CDN成本低且效果显著。

现在请解决:
问题:如何提高代码质量?

方案1:
"""

4.3 自我反思

python
prompt = """
你是一个自我反思的AI助手。请按照以下步骤回答问题:

步骤1:初步回答
- 给出你的初步答案

步骤2:自我反思
- 检查答案是否完整
- 检查答案是否准确
- 识别可能的错误

步骤3:改进答案
- 根据反思结果改进答案
- 补充遗漏的信息
- 修正错误

示例:
问题:Python中列表和元组的区别是什么?

步骤1:初步回答
列表是可变的,元组是不可变的。

步骤2:自我反思
答案不完整,只提到了可变性,还有其他区别:
- 语法不同:列表用[],元组用()
- 性能不同:元组更快
- 用途不同:元组可以作为字典的键

步骤3:改进答案
列表和元组的主要区别:
1. 可变性:列表可变,元组不可变
2. 语法:列表用[],元组用()
3. 性能:元组比列表快
4. 用途:元组可以作为字典的键,列表不能

现在请回答:
问题:什么是装饰器?

步骤1:初步回答
"""

4.4 分步指导

python
prompt = """
你是一个编程教学助手。请按照以下步骤指导用户:

步骤1:解释概念
- 用简单的语言解释概念
- 提供实际例子

步骤2:展示代码
- 提供完整的代码示例
- 添加详细注释

步骤3:解释代码
- 逐行解释代码
- 说明关键部分

步骤4:提供练习
- 给出练习题
- 提供参考答案

示例:
请教我如何使用Python的列表推导式

步骤1:解释概念
列表推导式是Python中创建列表的简洁方式,它允许你用一行代码生成列表。

步骤2:展示代码
```python
# 传统方式
squares = []
for i in range(10):
    squares.append(i ** 2)

# 列表推导式
squares = [i ** 2 for i in range(10)]

步骤3:解释代码

  • for i in range(10): 遍历0到9
  • i ** 2: 计算平方
  • [...]: 将结果收集到列表中

步骤4:提供练习 练习:用列表推导式生成1到20之间的偶数列表

参考答案:

python
evens = [i for i in range(1, 21) if i % 2 == 0]

现在请教学: 请教我如何使用Python的装饰器

步骤1:解释概念 """


### 5. Prompt优化实战

#### 5.1 优化前后的对比

**案例1:代码生成**

**优化前**:
```python
prompt = "写一个快速排序"

优化后

python
prompt = """
你是一个专业的Python编程助手。

请编写一个快速排序算法,要求:

1. 使用递归实现
2. 添加详细的中文注释
3. 包含时间复杂度和空间复杂度分析
4. 提供测试代码

输出格式:
```python
# 快速排序实现
def quick_sort(arr):
    # 你的代码
    pass

# 测试代码
if __name__ == "__main__":
    # 测试
    pass

时间复杂度:O(n log n) 空间复杂度:O(log n)

"""

案例2:文本分析

优化前

python
prompt = "分析这段文本"

优化后

python
prompt = """
你是一个专业的文本分析助手。

请分析以下文本,并提供以下信息:

文本:
人工智能(AI)是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。

分析要求:
1. 主题识别:文本的主要主题是什么?
2. 关键词提取:提取5个最重要的关键词
3. 情感分析:文本的情感倾向(正面/负面/中性)
4. 摘要生成:用一句话总结文本内容
5. 难度评估:文本的阅读难度(简单/中等/困难)

输出格式:
{
    "主题": "...",
    "关键词": ["...", "...", "...", "...", "..."],
    "情感": "...",
    "摘要": "...",
    "难度": "..."
}
"""

5.2 Prompt模板

python
class PromptTemplate:
    """Prompt模板类"""
    
    def __init__(self, template: str, variables: list):
        self.template = template
        self.variables = variables
    
    def format(self, **kwargs) -> str:
        """格式化Prompt"""
        return self.template.format(**kwargs)


# 代码生成模板
code_template = PromptTemplate(
    template="""
你是一个专业的{language}编程助手。

请编写一个{function_name},要求:

{requirements}

输出格式:
```{language}
# {function_name}实现
def {function_name}({parameters}):
    # 你的代码
    pass

# 测试代码
if __name__ == "__main__":
    # 测试
    pass

""", variables=["language", "function_name", "requirements", "parameters"] )

使用示例

prompt = code_template.format( language="Python", function_name="快速排序", requirements="""

  1. 使用递归实现
  2. 添加详细注释
  3. 包含时间复杂度分析 """, parameters="arr" ) print(prompt)

## 实践任务

### 任务:优化Prompt提升效果

**目标**:优化Prompt,提升任务效果

**要求**:
1. 选择一个任务(代码生成、文本分析、问答等)
2. 设计初始Prompt
3. 测试效果
4. 优化Prompt
5. 对比效果

**代码框架**:
```python
from openai import OpenAI

client = OpenAI(api_key="your-api-key")

# 初始Prompt
initial_prompt = """
TODO: 设计初始Prompt
"""

# 优化后的Prompt
optimized_prompt = """
TODO: 设计优化后的Prompt
"""

# 测试函数
def test_prompt(prompt, test_cases):
    results = []
    for test_case in test_cases:
        response = client.chat.completions.create(
            model="gpt-4",
            messages=[
                {"role": "user", "content": prompt.format(**test_case)}
            ]
        )
        results.append(response.choices[0].message.content)
    return results

# 测试用例
test_cases = [
    # TODO: 设计测试用例
]

# 对比效果
print("初始Prompt效果:")
initial_results = test_prompt(initial_prompt, test_cases)
for result in initial_results:
    print(result)

print("\n优化后Prompt效果:")
optimized_results = test_prompt(optimized_prompt, test_cases)
for result in optimized_results:
    print(result)

课后作业

作业1:Prompt优化实践

题目:优化特定任务的Prompt

要求

  1. 选择一个实际任务
  2. 设计初始Prompt
  3. 逐步优化Prompt
  4. 记录优化过程
  5. 分析优化效果

作业2:Few-shot vs Zero-shot对比

题目:对比Few-shot和Zero-shot的效果

要求

  1. 选择多个任务
  2. 设计Zero-shot Prompt
  3. 设计Few-shot Prompt
  4. 对比效果
  5. 分析差异

作业3:CoT效果分析

题目:分析CoT对复杂任务的影响

要求

  1. 选择复杂推理任务
  2. 设计无CoT的Prompt
  3. 设计有CoT的Prompt
  4. 对比效果
  5. 分析CoT的作用

参考资料

必读文献

  1. Wei, J., et al. (2022). "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models". NeurIPS.

    • CoT原始论文
  2. Brown, T., et al. (2020). "Language Models are Few-Shot Learners". NeurIPS.

    • Few-shot Learning论文

推荐阅读

  1. OpenAI Prompt Engineering Guide: https://platform.openai.com/docs/guides/prompt-engineering

    • OpenAI Prompt工程指南
  2. Anthropic Prompt Library: https://docs.anthropic.com/claude/prompt-library

    • Anthropic提示库

在线资源

  1. Learn Prompting: https://learnprompting.org/

    • Prompt学习网站
  2. Prompt Engineering Guide: https://www.promptingguide.ai/

    • Prompt工程指南

扩展阅读

高级技术

  • Self-Consistency: 自我一致性
  • Tree of Thoughts: 思维树
  • ReAct: 推理+行动

应用领域

  • 代码生成: 生成高质量代码
  • 文本摘要: 生成准确摘要
  • 问答系统: 提高问答准确率

下节预告

下一节我们将学习LLM评估与选择,学习如何评估LLM性能、基准测试、成本分析等。


架构师AI杜公众号二维码

扫描二维码关注"架构师AI杜"公众号,获取更多技术内容和最新动态