写在前面

帮朋友推广一下大众号,欢迎朋友们关注,谢谢!

这样设置Prompt,让ChatGPT输出更好的效果!

导言

众所周知,为ChatGPT供给更适宜的Prompt输入,咱们就能得到更优质的成果。

为了协助初学者更好地学习这些常识和技术,吴恩达教师与 OpenAI 协作推出了《ChatGPT Prompt Engineering for Developers》教程的中文版。该课程经过简略易懂的解说和范例代码演示,深入介绍了怎么运用 Prompt 和 OpenAI 的 API 来开发应用程序,包括怎么构造 Prompt 并基于 OpenAI 供给的 API 完结多种常用功用,如总结、揣度、转化等。这是入门 LLM 开发的经典教程。

本序列文章是深度参考吴恩达教师的教程之后,提炼的一些要害点。期望能够协助到咱们。

本文章主要聚焦于:编写 Prompt 的准则。 了解基本准则后,也能够进一步阅读《这样逐渐优化Prompt,让ChatGPT输出你想要的成果!》

纲要

给OpenAI API 供给更优质的Prompt,需求遵从两个准则:

  • 准则一:编写明晰、详细的指令

    战略1:运用合理的分隔符,更明晰地表示输入的不同部分。

    战略2:给模型指示,要求结构化地输出内容。

    战略3:能够要求模型查看是否满意条件。

    战略4:能够给模型供给少数示例,以取得更优的成果。

  • 准则二:给模型能够思考的时刻

    战略5:给模型指定完结使命所需的进程。

    战略6:引导模型在下定论之前找出一个自己的解法。

接下来结合详细的代码实践,来一起学习上面的准则和详细的战略。

提示:在本教程中,咱们将运用 OpenAI 开放的 ChatGPT API。为此,您需求先取得 ChatGPT 的 API_KEY(您也能够直接拜访官方网站进行在线测试),然后装置 openai 的第三方库。

装置openai库

pip install openai

准备辅佐函数

这个辅佐函数在后续的示例中经常会用到。主要功用是根据输入的Prompt内容,调用openai API,并取得输出成果。

import openai
​
# 设置key
# Key的查看进口:https://beta.openai.com/account/api-keys
# 也能够经过环境变量的方式来设置,为了简略起见,这儿直接经过设置参数的方式来设置
openai.api_key = "sk-XXX"# 一个封装 OpenAI 接口的函数,参数为 Prompt,返回对应成果
def get_completion(prompt, model="gpt-3.5-turbo"):
  messages = [{"role": "user", "content": prompt}]
  response = openai.ChatCompletion.create(
    model=model,
    messages=messages,
    temperature=0, # 模型输出的温度系数,控制输出的随机程度
   )
  return response.choices[0].message["content"] 

战略1:运用合理的分隔符

运用合理的分隔符,向模型更明晰地表示输入的不同部分。

分隔符能够是任何标记,只要让模型明晰知道这是一个独自的部分即可。例如分隔符能够是:“`,””,<>,,<\tag>等。

以下是一个例子,咱们给出一段话并要求 GPT 进行总结,在该示例中咱们运用 “` 来作为分隔符。

# 原始的内容
text = f"""
   你应该供给尽可能明晰、详细的指示,以表达你期望模型履行的使命。\
   这将引导模型朝向所需的输出,并降低收到无关或不正确呼应的可能性。\
   不要将写明晰的提示与写简略的提示混杂。\
   在许多情况下,更长的提示能够为模型供给更多的明晰度和上下文信息,然后导致更详细和相关的输出。"""# 经过分隔符要求ChatGPT总结分隔符包括的内容。
prompt = f"""
   把用三个反引号包裹起来的文本内容总结成一句话。
   ```{text}```
   """
# 调用ChatGPT API
response = get_completion(prompt)
print(response)

输出成果:

供给明晰、详细的指示,防止无关或不正确呼应。不要混杂明晰和简略,更长的提示能够供给更多明晰度和上下文信息。

战略2:格局化输出内容

要求ChatGPT以某种格局化的方式输出内容,这样的输出更简单被咱们的程序解析。能够是 Json、HTML 等格局。

下面的示例中,咱们要求 GPT 生成虚拟的三本书的书名、作者、出版社等信息,并以 Json 格局返回成果。为了便利解析,咱们指定了 Json 键(key)。

prompt = """
   请生成3本虚拟的书,包括书名、作者、出版社等信息。\
   并以json方式输出成果,其间包括以下json key:\
   book_name, author, publisher\
   """
response = get_completion(prompt)
print(response)

输出成果:

[  {  "book_name": "时光之旅",  "author": "张三",  "publisher": "人民文学出版社"  },  {  "book_name": "未来的国际",  "author": "李四",  "publisher": "科学出版社"  },  {  "book_name": "爱情的故事",  "author": "王五",  "publisher": "上海文艺出版社"  }]

战略3:要求模型查看是否满意条件

有时候,咱们期望模型只要在满意某些条件的情况下才履行详细的使命。假如条件不满意,咱们期望模型停止履行,并告知咱们。

下面有两个示例,分别用来展示“满意某些条件”和“不满意某些条件”的情况。

示例1: 给模型输入一段泡茶的进程,让模型判别是否包括明晰的指令,假如包括,则以咱们指定的格局来输出指令序列。

text = f"""
   泡一杯茶很简单。首要需求把水烧开。在等待期间,拿一个杯子并把茶叶放进去。\
   比及水烧开了,就把开端倒在茶叶上。然后,等待几分钟,让茶叶充分浸泡。\
   几分钟之后,能够取出茶包,然后就能够喝茶了。\
   假如有需求,能够参加牛奶或糖。\
   就这样,你就能够享受一杯甘旨的茶了。
   """
 
prompt = f"""
   你将取得一段文本,是三个引号括起来的文本内容。\
   假如它包括一些列的指令,则依照下面的格局重写这些指令。\
   第一步:
   第二步:
   第三步:
   ……
   第N步:
   假如不包括指令,则输出:未辨认出有用指令。
   """{input_text}"""
   """
response = get_completion(prompt)
print(response)

输出成果:

第一步:把水烧开。
第二步:拿一个杯子并把茶叶放进去。
第三步:比及水烧开了,就把开端倒在茶叶上。
第四步:等待几分钟,让茶叶充分浸泡。
第五步:取出茶包。
第六步:假如需求,能够参加牛奶或糖。
第七步:享受一杯甘旨的茶。

示例2: 输入另一段没有包括明晰指令的内容,让模型来判别。

text = f"""今天阳光明媚,鸟儿在歌唱。\
   这是一个去公园漫步的美好日子。\
   鲜花盛开,树枝在微风中轻轻摇曳。\
   人们外出享受着这美好的气候,有些人在野餐,有些人在玩游戏或许在草地上放松。\
   这是一个完美的日子,能够在户外度过并赏识大自然的美景。"""prompt = f"""
   你将取得一段文本,是三个引号括起来的文本内容。\
   假如它包括一些列的指令,则依照下面的格局重写这些指令。\
   第一步:
   第二步:
   第三步:
   ……
   第N步:
   假如不包括指令,则输出:未辨认出有用指令。
   """{input_text}"""
   """
response = get_completion(prompt)
print(response)

输出成果:

未辨认出有用指令。

战略4:供给少数示例,要求模型按示例格局输出成果

咱们能够要求模型在履行实践使命之前,依照供给给它的少数示例,来履行剩下的使命。

在下面的示例中,咱们以教师和学生的对话为例。

先供给一个对话的示例,然后要求模型按共同的口气和相同的格局,输出后续的内容。

prompt = f"""
   你的使命是以共同的风格来回答问题。
   <学生>:教我耐心。\
   <教师>:挖出最深峡谷的河流源于一处不起眼的泉眼;最宏伟的交响乐从单一的音符开端;最杂乱的挂毯以一根孤独的线开端编织。\
   <学生>:教我坚韧。
   """
response = get_completion(prompt)
print(response)

输出成果:

<教师>:坚韧不是一蹴即至的,它需求不断的练习和磨砺。就像锻炼肌肉一样,只要经过反复的挑战和克服,才能让自己变得更加坚韧。一起,也要学会接受失利和挫折,从中汲取经验教训,不断前行。

战略5:给模型指定完结使命所需的进程

人类在没有足够时刻时核算的答案可能会犯过错。

模型也一样,模型也可能在短时刻内(或少数文字无法完结的使命的情况下)给出过错的答案。

假如模型匆忙得出了过错的定论,您能够测验重新构思查询,请求模型在供给终究答案之前进行一系列相关的推理。

在这些情况下,您能够指示模型花更多时刻思考问题。

下面咱们以一个示例来展示这个进程。

text = f"""
   在一个诱人的村庄里,兄妹杰克和吉尔出发去一个山顶井里吊水。\
   他们一边唱着欢喜的歌,一边往上爬,\
   但是不幸来临——杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。\
   虽然略有些跌伤,但他们还是回到了温馨的家中。\
   虽然出了这样的意外,他们的冒险精力仍然没有减弱,持续充溢愉悦地探究。
    """prompt_1 = f"""
   履行以下操作:
   1、用一句话归纳下面用三个反引号括起来的文本。
   2、将摘要翻译成法语。
   3、在法语摘要中列出每个人名。
   4、输出一个 JSON 对象,其间包括以下键:French_summary,num_names。
​
   请用换行符分隔您的答案。
​
   Text:
   ```{text}```
   """
response_1 = get_completion(prompt_1)
print(response_1)

输出成果:

1、兄妹在山上吊水时发生意外,但仍然坚持冒险精力。
2、Dans un charmant village, les frre et sur Jack et Jill partent chercher de l'eau dans un puits au sommet d'une montagne. Ils chantent joyeusement en montant, mais malheureusement, Jack trbuche sur une pierre et tombe de la montagne, suivi de prs par Jill. Bien qu'ils soient lgrement blesss, ils retournent chez eux chaleureusement. Malgr cet accident, leur esprit d'aventure ne diminue pas et ils continuent  explorer avec joie.
3、Jack, Jill.
4、{"English_summary": "Brother and sister have an accident while fetching water on a mountain but continue to explore with joy.", "num_names": 2}

在吴恩达教师的视频里,这儿的输出认为是有问题的。例如,键“名字”会被替换为法语。

但是由于我不懂法语,也没太理解这儿的问题所在。

吴恩达教师的原始视频中,是经过运用了更好的Prompt,使得模型终究输出了合理的成果。

修改后的Prompt如下:

text = f"""
   在一个诱人的村庄里,兄妹杰克和吉尔出发去一个山顶井里吊水。\
   他们一边唱着欢喜的歌,一边往上爬,\
   但是不幸来临——杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。\
   虽然略有些跌伤,但他们还是回到了温馨的家中。\
   虽然出了这样的意外,他们的冒险精力仍然没有减弱,持续充溢愉悦地探究。
   """prompt_2 = f"""
   履行以下操作:
   1、用一句话归纳下面用<>括起来的文本。
   2、将摘要翻译成英语。
   3、在英语摘要中列出每个人名。
   4、输出一个 JSON 对象,其间包括以下键:English_summary,num_names。
​
   请运用以下格局:
   文本:<要总结的文本>
   摘要:<摘要>
   翻译:<摘要的翻译>
   称号:<英语摘要中的称号列表>
   输出 JSON:<带有 English_summary 和 num_names 的 JSON>
​
   Text:
   ```{text}```
   """response_2 = get_completion(prompt_2)
print(response_2)

输出成果:

摘要:兄妹杰克和吉尔在诱人的村庄里去山顶井吊水,但杰克不幸滚下山来,他们虽然受了些伤,但仍然充溢冒险精力持续探究。
翻译:In a charming village, siblings Jack and Jill set out to fetch water from a well on a mountaintop. While singing joyfully and climbing up, unfortunately, Jack stumbled on a rock and rolled down the mountain, with Jill following closely behind. Despite some injuries, they returned to their cozy home. Despite the mishap, their adventurous spirit remained undiminished, and they continued to explore with joy.
称号:Jack,Jill
输出 JSON:{"English_summary": "In a charming village, siblings Jack and Jill set out to fetch water from a well on a mountaintop. While singing joyfully and climbing up, unfortunately, Jack stumbled on a rock and rolled down the mountain, with Jill following closely behind. Despite some injuries, they returned to their cozy home. Despite the mishap, their adventurous spirit remained undiminished, and they continued to explore with joy.", "num_names": 2}

战略6:引导模型在下定论之前找出一个自己的解法

有时候,咱们让模型直接判别咱们的输入是否正确,模型可能会得到过错的成果。

这时候咱们能够指示模型,不要直接判别咱们的输入,而是先让模型自行回答,再经过对比两个成果,来判别咱们的输入是否正确。

接下来咱们会给出一个问题和一个学生的回答,要求模型判别回答是否正确。

prompt = f"""
   判别学生的处理方案是否正确。
​
   问题:
   我正在建造一个太阳能发电站,需求协助核算财务。
   土地费用:每平方英尺100美元
   太阳能电池板:每平方英尺250美元
   维护费用:每年需求付出固定的100000美元,并额定付出每平方英尺10美元
   作为平方英尺数的函数,首年运营的总费用是多少。
​
   学生的处理方案:
   设x为发电站的巨细,单位为平方英尺。
   费用:
   土地费用:100*x
   太阳能电池板费用:250*x
   维护费用:100000+100*x
   总费用:100*x+250*x+100000+100*x=450*x+100000
   """
  response = get_completion(prompt)
  print(response)
response = get_completion(prompt)
print(response)

输出成果:

该学生的处理方案是正确的。

但是,实践上学生的处理方案实践上是过错的。过错的当地在于:维护费用里每平方英尺是10美元,而学生核算进程过错地写成100*x 了。

咱们能够经过指导模型先自行找出一个解法来处理这个问题。

在接下来这个 Prompt 中,咱们要求模型先自行处理这个问题,再根据自己的解法与学生的解法进行对比,然后判别学生的解法是否正确。

一起,咱们给定了输出的格局要求。经过明晰进程,让模型有更多时刻思考,有时能够取得更准确的成果。

prompt = f"""
   请判别学生的处理方案是否正确,请经过如下进程处理这个问题:
   进程:
   首要,自己处理问题。
   然后将你的处理方案与学生的处理方案进行比较,并评价学生的处理方案是否正确。
   在自己完结问题之前,请勿决定学生的处理方案是否正确。
​
   运用以下格局:
   问题:问题文本
   学生的处理方案:学生的处理方案文本
   实践处理方案和进程:实践处理方案和进程文本
   学生的处理方案和实践处理方案是否相同:是或否
   学生的成果:正确或不正确
​
   问题:
     我正在建造一个太阳能发电站,需求协助核算财务。 
     - 土地费用为每平方英尺100美元
     - 购买太阳能电池板每平方英尺250美元
     - 每年需求付出固定的100000美元,并额定付出每平方英尺10美元
     作为平方英尺数的函数,首年运营的总费用是多少?
​
   学生的处理方案:
     设x为发电站的巨细,单位为平方英尺。
     费用:
     1. 土地费用:100*x
     2. 太阳能电池板费用:250*x
     3. 维护费用:100000+100*x
     总费用:100*x+250*x+100000+100*x=450*x+100000
​
   实践处理方案和进程:
   """
response = get_completion(prompt)
print(response)

终究,依照新的Prompt引导模型先自行处理,再跟校园的成果做对比之后,模型就能发现学生的回答是过错的。

新的正确的输出成果:

实践处理方案:
     设x为发电站的巨细,单位为平方英尺。
     费用:
     1. 土地费用:100*x
     2. 太阳能电池板费用:250*x
     3. 维护费用:100000+10*x
     总费用:100*x+250*x+100000+10*x=360*x+100000
​
   学生的处理方案和实践处理方案是否相同:
     不相同
​
   学生的成果:
     不正确

参考资料:

www.deeplearning.ai/short-cours…