Press "Enter" to skip to content

微软生成式AI入门课程05 —— 创建高级提示

让我们回顾一下上一章的一些学习内容:

“提示工程”是一个过程,在这个过程中,我们通过提供更有用的指示或上下文来引导模型产生更相关的回答

编写提示的两个步骤是:构建提示——通过提供相关的上下文,并进行“优化”,以逐渐改进提示。

到目前为止,我们已经对如何编写提示有了一些基本的了解,但我们需要更深入地了解。在本章中,您将从尝试各种提示开始,了解为什么一个提示比另一个好。您将学习如何使用一些基本的技巧来构建提示,这些技巧适用于任何LLM。

介绍

在本章中,我们将涵盖以下主题:

  • 运用不同的技巧来扩展您对提示工程的了解。
  • 配置提示以使输出多样化。

学习目标

完成本课程后,您将能够:

  • 应用改进提示结果的提示工程技巧。
  • 进行变化或确定性的提示。

提示工程

提示工程是创建能产生所需结果的提示的过程。提示工程不仅仅是编写一个文本提示,它不是一门工程学科,而是一系列技巧的集合,您可以应用这些技巧来获得所需的结果。

一个提示的示例

让我们来看一个基本的提示,像这样:

“生成 10 个关于地理的问题。”

在这个提示中,您实际上是应用了一组不同的提示技巧。

让我们来分解一下。

  • 上下文,您指定了它应该是关于”地理”的。
  • 限制输出,您希望不超过 10 个问题。

简单提示的局限性

您可能会得到所需的结果,也可能不会。您将获得生成的问题,但地理是一个庞大的主题,由于以下原因,您可能无法获得真正想要的结果:

  • 庞大的主题,您不知道它是否涉及国家、首都、河流等等。
  • 格式,如果您希望问题以某种特定的方式呈现呢?

正如您所见,创建提示时需要考虑许多因素。

到目前为止,我们已经看到了一个简单的提示示例,但生成式AI能够在许多角色和行业中帮助人们,我们来探索一些基本技巧。

提示技巧

首先,我们需要理解提示是LLM的一个“ emergent ”属性,这意味着这不是一个内置在模型中的功能,而是我们在使用模型时发现的东西。

我们可以使用一些基本的技巧来提示LLM。让我们一起来探索一下:

  • 少量示例提示,这是最基本的提示形式。它是一个只包含几个示例的提示。
  • 思维链,这种类型的提示告诉LLM如何将一个问题分解为一系列步骤进行处理。
  • 生成的知识,为了改善提示的回答,您可以提供除了提示外的生成的事实或知识。
  • 从少到多,与思维链类似,这个技术是将一个问题分解为一系列步骤,然后按顺序要求执行这些步骤。
  • 自我改进,这个技术是对LLM的输出提出批评,然后要求它进行改进。
  • 助产提示,在这里,您希望确保LLM的答案是正确的,并要求它解释答案的各个部分。这是一种自我改进的形式。

少量示例提示

这种形式的提示非常简单,它可能由一个提示和几个示例组成。这种技术可能是您刚开始学习LLM时使用的。这是一个示例:

  • 提示:”代数是什么?”
  • 答案:”代数是研究数学符号及其操作规则的数学分支。”

思维链

思维链是一种非常有趣的技巧,它是将LLM按照一系列步骤进行指导的方法。思维链的思想是通过一种方式教导LLM如何做事情。考虑以下示例,带和不带思维链的情况:

- 提示:"Alice 有 5 个苹果,扔掉了 3 个苹果,把 2 个苹果给了 Bob,然后 Bob 又还给了一个苹果,Alice 还剩下几个苹果?"
- 答案:5

LLM的答案是 5,这是不正确的。正确的答案是 1,根据计算(5 – 3 – 2 + 1 = 1)。

那么我们该如何教导LLM正确地进行计算呢?

让我们尝试思维链。应用思维链意味着:

  1. 给LLM一个类似的例子。
  2. 展示计算过程,以及如何正确计算。
  3. 提供原始提示。

具体如下所示:

  • 提示:”Lisa 有 7 个苹果,扔掉了 1 个苹果,把 4 个苹果给了 Bart,然后 Bart 又还给了一个苹果: 7 -1 = 6 6 -4 = 2 2 +1 = 3

Alice 有 5 个苹果,扔掉了 3 个苹果,把 2 个苹果给了 Bob,然后 Bob 又还给了一个苹果,Alice 还剩下几个苹果?” 答案:1

请注意,我们编写了更长的提示,包括另一个例子、一个计算过程,然后是原始提示,最终得到了正确的答案 1。

正如您所见,思维链是一种非常强大的技巧。

生成的知识

当您想要构建提示时,通常希望使用您公司的数据。您希望提示的一部分来自公司,另一部分是您真正感兴趣的提示。

以保险业务为例,如果使用您公司的数据构建提示,提示可能如下所示:

```text
{{公司}}:{{公司名称}}
{{产品}}:
{{产品列表}}
请根据以下预算和要求提供一个保险建议:
预算:{{预算}}
要求:{{要求}}
```

在上面的示例中,您可以看到如何使用模板构建提示。在模板中,有一些变量,用 {{变量}} 表示,将使用公司 API 中的实际值替换这些变量。

下面是提示完成后的示例,变量已被公司的内容替换:

```text
保险公司:ACME Insurance
保险产品(每月费用):
- 汽车,廉价,500 美元
- 汽车,昂贵,1100 美元
- 房屋,廉价,600 美元
- 房屋,昂贵,1200 美元
- 生命,廉价,100 美元

请根据以下预算和要求提供一个保险建议:
预算:$1000
要求:汽车,房屋
```

运行此提示会生成如下回应:

```output
,以及生命保险

根据预算和要求,我们建议从 ACME Insurance 中选择以下保险套餐:
- 汽车,廉价,500 美元
- 房屋,廉价,600 美元
- 生活,廉价,100 美元
总费用:1,200 美元
```

正如您所见,它还建议了生命保险,而实际上不应该建议。这个结果表明我们需要通过更改提示来优化提示,以便更清楚地说明它可以允许什么。经过一些“试错”,我们得到了以下提示:

```text
保险公司:ACME Insurance
保险产品(每月费用):
- 类型:汽车,廉价,费用:500 美元
- 类型:汽车,昂贵,费用:1100 美元
- 类型:房屋,廉价,费用:600 美元
- 类型:房屋,昂贵,费用:1200 美元
- 类型:生命,廉价,费用:100 美元

请根据以下预算和要求提供一个保险建议:
预算:$1000 限制选择类型:汽车,房屋
```

注意添加了“类型”和“费用”,还使用了“限制”关键字,这有助于LLM理解我们的意图。

现在,我们得到了以下回应:

```output
根据预算和要求,我们建议从 ACME Insurance 选择廉价汽车保险产品,每月费用为 500 美元。
```

这个示例的目的是表明,即使我们使用了像“生成的知识”这样的基本技巧,我们在大多数情况下仍需要优化提示才能获得所需的结果。

从少到多

最少到最多的提示思路是将一个更大的问题分解成子问题。这样,您就可以帮助引导LLM如何“征服”这个更大的问题。一个很好的例子可能是数据科学,您可以要求LLM将一个问题分解为如下部分:

提示:”如何以 5 个步骤进行数据科学计算?”

您的AI助手会回答:

  1. 收集数据。
  2. 清洁数据。
  3. 分析数据。
  4. 绘制数据。
  5. 呈现数据。

自我改进,批评结果

在生成式AI和LLM中,您不能信任输出结果。您需要验证它。毕竟,LLM只是向您展示下一个最有可能说的事情,而不是正确的事情。因此,一个好主意是要求LLM批评自己,这引导我们进入了自我改进的技巧。

它的工作原理是按照以下步骤进行:

  1. 初始提示,要求LLM解决一个问题。
  2. LLM回答。
  3. 您对答案进行批评,并要求AI进行改进。
  4. LLM再次回答,这次考虑到了批评,并提出了它提出的解决方案。

您可以根据需要重复此过程。

以下是使用此技术的示例:

提示:”使用 Flask 构建一个 Python Web API,具有产品和客户路由”

AI回答:

```python
import flask
app = Flask(__name__)

@app.route('/products')
def products():
return 'Products'

@app.route('/customers')
def customers():
return 'Customers'
```

提示:”对上述代码提出 3 个改进建议”

AI回答:

```text
没有问题,请找到以下改进建议:

1. 导入正确的模块:第一行应该导入 Flask 而不是 flask。正确的导入语句应该是 from flask import Flask。

2. 添加一个 main 函数:在文件的结尾添加 if __name__ == '__main__': 代码块,以在文件运行时运行应用程序。

3. 使用 f-strings:使用 f-strings 格式化路由函数中的返回语句。例如,return 'Products' 可以改为 return f'This is the {request.path} page'。
```

```python
from flask import Flask, request

app = Flask(__name__)

@app.route('/products')
def products():
return f'This is the {request.path} page'

@app.route('/customers')
def customers():
return f'This is the {request.path} page'

if __name__ == '__main__':
app.run()
```

正如您所见,上面的AI响应正在改进第一个建议的代码,感谢对第一个答案进行批评。

助产提示

助产提示是一种类似于自我改进的技术,但它更多地涉及要求LLM解释自己,目的是减少LLM的输出中的不一致,以确保它得出正确的答案。遵循以下步骤:

  1. 要求LLM回答一个问题。
  2. 对于答案的每个部分,要求LLM详细解释。
  3. 如果存在不一致,则丢弃不一致的部分。

重复步骤 2 和步骤 3,直到您遍历完所有部分并对答案感到满意。

以下是一个示例提示:

提示:”如何通过 5 个步骤创建危机计划以减轻大流行的影响?” LLM回答:

```text
1. 确定风险
2. 确定利益相关方
3. 确定资源
4. 确定行动
5. 确定沟通渠道
```

已确定 5 个步骤,但我们如何确定这是正确的呢?让我们要求LLM详细解释每个步骤:

提示:”更详细地解释第一个步骤,大流行中的风险是什么?”

```text
以下是风险的详细信息:

- 生命损失
- 业务损失
- 声誉损失
- 客户损失
- 员工损失
```

在这一点上,我们希望确保LLM是正确的,所以我们要求它更详细地解释第一个风险,并希望它与上面的答案一致:

提示:”在大流行中,风险最大的是什么?为什么?”

```text
在大流行中,最大的风险是生命损失,因为保护生命是最重要的事情。
```

大流行中的两个最大风险是什么?

```text
两个最大的风险是生命损失和业务损失。
```

在这一点上,LLM是一致的,并将“生命”和“业务”作为最高的两个风险。现在我们可以继续下一个步骤,并且相当自信。但是,我们不应该盲目地相信LLM,我们应该始终验证输出。

改变输出

LLM的特点是非确定性的,这意味着每次运行相同的提示都会得到不同的结果。例如,尝试以下提示:

“生成一个 Python Web API 的代码”

```text
# 导入必要的模块
import flask
from flask import request, jsonify

# 创建一个Flask应用
app = flask.Flask(__name__)

# 为API创建一个路由
@app.route(</api<, methods=[<GET<])
def api():
# 从请求中获取数据
data = request.args

# 处理数据
result = process_data(data)

# 将结果返回为JSON格式
return jsonify(result)

# 处理数据的函数
def process_data(data):
# 对数据进行操作
result = data + 1

# 返回结果
return result

# 运行应用
if __name__ == <__main__<:
app.run()
```

再次运行相同的提示会得到略有不同的结果:

```text
# 导入必要的包
import flask
from flask import request, jsonify

# 创建 Flask 应用
app = flask.Flask(__name__)
app.config["DEBUG"] = True

# 创建书籍列表
books = [
{'id': 0,
'title': '宇宙之炎',
'author': '弗农·芬格',
'first_sentence': '冷冻睡眠本身是无梦的。',
'year_published': '1992'},
{'id': 1,
'title': '离开奥梅拉斯的人们',
'author': '厄舍拉·凯·勒·吉恩',
'first_sentence': '一阵摇铃声使燕子飞翔,夏季节日来到了沿海高塔之城奥梅拉斯。',
'published': '1973'},
{'id': 2,
'title': '达尔格伦',
'author': '塞缪尔·R·德拉尼',
'first_sentence': '伤害秋季之城。',
'published': '1975'}
]

# 创建 API 的端点
@app.route('/', methods=['GET'])
def home():
return '''<h1>图书 API</h1>
<p>用于检索图书的原型 API。</p>'''

# 创建返回所有书籍的端点
@app.route('/api/v1/resources/books/all', methods=['GET'])
def api_all():
return jsonify(books)

# 创建返回单本书籍的端点
@app.route('/api/v1/resources/books', methods=['GET'])
def api_id():
# 检查 URL 中是否提供了 ID
# 如果提供了 ID,则将其赋值给一个变量
# 如果未提供 ID,则显示错误
if 'id' in request.args:
id = int(request.args['id'])
else:
return "错误:未提供 id 字段,请指定一个 id。"

# 创建一个空列表以存储结果
results = []

# 遍历数据并匹配符合请求的 ID 的结果
# ID 是唯一的,但其他字段可能返回多个结果
for book in books:
if book['id'] == id:
results.append(book)

# 使用 Flask 中的 jsonify 函数将我们的 Python 字典列表转换为 JSON 格式
return jsonify(results)

app.run()
```

那么变化的输出是个问题吗?

这要取决于你想做什么。如果你希望得到特定的响应,那么这是个问题。如果你对像”生成任意三个关于地理学的问题”这样的变化输出感到满意,那么这不是个问题。

使用温度来改变输出

好的,我们决定要限制输出,使其更可预测,即更确定性。我们该如何做到呢?

温度是一个介于0和1之间的值,其中0是最确定性的,1是最多变性的。默认值是0.7。让我们看看两次在温度设为0.1的相同提示下运行会发生什么:

“为 Python Web API 生成代码”

```python
# 导入必要的库
import flask
from flask import request, jsonify

# 创建 Flask 类的实例
app = flask.Flask(__name__)

# 创建 API 的端点
@app.route('/api/v1/endpoint', methods=['GET'])
def api_endpoint():
# 获取请求数据
data = request.get_json()

# 处理数据
result = process_data(data)

# 返回结果
return jsonify(result)

# 处理数据的函数
def process_data(data):
# 处理数据
result = {'result': 'success'}

# 返回结果
return result

# 运行 Flask 应用
if __name__ == '__main__':
app.run()
```

再次运行该提示,我们得到了这个结果:

```python
# 导入必要的库
import flask
from flask import request, jsonify

# 创建一个 Flask 应用
app = flask.Flask(__name__)

# 创建一个 API 的路由
@app.route('/api', methods=['GET'])
def api_call():
# 从请求中获取数据
data = request.get_json()

# 处理数据
result = process_data(data)

# 返回结果
return jsonify(result)

# 定义处理数据的函数
def process_data(data):
# 处理数据
result = data + 1

# 返回结果
return result

# 运行应用
if __name__ == '__main__':
app.run()
```

如您所见,这两个输出之间只有微小的差别。让我们进行相反的尝试,将温度设置为 0.9:

```text
# 导入所需的库
import flask
from flask import request, jsonify

# 创建一个 Flask 应用
app = flask.Flask(__name__)

# 创建一个 API 的路由
@app.route('/api', methods=['GET'])
def api_call():
# 从请求中获取数据
data = request.args

# 处理数据
result = process_data(data)

# 返回结果
return jsonify(result)

# 处理数据的函数
def process_data(data):
# 对数据进行处理
result = data + 1

# 返回结果
return result

# 运行应用
if __name__ == '__main__':
app.run()
```

和第二次运行 0.9 作为温度值的尝试:

```text
import flask
from flask import request, jsonify

# 创建 Flask 应用
app = flask.Flask(__name__)
app.config['DEBUG'] = True

# 创建一些测试数据
books = [
{'id': 0, 'title': 'A Fire Upon The Deep', 'author': 'Vernor Vinge', 'first_sentence': 'The coldsleep itself was dreamless.', 'year_published': '1992'},
{'id': 1, 'title': 'The Ones Who Walk Away From Omelas', 'author': 'Ursula K. Le Guin', 'first_sentence': 'With a clamor of bells that set the swallows soaring, the Festival of Summer came to the city Omelas, bright-towered by the sea.', 'published': '1973'},
{'id': 2, 'title': 'Dhalgren', 'author': 'Samuel R. Delany', 'first_sentence': 'to wound the autumnal city.', 'published': '1975'}
]

# 创建一个端点
@app.route('/', methods=['GET'])
def home():
return '''<h1>Welcome to our book API!</h1>'''

@app.route('/api/v1/resources/books

正如您所见,结果变化非常大。

请注意,您可以更改的参数还有很多,如 top-k、top-p、重复惩罚、长度惩罚和多样性惩罚,但这些超出了本课程安排的范围。

良好实践

当提示LLM时,有许多实践方法可供尝试以获得所需的结果。随着您越来越多地使用提示,您将找到自己的风格。

除了我们已经讨论过的技巧之外,还有一些良好的实践方法,可以在提示LLM时考虑。

以下是一些值得考虑的良好实践方法:

  • 指定上下文。上下文很重要,您越详细地指定,如领域、主题等,效果就越好。
  • 限制输出。如果您希望具有特定数量的项目或特定长度,请指定它。
  • 同时指定“什么”和“如何”。请记住同时提及您想要的内容以及您希望以何种方式,例如“使用产品和客户路由创建一个Python Web API,并将其分解成3个文件”。
  • 使用模板。您经常会希望使用来自公司的数据丰富提示。使用模板来实现。模板可以有变量,您可以用实际数据替换这些变量。
  • 拼写正确。LLM可能提供了正确的答案,但如果拼写正确,您将得到更好的答案。

作业

以下是使用 Flask 构建简单 API 的 Python 代码:

```python
from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def hello():
name = request.args.get('name', 'World')
return f'Hello, {name}!'

if __name__ == '__main__':
app.run()
```

使用 GitHub Copilot 或 ChatGPT 等AI助手,并应用“自我改进”技巧来改进代码。

答案

请尝试通过向代码添加合适的提示来完成作业。

[!TIP] 构建一个提示以要求它进行改进,对于要改进的内容的数量有所限制是个好主意。您还可以要求以特定的方式进行改进,例如架构、性能、安全等方面。

答案

知识检测

我为什么要使用思维链技术?请给出 1 个正确答案和 2 个错误答案。

  1. 为了教导LLM如何解决一个问题。
  2. B,为了教导LLM如何找到代码中的错误。
  3. C,为了教导LLM提出不同的解决方案。

A:1,因为思维链是通过向LLM提供一系列步骤、类似问题及其解决方法来教导LLM如何解决问题的。

🚀 挑战

您刚刚在作业中使用了自我改进技术。选择您构建的任何程序,并考虑要应用的改进。然后使用自我改进技术应用这些改进。您认为结果会更好还是更差?

出色的工作!继续学习

想要了解更多关于创建高级提示的知识吗?转到持续学习页面查找其他关于此主题的资源。

请继续下一课,我们将应用我们对提示工程的了解,通过构建文本生成应用程序来学习。

本文由极客智坊网页翻译服务自动生成:

微信扫码体验极客智坊AI服务

原文地址:https://microsoft.github.io/generative-ai-for-beginners/#/05-advanced-prompts/README

发表回复