1. 指南
1-1. 提示的指南
在本课中,你将练习两个提示原则及其相关策略,以便为大型语言模型编写有效的提示语。
1-2. 配置
安装 openai 依赖,
!pip install openai
!export OPENAI_API_KEY='sk-...'
加载API密钥和相关的Python库,
import openai
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
openai.api_key = os.getenv('OPENAI_API_KEY')
在整个课程中,我们将使用 OpenAI 的 gpt-3.5-turbo 模型和聊天完成度端点(chat completions endpoint)。
这个辅助函数将使我们更容易使用提示语和查看生成的输出,
def get_completion(prompt, model="gpt-3.5-turbo"):
messages = [{"role": "user", "content": prompt}]
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=0, # this is the degree of randomness of the model's output
)
return response.choices[0].message["content"]
1-3. 提示语原则
-
原则 1: 写出清晰而具体的指示(Write clear and specific instructions)
-
原则 2: 给模型 "思考 "的时间(Give the model time to “think”)
原则 1: 写出清晰而具体的指示
技巧 1: 使用分隔符来清楚地表明输入的不同部分
- 分隔符可以是任何东西,例如: ```,
"""
,< >
,<tag> <\tag>
,:
示例代码,
text = f"""
你应该通过提供尽可能清晰和具体的指令来表达你希望模型做什么。\
这将引导模型走向所需的输出,并减少收到不相关或不正确响应的机会。\
不要把写一个清晰的提示和写一个短的提示混为一谈。\
在许多情况下,较长的提示为模型提供了更多的清晰度和背景,\
这可以导致更详细和相关的输出。
"""
prompt = f"""
将由三个反斜线划定的文本总结为一句话。
```{text}```
"""
response = get_completion(prompt)
print(response)
输出结果如下,
提供清晰具体的指令可以引导模型输出所需结果,避免不相关或不正确响应,较长的提示可以提供更多清晰度和背景,导致更详细和相关的输出。
技巧 2: 要求提供结构化的输出
- JSON, HTML
示例代码,
prompt = f"""
生成一个包含三个编造的书名及其作者和流派的列表。\
以JSON格式提供,键值如下:
book_id, title, author, genre。
"""
response = get_completion(prompt)
print(response)
输出结果如下,
[
{
"book_id": 1,
"title": "The Shadow of the Wind",
"author": "Carlos Ruiz Zafón",
"genre": "Gothic fiction"
},
{
"book_id": 2,
"title": "The Nightingale",
"author": "Kristin Hannah",
"genre": "Historical fiction"
},
{
"book_id": 3,
"title": "The Martian",
"author": "Andy Weir",
"genre": "Science fiction"
}
]
技巧 3: 要求模型检查条件是否得到满足
示例代码 1,
text_1 = f"""
泡一杯茶很容易!\
首先,你需要让一些水沸腾。\
在这过程中,拿起一个杯子,把茶包放进去。\
一旦水足够热,就把它倒在茶包上。\
让茶叶浸泡一会儿。\
几分钟后,取出茶包。\
如果你喜欢,你可以加入一些糖或牛奶来调味。\
就这样 你就可以享受到一杯美味的茶了。
"""
prompt = f"""
你将得到由三引号划定的文本。\
如果它包含一连串的指令,请按以下格式重写这些指令:
第1步 - ...
第2步 - ...
...
第N步 - ...
如果该文本不包含指令序列,那么只需写上 "未提供步骤"。
\"\"\"{text_1}\"\"\"
"""
response = get_completion(prompt)
print("Completion for Text 1:")
print(response)
输出结果如下,
Completion for Text 1:
第1步 - 让一些水沸腾。
第2步 - 拿起一个杯子,把茶包放进去。
第3步 - 一旦水足够热,就把它倒在茶包上。
第4步 - 让茶叶浸泡一会儿。
第5步 - 取出茶包。
第6步 - 如果你喜欢,你可以加入一些糖或牛奶来调味。
第7步 - 享受你的美味茶!
示例代码 2,
text_2 = f"""
今天阳光明媚,鸟儿在歌唱。
这是一个去公园散步的好日子。
鲜花盛开,树木在微风中轻轻摇曳。
人们都出来走动,享受这美好的天气。
一些人正在野餐,而另一些人正在玩游戏,或只是在草地上放松。
这是一个完美的日子,可以花时间在户外,欣赏大自然的美丽。
"""
prompt = f"""
你将得到由三引号划定的文本。\
如果它包含一连串的指令,请按以下格式重写这些指令:
第1步 - ...
第2步 - ...
...
第N步 - ...
如果该文本不包含指令序列,那么只需写上 "未提供步骤"。
\"\"\"{text_2}\"\"\"
"""
response = get_completion(prompt)
print("Completion for Text 2:")
print(response)
输出结果如下,
Completion for Text 2:
未提供步骤
技巧 4: "少许样本"提示
举出完成任务的成功例子,然后要求模型执行任务。
示例代码,
prompt = f"""
你的任务是以一致的风格来回答。
<孩子>:教我耐心。
<祖父母>:雕琢最深山谷的河流从一个小小的泉眼流过;\
最宏伟的交响乐源于一个音符;最复杂的织锦从一根线开始。
<孩子>:教我如何坚韧不拔。
"""
response = get_completion(prompt)
print(response)
输出结果如下,
<祖父母>:坚韧不拔的力量来自于内心的信念和毅力。要有目标,有计划,有毅力,不断努力,不轻易放弃,才能走向成功的道路。
原则 2: 给模型 "思考 "的时间
技巧 1: 具体说明完成一项任务所需的步骤
示例代码,
text = f"""
在一个迷人的村庄里,杰克和吉尔兄妹开始了从山顶水井取水的征程。
当他们欢快地唱着歌爬上山顶时,不幸发生了--杰克被一块石头绊倒,\
翻下山去,吉尔也跟着摔倒。
虽然受了点伤,但两人还是在安慰的怀抱中回到了家。
尽管发生了意外,他们的冒险精神仍然没有受到影响,他们继续愉快地探索。
"""
# example 1
prompt_1 = f"""
执行以下操作:
1 - 用1个句子总结以下由三个反斜线划定的文本。
2 - 将摘要翻译成日文。
3 - 在日文摘要中列出每个名字。
4 - 输出一个json对象,包含以下内容 \
keys: japanese_summary, num_names.
用换行符把你的答案分开。
Text:
```{text}```
"""
response = get_completion(prompt_1)
print("Completion for prompt 1:")
print(response)
输出结果如下,
Completion for prompt 1:
1 - 杰克和吉尔兄妹在山顶水井取水时发生了意外,但他们的冒险精神没有受到影响,继续愉快地探索。
2 - 山頂の井戸から水を汲む旅を始めたジャックとジル兄妹は、歌を歌いながら山を登っていたが、ジャックが石につまずいて山から転落し、ジルも転倒してしまった。彼らは少し怪我をしたが、安心した抱擁の中で家に戻った。事故が起こったにもかかわらず、彼らの冒険心は影響を受けず、彼らは楽しく探検を続けた。
3 - ジャック、ジル
4 - {
"japanese_summary": "山頂の井戸から水を汲む旅を始めたジャックとジル兄妹は、歌を歌いながら山を登っていたが、ジャックが石につまずいて山から転落し、ジルも転倒してしまった。彼らは少し怪我をしたが、安心した抱擁の中で家に戻った。事故が起こったにもかかわらず、彼らの冒険心は影響を受けず、彼らは楽しく探検を続けた。",
"num_names": 2
}
要求以指定的格式输出,
示例代码,
prompt_2 = f"""
你的任务是执行以下行动:
1 - 用1个句子总结以下以<>为界的文字。
2 - 将摘要翻译成日文。
3 - 列出日文摘要中的每个名字。
4 - 输出一个json对象,包含以下键:japanese_summary, num_names。
使用以下格式:
文本: <要总结的文本>
摘要: <摘要>
翻译: <摘要翻译>
名称: <日文摘要中的名字列表>
输出JSON:<json格式的summary 和 num_names>
Text: <{text}>
"""
response = get_completion(prompt_2)
print("\nCompletion for prompt 2:")
print(response)
输出结果如下,
Completion for prompt 2:
摘要:在一个迷人的村庄里,杰克和吉尔兄妹开始了从山顶水井取水的征程,但杰克不幸被一块石头绊倒,两人受了点伤但还是继续愉快地探索。
翻译:魅力的村にて、ジャックとジル兄妹は山頂の井戸から水を汲む旅を始めましたが、ジャックは石につまずいて山から転落し、2人は少し怪我をしましたが、探検を楽しんで続けました。
名称:杰克、吉尔
输出JSON:{"japanese_summary": "魅力的な村で、ジャックとジル兄妹は山頂の井戸から水を汲む旅を始めましたが、ジャックは石につまずいて山から転落し、2人は少し怪我をしましたが、探検を楽しんで続けました。", "num_names": 2}
技巧 2: 在匆忙得出结论之前,要求模型自己解决问题
示例代码,
prompt = f"""
判断该学生的解决方案是否正确。
问题:
我正在建造一个太阳能发电装置,我需要帮助解决财务问题。
- 土地成本为100美元/平方英尺
- 我可以以250美元/平方英尺的价格购买太阳能电池板
- 我协商了一份维护合同,每年的费用为10万美元,另外每平方英尺10美元。
第一年运营的总成本是多少,与平方英尺数的关系是什么。
学生的解决方案:
设x为安装的面积,单位为平方英尺。
成本:
1. 土地成本:100x
2. 太阳能电池板成本:250x
3. 维护费用:100,000 + 100x
总成本:100x + 250x + 100,000 + 100x = 450x + 100,000
"""
response = get_completion(prompt)
print(response)
输出结果如下,
该学生的解决方案是正确的。总成本与安装面积呈线性关系,即总成本随着安装面积的增加而增加。
请注意,这个学生的解决方案实际上是不正确的。
我们可以通过指示模型先算出自己的解决方案来解决这个问题。
示例代码,
prompt = f"""
你的任务是确定该学生的解决方案是否正确。
要解决这个问题,请做以下工作:
- 首先,找出你自己的解决方案。
- 然后将你的方案与学生的方案进行比较,评估学生的方案是否正确。\
在你自己做完这个问题之前,不要决定学生的解决方案是否正确。
使用以下格式:
问题:
```#
这里的问题
```#
学生的解决方案:
```#
学生的解决方案在这里
```#
实际的解决方案:
```#
解决问题的步骤和你的解决方案在这里
```#
学生的解决方案是否与刚才计算的实际解决方案相同:
```#
是或不是
```#
学生的成绩:
```#
正确或不正确
```#
问题:
```#
我正在建造一个太阳能发电装置,我需要帮助解决财务问题。
- 土地成本为100美元/平方英尺
- 我可以以250美元/平方英尺的价格购买太阳能电池板。
- 我谈好了一份维护合同,每年的费用为10万美元,另外每平方英尺增加10美元。
运营第一年的总成本是多少,与平方英尺的数量成正比。
```#
学生的解决方案:
```#
设x为安装的面积,单位为平方英尺。
成本:
1. 土地成本:100x
2. 太阳能电池板成本:250x
3. 维护费用:100,000 + 100x
总成本:100x + 250x + 100,000 + 100x = 450x + 100,000
```#
实际解决方案:
"""
response = get_completion(prompt)
print(response)
输出结果如下,
学生的解决方案与实际解决方案相同。
```#
设x为安装的面积,单位为平方英尺。
成本:
1. 土地成本:100x
2. 太阳能电池板成本:250x
3. 维护费用:100,000 + 10x
总成本:100x + 250x + 100,000 + 10x = 360x + 100,000
```#
学生的解决方案是否与刚才计算的实际解决方案相同:
是
学生的成绩:
正确
请注意,这个学生的解决方案实际上是不正确的。我用中文尝试和好几遍,都等不到正确的反馈,然后使用英文代码测试了一下。
示例代码,
prompt = f"""
Your task is to determine if the student's solution is correct or not.
To solve the problem do the following:
- First, work out your own solution to the problem.
- Then compare your solution to the student's solution and evaluate if the student's solution is correct or not.
Don't decide if the student's solution is correct until you have done the problem yourself.
Use the following format:
Question:
```#
question here
```#
Student's solution:
```#
student's solution here
```#
Actual solution:
```#
steps to work out the solution and your solution here
```#
Is the student's solution the same as actual solution just calculated:
```#
yes or no
```#
Student grade:
```#
correct or incorrect
```#
Question:
```#
I'm building a solar power installation and I need help working out the financials.
- Land costs $100 / square foot
- I can buy solar panels for $250 / square foot
- I negotiated a contract for maintenance that will cost me a flat $100k per year, and an additional $10 / square foot
What is the total cost for the first year of operations as a function of the number of square feet.
```#
Student's solution:
```#
Let x be the size of the installation in square feet.
Costs:
1. Land cost: 100x
2. Solar panel cost: 250x
3. Maintenance cost: 100,000 + 100x
Total cost: 100x + 250x + 100,000 + 100x = 450x + 100,000
```#
Actual solution:
"""
response = get_completion(prompt)
print(response)
输出结果如下,
Actual solution:
Let x be the size of the installation in square feet.
Costs:
1. Land cost: 100x
2. Solar panel cost: 250x
3. Maintenance cost: 100,000 + 10x
T