这个由 Isa Fulford (OpenAI) 和 吴恩达 (DeepLearning.AI) 教授的短期课程将描述 LLM 的工作原理,提供即时工程的最佳实践,并展示 LLM API 如何用于各种任务的应用程序,包括: 总结(例如,为简洁起见总结用户评论) 推断(例如,情感分类、主题提取) 转换文本(例如,翻译、拼写和语法更正) 扩展(例如,自动编写电子邮件) 在这个课程中能够学习到,编写有效提示的两个关键原则,即如何系统地设计好的提示,并学习构建自定义聊天机器人。
免费ChatGPT地址:http://ai.mkzero.top:44444/
1.课程简介 首先,你将学习一些软件开发最佳实践的提示。然后,我们将涵盖一些常见的用例,包括总结、推理、转换和扩展。接着,你将使用LLM构建一个聊天机器人。我们希望这会激发你的想象力,并能够创建出新的应用程序。在大型语言模型或LLM的开发中,大体上有两种类型的LLM,我将其称为基础LLM和指令调整后的LLM。 因此,基础LLM已经训练出来根据文本训练数据预测下一个单词。通常是在互联网和其他来源的大量数据上进行训练,以找出接下来最有可能的单词。例如,如果你提示“一次有一个独角兽”,它可能会继续完整这个句子,预测出接下来的几个单词是“和所有的独角兽朋友生活在一个神奇的森林里”。但如果你提示“法国的首都是什么”,那么LLM可能会给出正确的回答“巴黎”,或者可能会给出错误的回答。 基于互联网上的文章,基础LLM有可能会回答法国的最大城市是什么,法国的人口是多少等等。因为互联网上的文章很可能是关于法国的问答列表。相比之下,指令调整后的LLM更接受人们的指令。因此,如果你问它法国的首都是什么,它很可能会输出法国的首都是巴黎。指令调整后的LLM的研究和实践的动量更大。 因此,指令调整后的LLM通常是这样训练的:首先,你从大量文本数据中训练出一个基础LLM,随后使用指令和良好尝试的输入和输出来对其进行微调和优化,然后通常使用称为“人类反馈强化学习”的技术进行进一步细化,以使系统更能够有帮助且能够遵循指令。因为指令调整后的LLM被训练成有用、诚实和无害的,所以它们输出有害文本(如毒性输出)的可能性比基础LLM更小。很多实际的应用场景已开始向指令调整后的LLM转移,而一些在互联网上查到的最佳实践则可能更适用于基础LLM。 对于大多数今天的实际应用,我们建议大多数人应该专注于经过调整的指令语言模型。这些模型更易于使用,而且由于OpenAI和其他LLM公司的工作,它们变得更加安全和更加符合要求。因此,本课程将专注于经过调整的指令语言模型的最佳实践,这是我们建议大多数应用程序使用的模型。
2.提示工程关键原则 你可以在 OpenAI 的网站上获取其中一个 API 密钥。只需要设置你的 API 密钥,然后输入你的 API 密钥。如果你想的话也可以将其设置为环境变量。同时,我们将在本课程中使用 OpenAI 的聊天gpt-3.5-turbo模型. 先安装openai的库。 pip install openai
import openai
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
openai.api_key = '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'
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
)
# print(response) # 我加的方便看这个字典有什么
return response.choices[0].message["content"]
我将概述一些原则和策略,这些原则和策略在使用ChatGBT等语言模型时将非常有用。我将首先对它们进行高层次的概述,然后我们将使用示例应用具体的策略。我们将在整个课程中使用这些相同的策略。因此,对于原则而言,第一个原则是编写清晰具体的指令。第二个原则是给模型充足的时间来思考。 1.原则一编写清晰具体的指令 策略1:使用分隔符 三重引号:""" 三重反引号:``` 三个破折号:---,尖括号:< >,XML标签: 策略2:请求结构化输出HTML、json 策略3:检查是否满足条件。检查执行任务所需的前提条件。 策略4:少量提示 给出完成任务的成功例子,然后要求模型执行任务。 策略1-使用定界符清楚地限定输入的不同部分 我们有一个段落,我们想要实现的任务是对这个段落进行总结。所以在提示中,我说,把总结的句子放到三个反引号中```。为了获得响应,我们只需使用我们的 getCompletion 帮助函数。然后我们只需打印出响应即可。如果我们运行这个程序,你会看到我们收到了一句话的输出,并且我们使用了这些定界符,以使模型非常清楚地了解它应该总结哪些确切的文本。因此,定界符可以是任何明显的标点符号,可以将特定的文本从提示的其余部分分隔开来。
text = f"""
您应该提供尽可能明确和具体的指示,以表达您希望模型执行的操作。\
这将指导模型朝着所期望的输出方向发展,减少接收到无关或不正确的响应的可能性。\
不要混淆编写清晰的提示和编写简短的提示。在许多情况下,更长的提示提供更多的清晰度和上下文,\
从而可以产生更详细和相关的输出。
"""
prompt = f"""
总结由三个反引号分隔符中的文本,变成一句话变成一个句子。
```{text}```
"""
response = get_completion(prompt)
print(response)
这些定界符可以是三个反引号,也可以是引号、XML 标签、节标题或任何能够使模型明确知道这是一个独立部分的东西。如给我总结三个反引号里的东西或给我总结三个破折号里的东西。使用定界符也是一种有用的技术,可以尝试避免提示注入。所谓提示注入,是指如果允许用户向提示中添加一些输入,它们可能会向模型提供一些冲突的指令,从而使模型遵循用户的指令而不是执行你所期望的操作。
策略2-要求结构化输出 下一个策略是请求结构化输出。为了使解析模型输出更容易,请求HTML或JSON等结构化输出是有帮助的。在提示中,我们说,生成三个虚构的图书标题,以及它们的作者和流派,使用以下键名以JSON格式提供:书籍ID、标题、作者和流派。你可以看到,我们有三个虚构的书名,用这种漂亮的JSON结构化输出格式化。而这件好事是你实际上可以在 Python 中将其读入字典或列表中。输出json格式的好处就不用我多说了吧。
prompt = f"""
生成三本虚构书籍的书名、作者和类型的列表。
以 JSON 格式提供此列表,使用以下键:book_id、title、author、genre。
"""
response = get_completion(prompt)
print(response)
效果不错 策略3-要求模型检查是否满足条件 下一个策略是要求模型检查是否满足条件。如果任务有假设条件并且这些条件不一定被满足,那么我们可以告诉模型首先检查这些假设条件,如果不满足则指示出来,并停止完全的任务完成尝试。你还应该考虑潜在的边缘情况以及模型如何处理它们,以避免意外的错误或结果。现在我将复制一段描述如何泡茶的段落,然后复制我们的提示。因此,提示是,如果文本包含一系列指示,请将这些指示重写为以下格式,然后写出步骤说明。如果文本不包含一系列指示,则只需写下“未提供步骤”。如果我们运行这个 cell,你会看到模型能够从文本中提取出指示。现在,我将尝试在不同的段落中使用相同的提示。 [!TIP] 尽量不要用"""三个引号还得写转义符
text_1 = f"""
泡一杯茶很简单!首先,你需要把一些水烧开。在那个时候, \
拿一个杯子并在里面放入一个茶包。一旦水足够热, \
就把它倒在茶包上。让它浸泡一段时间,以便茶叶可以浸泡。过一 \
几分钟后,取出茶包。如果你喜欢,你可以加一些糖或者牛奶来调味。 \
就这样!你有了一杯可口的茶可以享用了。
"""
prompt = f"""
提供给你一个由三重引号分隔的文本。
如果它包含一系列的说明,请按以下格式重新编写这些说明:
步骤 1 - ...
步骤 2 - ...
…
步骤 N - ...
如果文本不包含一系列的说明,则只需写“未提供步骤”。
\"\"\"{text_1}\"\"\"
"""
response = get_completion(prompt)
print("Completion for Text 1:")
print(response)
这段文字是在描述一个阳光明媚的日子,没有任何指令。如果我们使用之前用过的提示,并在这段文本上运行,那么模型会尝试提取指令。如果没有找到,我们会要求其简单地说“没有提供任何步骤”。所以我们现在运行它,模型认定第二段没有指令。因此,我们的最后一种策略就是我们所称的“小批量提示”,就是在要求模型完成实际任务之前提供执行任务的成功示例。
text_2 = f"""
今天阳光明媚,鸟儿在歌唱。这是去公园散步的美好日子。花儿正在盛开,树木在微风中轻轻摇曳。人们在外面玩耍,享受美好的天气。有些人在野餐,有些人在玩游戏,还有些人在草地上放松。这是一个完美的日子,可以在户外度过,并欣赏大自然的美丽。
"""
prompt = f"""
您将获得由三个引号分隔的文本。
如果其中包含一系列指令,请按以下格式重写这些指令:
步骤1-...
步骤2-…
…
步骤N-…
如果该文本不包含一系列指令,则只需编写“未提供步骤”。
\"\"\"{text_2}\"\"\"
"""
response = get_completion(prompt)
print("Completion for Text 2:")
print(response)
这效果很棒!! 策略4-小批量提示 这里我来举一个例子。对于这个提示,我们告诉模型它的任务是以一致的风格回答问题,我们提供了一个孩子和祖父之间的对话示例。孩子说:“教我耐心”,祖父用类比的方式回答。既然我们要求模型用一致的语气回答,现在我们说:“教我关于韧性”。由于模型已经有了这个少量示例,它会用类似的语气回答下一个任务。它会回答韧性就像能被风吹弯却从不折断的树等等。这些是我们针对第一个原则的四种策略,即给模型明确具体的指令。
prompt = f"""
Your task is to answer in a consistent style.
<child>: Teach me about patience.
<grandparent>: The river that carves the deepest \
valley flows from a modest spring; the \
grandest symphony originates from a single note; \
the most intricate tapestry begins with a solitary thread.
<child>: Teach me about resilience.
"""
response = get_completion(prompt)
print(response)
原则2-给模型充足的思考时间 第二原则是给模型充足的思考时间。如果模型由于急于得出错误的结论而出现了推理错误,您可以尝试重新构造查询,要求模型在提供最终答案之前进行一系列相关推理。另一种思考方式是,如果您给模型一个时间太短或用太少的字数来完成的任务,它可能会猜测答案,这个答案很可能是错误的。你知道,这对一个人来说也一样。如果你让某人在没有时间计算出答案的情况下完成一道复杂的数学题,他们很可能会犯错。所以在这些情况下,您可以指示模型多花时间思考问题,这意味着它在任务上花费更多的计算力。现在我们将介绍第二原则的一些策略,并进行一些例子。我们的第一个策略是明确说明完成任务所需的步骤。 策略5-指定完成任务的步骤 首先,让我复制一段文字。这是一个描述杰克和吉尔(Jack and Jill)故事的段落。现在我将复制一个提示。在这个提示中,指令是执行以下动作:第一,用一句话总结由三个反引号包围的文本。第二,将摘要翻译成法语。第三,列出法语摘要中的每个名字。第四,输出一个JSON对象,包含以下键:法语摘要和名称数。然后我们希望用换行符分隔答案。因此,我们添加文本,就是这个段落。 那么,如果我们运行这个代码。如你所见,我们得到了摘要文本,然后是法语翻译,接着是名称。有趣的是,它给这些名称在法语中加了一些头衔。接着我们得到了我们请求的JSON数据。
text = f"""
在一个迷人的村庄里,兄妹杰克和吉尔出发前往山顶的水井取水。他们一边唱歌欢快地爬山,一边不幸地发生了意外——杰克绊了一块石头,滚下了山坡,吉尔也跟着摔倒了。尽管轻微受伤,他们还是回到了家里得到了安慰的拥抱。尽管发生了不幸的事情,他们的冒险精神仍然没有减退,他们继续愉快地探险。
"""
# 例子1
prompt_1 = f"""
执行以下操作:
1 - 用1个句子概括由三个反引号分隔的以下文本。
2 - 将摘要翻译成法语。
3 - 列出法语摘要中的每个名字。
4 - 输出一个json对象,其中包含以下键:french_summary,num_names。
用换行符分隔您的答案。
文本:
```{text}```
"""
response = get_completion(prompt_1)
print("prompt_1的自动补全:")
print(response)
ChatGPT这效果真不错,什么都不用干自动完成这个教程。 现在我将展示给你们另一个提示来完成同样的任务。在这个提示中,我使用了一个我相当喜欢的格式来指定模型输出结构,因为正如你在这个例子中所注意到的,这种名称的头衔是用法语的,这可能不是我们想要的。如果我们将此输出传递出去,这可能会有一些困难和不可预测性。因此,在这个提示中,我们询问的是类似的事情。提示的开头是一样的。我们只是要求同样的步骤。然后我们要求模型使用以下格式。因此,我们只是指定了确切的格式。
prompt_2 = f"""
你的任务是执行以下操作:
1 - 用一句话概括以下用尖括号<>括起来的文本。
2 - 将概括翻译成法语。
3 - 列出法语概括中的每个名字。
4 - 输出一个JSON对象,包含以下键:french_summary,num_names。
使用以下格式:
文本: <要概括的文本>
概括: <概括>
翻译: <概括翻译>
名字: <意大利概括中的名字列表>
输出JSON: <具有摘要和num_names的JSON>
文本:<{text}>
"""
response = get_completion(prompt_2)
print("\nPrompt 2的回答:")
print(response)
策略6-指导模型(在急于得出结论之前)制定自己的解决方案 接下来,我们的策略是指导模型在作出结论之前自行解决问题。有时,我们明确指导模型在做出结论之前自行推理出解决方案,会得到更好的结果,这和之前提到的给模型时间思考问题,不要急于下结论的概念相同。因此,在这个问题中,我们要求模型确定学生的解决方案是否正确。 首先,我们有一个数学问题,然后我们有学生的解决方案。实际上,学生的解决方案是错误的,因为他们将维护成本计算为100,000加上100x,但实际上应该是10x,因为每平方英尺只有10美元,其中x是他们定义的安装面积。因此,这实际上应该是360x加上100,000,而不是450x。如果我们运行这个单元格,模型会说学生的解决方案是正确的。如果你仔细阅读学生的解决方案,你甚至会发现我在仔细阅读后也算错了,因为它看起来是正确的。如果你仅仅阅读这一行,这一行是正确的。因此,模型只是与学生意见一致,因为它只是浏览了一遍这个问题,就像我刚才所做的那样。因此,我们可以通过指导模型自行解决问题,然后将其解决方案与学生的解决方案进行比较来解决这个问题。
prompt = f"""
判断学生的解决方案是否正确。
问题:
我正在建造一个太阳能发电安装,并需要帮助解决财务问题。
土地成本为每平方英尺100美元
我可以购买每平方英尺250美元的太阳能电池板
我谈判了一份维护合同,每年将花费100,000美元,以及每平方英尺额外的10美元
作为第一年运营的总成本的函数,总共需要多少费用?
学生的解决方案:
设x为安装的面积(平方英尺)。
成本:
土地费用:100x
太阳能电池板费用:250x
维护成本: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)
3.提示工程需要迭代 当您编写使用OOM开发应用程序的提示时,该流程可能会非常类似,您有一个想法,想要完成的任务,然后可以尝试编写第一个提示,希望它的表述清晰具体,并且如果合适,可以给系统一些时间进行思考,然后运行它并查看结果。如果第一次效果不好,则迭代的过程中可以找出原因,例如:指示不够清晰或算法没有足够的时间进行思考,从而充实思路、改进提示,如此循环多次,直到开发应用程序所需的提示得以完成。 这也是为什么我个人没有过多关注互联网文章中的“30个完美提示”的原因,因为我认为可能没有适用于所有情况的完美提示。开发一个适用于您特定应用程序的好提示的流程比任何其他事情都更重要。 让我们一起在代码示例中看一个例子。 介绍了椅子的制造方式、尺寸、选项、材料等问题。这款椅子来自意大利。假设你想拿这张信息单来帮助营销团队编写一个在线零售网址的描述,像这样……我将它粘贴进来,所以我的提示是:您的任务是基于技术信息单,帮助营销团队为零售网站或产品创建描述,撰写产品描述等。对吧?这是我第一次尝试向大型语言模型解释这个任务。所以,我按下Shift Enter,这需要几秒钟的时间来运行,我们得到了这个结果。它看起来做得很好,写了一个描述,介绍了一个令人惊叹的中世纪灵感办公椅,完美的版本等等,但当我看到这个结果时,我会说,哇,这真的很长。它做得非常好,准确地完成了我所要求的工作,也就是从技术信息单入手撰写产品描述。
In [ ]:
fact_sheet_chair = """ 概述 是一款美丽的中世纪风格家具系列的一部分,包括文件柜、书桌、书架、会议桌等。 有几种壳体颜色和底座饰面的选择。 提供塑料后背和前面的软垫(SWC-100)或10种面料和6种皮革的全套软垫(SWC-110)。 底座饰面选项包括:不锈钢、哑光黑色、光泽白色或铬。 椅子可以有扶手或没有扶手。 适用于家庭或商业环境。 适合合同使用。 构造 5个轮子的塑料涂层铝制底座。 气动椅子调节,方便升降操作。 尺寸 宽度53厘米| 20.87英寸 深度51厘米| 20.08英寸 高度80厘米| 31.50英寸 座位高度44厘米| 17.32英寸 座位深度41厘米| 16.14英寸 选项 软地板或硬地板轮轴选项。 两种座椅泡沫密度选择:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺)。 无扶手或8个位置PU扶手 材料 壳体底座滑轮 改进的尼龙PA6 / PA66涂层铸铝。 壳体厚度:10毫米。 座位 HD36泡沫 原产国 意大利 """
fact_sheet_chair = """
概述
是一款美丽的中世纪风格家具系列的一部分,包括文件柜、书桌、书架、会议桌等。
有几种壳体颜色和底座饰面的选择。
提供塑料后背和前面的软垫(SWC-100)或10种面料和6种皮革的全套软垫(SWC-110)。
底座饰面选项包括:不锈钢、哑光黑色、光泽白色或铬。
椅子可以有扶手或没有扶手。
适用于家庭或商业环境。
适合合同使用。
构造
5个轮子的塑料涂层铝制底座。
气动椅子调节,方便升降操作。
尺寸
宽度53厘米| 20.87英寸
深度51厘米| 20.08英寸
高度80厘米| 31.50英寸
座位高度44厘米| 17.32英寸
座位深度41厘米| 16.14英寸
选项
软地板或硬地板轮轴选项。
两种座椅泡沫密度选择:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺)。
无扶手或8个位置PU扶手
材料
壳体底座滑轮
改进的尼龙PA6 / PA66涂层铸铝。
壳体厚度:10毫米。
座位
HD36泡沫
原产国
意大利
"""
Issue 1: 文本过长 但是当我看到结果时,我会说,这结果太长了。也许我们希望它短一点。那么,我有了一个想法。我写了一条提示,得到了结果。但是我对结果不是很满意,因为它太长了,所以我将澄清我的提示,并说使用最多50个单词来尝试更好地指导所需的长度,并让我们再次运行它。好的,这看起来是一个非常好的产品简短描述,介绍了一个中世纪灵感的办公椅等等,是一个既时尚又实用的椅子。不错。让我再次检查一下它的长度。所以我将回答分割成单词,然后打印出长度。它是52个单词,其实不错。大型语言模型在遵循非常精确的单词计数方面不是那么出色,但它实际上表现得不错。有时它会打印出60或65个单词的内容,但它是合理的。其中一些我再跑一次。
prompt = f""" 您的任务是帮助市场团队根据技术规格说明书创
建产品的零售网站描述。 根据技术规格书提供的信息编写产品描述,规格书用三个反
引号分隔。 请使用不超过50个词。 技术规格: ```{fact_sheet_chair}``` """
response = get_completion(prompt)
print(response)
len(response)
Issue 2. 文字关注错误的细节 但是这些是告诉大型语言模型你想要的输出长度的不同方式。所以这是一种,两种,三种。我数了一下这些句子。看起来我做得相当不错。然后我还看到有人有时会做一些事情,比如说,不知道,最多使用280个字符。大型语言模型,由于它们解释文本的方式,使用一种称为分词器的东西,我不会讲。但是它们倾向于在计算字符数量方面表现一般。但是,看看281个字符。这实际上相当接近。通常情况下,大型语言模型不太可能准确预测长度。但这些是他们可以玩耍的不同方式,以尝试控制您获得的输出长度。但是,只需将其切换回最多使用50个单词即可。那就是我们刚才得到的结果。随着我们继续为网站完善这段文本,我们可能会决定,哇,这个网站并不是直接面向消费者销售,实际上是旨在向家具零售商销售家具,他们更关注椅子的技术细节和椅子的材料。 在这种情况下,您可以采取这个提示并说,我想修改这个提示,使其更加精确地描述技术细节。所以让我继续修改这个提示。我会说,这种描述是为家具零售商而设计的,因此它应该是技术性的,重点是材料、产品和构造。嗯,让我们运行一下。让我们看看。还不错。它说,铝制底座和气动椅。高质量的材料。所以通过改变提示,您可以使其更加专注于您想要的特定特征。当我看到这个时,我可以决定,在描述的末尾,我也想包括产品ID。所以这把椅子有两种款式,其中 SWC 110 和 SOC 100 。
prompt = f""" 你的任务是帮助市场团队基于技术规格说明
书为一个产品创建一个零售网站描述。 根据技术规格说明书
提供的信息编写产品描述,技术性较强,重点关注产品的材料构造。 使
用不超过50个单词。 技术规格说明书: ```{fact_sheet_chair}``` """
response = get_completion(prompt)
print(response)prompt = f""" 你的任务是帮助市场团队基于技术规格说明书为
一个产品创建一个零售网站描述。 根据技术规格说明书提供的信息编写产品描述
,技术性较强,重点关注产品的材料构造。 在描述的最后,列出技术规格说明书中每个7个字符的
产品ID。 使用不超过50个单词。 技术规格说明书: ```{fact_sheet_chair}``` """
response = get_completion(prompt)
print(response)
Issue 3. 描述需要一个规模表 所以也许我可以进一步改进这个提示。为了让它给我产品ID,我可以在描述的末尾添加这个指令:在技术规格中包括每7个字符一个产品ID。让我们运行一下,看看会发生什么。它说,向您介绍我们的中世纪风格办公椅,外壳颜色,讨论塑料涂层铝制底座,实用,一些选项,讨论两种产品ID。所以这看起来相当不错。您刚刚看到的是许多开发人员将经历的迭代提示开发的一个简短示例。
prompt = f""" 您的任务是帮助一支市场团队创建一篇产品描述,用技术说明书为依据。 根据
技术规格说明提供的信息编写产品描述,技术性较强,并且要侧重于产品构造材料。 在描述的末尾,包
括技术规格说明书中每个7个字符的产品ID。 在描述后,包括一个表格,其中包含产品的尺寸详细信息。该
表格应有两列,第一列包含尺寸名称,第二列包含英寸为单位的尺寸测量值。将表格格式化为HTML以在网站
上使用,表格应该具有“产品尺寸”这个标题。 技术规格说明书:```{fact_sheet_chair}``` """ response = get_completion(prompt) print(response)
4.总结类应用 我经常会这样做来总结文章,这样我就可以阅读更多文章的内容,而不仅仅是以前能读的那么少。如果你想以更加机械化的方式实现这一点,你可以在这节课中看到如何做到这一点。所以,让我们深入了解代码,看看你如何使用它来总结文本。 4.1 文字总结
prod_review = """ 我为我女儿的生日买了这个熊猫毛绒玩具,她非常喜欢,到处都带着它。它很柔软、超级可爱,脸上看起来很友好。但是相对于我花的钱,它有点小了。我认为可能有其他同等价格但更大的选项。它比预期的早了一天送到,所以在我把它送给女儿之前,我也玩了一下。 """
prompt = f""" 您的任务是从电子商务网站上生成一个产品评论的简短摘要。 请用不超过30个单词的信息总结下面的评论(用三个反引号括起来)。 评论:```{prod_review}``` """ response = get_completion(prompt) print(response)
4.2 针对某种信息总结
prompt = f""" 您的任务是从电子商务网站上生成一个产品评论的简短摘要,以便给物流部门反馈。 请用不超过30个单词的信息总结下面的评论(用三个反引号括起来),并重点关注提到产品的物流和交付方面的任何方面。 评论:```{prod_review}``` """ response = get_completion(prompt) print(response)
4.3 尝试“提取”而不是“总结”
prompt = f"""您的任务是从电子商务网站的产品评论中生成一个简短的摘要,以便向定价部门提供反馈,该部门负责确定产品的价格。
请总结以下评论(使用三个反引号括起来),不超过30个词,并关注与价格和感知价值相关的任何方面。
评论: ```{prod_review}```"""
response = get_completion(prompt)print(response)
4.4 针对多项信息总结
review_1 = prod_review
# 立灯的评论review_2 = """我需要一个漂亮的卧室灯,这个灯有额外的存储功能,价格也不太高。 得到得很快--2天内到货。 灯的绳索在运输过程中断了,但公司愉快地发送了一个新的灯绳。 也在几天内到达。 很容易安装。 然后我缺少一个零件,所以我联系了他们的支持部门,他们非常快地为我提供了缺失的零件! 对我来说,这是一个关心客户和产品的好公司。"""
# 电动牙刷的评论review_3 = """我的牙医建议我使用电动牙刷,这就是我买这个的原因。 到目前为止,电池寿命似乎相当不错。 经过初始充电和在第一周将充电器插上电源以调节电池之后,我已经拔下了充电器,并在最近的3周内每天早晚使用了它,全部使用同一次充电。 但是,牙刷头太小了。 我见过比这个更大的婴儿牙刷。 我希望头更大,有不同长度的毛刷,以更好地清洁牙齿,因为这个不行。 总的来说,如果您可以在50美元左右获得这个牙刷,这是一个不错的交易。 制造商的替换头非常昂贵,但您可以获得更合理的通用头。 这个牙刷让我感觉每天都去了一次牙医。 我的牙齿感觉闪闪发光! """
# 搅拌器的评论review_4 = """因此,他们在11月份的季节性销售中仍然以约49美元的价格销售17件套装,大约半价,但由于某种原因(称之为价格抬高),到了12月的第二个星期,所有价格都上涨到了70-89美元之间,对于相同的系统。 同样,11件套装的系统的价格也比早期的29美元上涨了约10美元左右。 因此,它看起来还不错,但是如果您看基础部分,刀锁定的部分看起来不如几年前的早期版本那么好,但我打算非常小心(例如,我先在搅拌器中压碎非常硬的物品,例如豆子,冰块,大米等,然后将它们粉碎成我想要的份量,然后在需要时切换到搅拌刀片,制作更细的面粉,并且在制作冰沙时首先使用交叉切割刀片,然后使用平刀片,如果我需要更细/不那么果肉)。 制作冰沙时,特别提示,将要使用的水果和蔬菜切成细小的块并冷冻(如果使用菠菜-轻轻炖软菠菜,然后冷冻直到使用)-如果制作水果冰沙,则可以避免添加太多冰-制作您的冰沙。 大约一年后,电机发出奇怪的声音。 我打电话给客户服务,但保修已经过期,所以我不得不再买一个。 FYI:这些产品的整体质量有所下降,因此他们有点依靠品牌认可和消费者忠诚度来维持销售。 大约两天到手。"""
reviews = [review_1, review_2, review_3, review_4]for i in range(len(reviews)): prompt = f""" 您的任务是从电子商务网站的产品评论中生成一个简短的摘要。
请在以下评论中生成一个包含不超过20个单词的摘要,使用三个\ 反引号分隔。
评论: ```{reviews[i]}``` """
response = get_completion(prompt) print(i, response, "\n")
5.推理类应用 如果你想要从一段文本中提取情感,无论是积极的还是消极的,在传统的机器学习工作流程中,你需要收集标签数据集、训练模型、找出如何在云端部署模型并进行推断。这样做可能效果不错,但需要完成很多繁琐的工作。而且对于每个任务,如情感分析、提取名称或其他任务,你都需要训练并部署单独的模型。 大语言模型的一个非常好的特点是,对于许多这样的任务,你只需要编写提示即可开始生成结果。这极大地提高了应用开发的速度。而且你只需要使用一个模型、一个API来完成许多不同的任务,而不需要找出如何训练和部署许多不同的模型。 5.1 产品评价文本情感分类 如果我想让系统告诉我,你知道的,这个评论的情感是什么
lamp_review = """我需要一个漂亮的台灯放在卧室里,这个台灯不仅有额外的储物功能,价格也不算太高。非常迅速就收到了货。在运输过程中,我台灯的拉线断了,但公司很高兴地给我们送来了一根新的。几天之内就到了。这个台灯很容易组装。我遗失了一个零件,所以我联系了他们的支持团队,他们非常快地给我补发了漏发的部分!Lumina对客户和产品都非常关心。
"""prompt = f"""以下是一个被三个反引号包围的产品评论,请判断该评论的情感极性:
评论内容:'''{lamp_review}'''"""response = get_completion(prompt)print(response)
5.2 文本情感分类 你可能有一个不同的分类问题,如下。这篇评论的作者是在表达愤怒吗?因为如果有人真的生气了,那可能就值得更加关注,建立客户评论、客户支持或成功的通道,以了解情况并为客户解决问题。 请注意,如果我想要用监督学习来构建所有这些分类器,那么在你看到我在视频中所做的几分钟内,我不可能通过监督学习完成这项任务。
prompt = f"""请分析以下产品评论作者所表达的情感,将情感列表控制在五个以下。回答格式为小写单词列表,用逗号分隔。
评论内容:'''{lamp_review}'''"""response = get_completion(prompt)print(response)prompt = f"""请判断以下产品评论作者是否表达了愤怒情绪?该评论使用三个反引号作为分隔符,请用“是”或“否”回答。
评论内容:'''{lamp_review}'''"""response = get_completion(prompt)print(response)
5.3 文本信息提取 让我展示一些你可以通过这个系统做的更多事情,特别是从客户评论中获取更丰富的信息。信息抽取是自然语言处理中的一部分,与从文本中提取你想要的信息有关。因此,在这个提示中,我要求它识别以下项目:购买的商品和制造商品的公司名称。如果你正在尝试总结来自在线购物电子商务网站的许多评论,可能需要你的大量评论来确定商品名称、制造商名称、正面和负面情感,以跟踪各个商品或制造商的积极或消极趋势。 在这个例子中,我将要求它将响应格式化为JSON对象,并将商品和品牌作为键。于是,如果我这样做,它说商品是台灯,品牌是Luminar,你可以轻松地将其加载到Python字典中,然后对此输出进行额外的处理。在我们通过的示例中,你看到如何编写提示来识别情感、确定是否有人生气,并提取商品和品牌。
prompt = f"""从评论文本中识别以下项目:- 评论者购买的物品- 制造该物品的公司
评论使用三个反引号分隔。将您的响应格式化为 JSON 对象,键为“Item”和“Brand”。如果没有相关信息,请将值设为“unknown”。尽可能简洁地回答。评论文本:'''{lamp_review}'''"""response = get_completion(prompt)print(response)prompt = f"""从评论文本中识别以下项目:- 情感极性(积极或消极)- 评论者是否表达了愤怒?(是或否)- 评论者购买的物品- 制造该物品的公司
评论使用三个反引号分隔。将您的响应格式化为 JSON 对象,键为“Sentiment”、“Anger”、“Item”和“Brand”。如果没有相关信息,请将值设为“unknown”。尽可能简洁地回答。将愤怒值格式化为布尔值。
评论文本:'''{lamp_review}'''"""response = get_completion(prompt)print(response)
6.转换类应用 大型语言模型非常擅长将其输入转换为不同的格式,例如将一种语言中的文本输入并将其转换或翻译成另一种语言,或帮助拼写和语法矫正,因此,您可以输入一段可能不完全符合语法规范的文本,并帮助你稍微修改一下,或者甚至转换格式,例如输入HTML并输出JSON。因此,我以前用一堆正则表达式写的一堆应用程序现在肯定可以更简单地实现,只需要使用一个大型语言模型和几个提示即可。大型语言模型可以使这些转换过程更加简单和高效,为人们提供更好的文本相关应用体验。 6.1 翻译任务 接下来我们将执行一个翻译任务。因此,大型语言模型是在很多来源的文本上进行训练的,其中很多是互联网的内容,并且这些文本内容是以许多不同的语言呈现的。这种训练使模型具有进行翻译的能力。这些模型能够以不同程度掌握数百种语言,因此我们将讨论如何使用这种能力的一些示例。
prompt = f"""将以下英文文本翻译成中文:\```Hi, I would like to order a blender``` """response = get_completion(prompt)print(response)prompt = f"""告诉我下面这句话是哪种语言:```Combien coûte le lampadaire?```"""response = get_completion(prompt)print(response)
6.2 通用翻译器 模型还可以同时进行多个翻译。在这个例子中,让我们假设,将以下文本翻译成法语和西班牙语。您知道吗,让我们再加上一个英语语。文本是,我想订购一个篮球。因此,我们拥有法语、西班牙语和英语语。
user_messages = [ "La performance du système est plus lente que d'habitude.", # System performance is slower than normal "Mi monitor tiene píxeles que no se iluminan.", # My monitor has pixels that are not lighting "Il mio mouse non funziona", # My mouse is not working "Mój klawisz Ctrl jest zepsuty", # My keyboard has a broken control key "我的屏幕在闪烁" # My screen is flashing]
for issue in user_messages: prompt = f"Tell me what language this is: ```{issue}```" lang = get_completion(prompt) print(f"Original message ({lang}): {issue}")
prompt = f""" Translate the following text to English \ and Korean: ```{issue}``` """ response = get_completion(prompt) print(response, "\n")
6.4 格式转换 那么,让我们看一些例子。在第一个例子中,提示是将以下俚语翻译成商务书信。兄弟,这是乔,看看这盏落地灯的规格。那么,让我们执行它。正如你所看到的,我们有了一封更为正式的商业信函,附有一份关于落地灯规格的提议。接下来,我们要做的事情是在不同的格式之间进行转换。ChatGBT非常擅长在不同的格式之间进行翻译,例如JSON到HTML,XML等各种格式。Markdown。因此,在提示中,我们将描述输入和输出格式。这是一个例子。我们有一个包含餐厅员工姓名和电子邮件的JSON列表。然后在提示中,我们要求模型将它从JSON转换为HTML。
data_json = { "resturant employees" :[ {"name":"Shyam", "email":"shyamjaiswal@gmail.com"}, {"name":"Bob", "email":"bob32@gmail.com"}, {"name":"Jai", "email":"jai87@gmail.com"}]}
prompt = f"""将以下Python字典从JSON格式转换成HTML表格,并加上列标题和表格标题:{data_json}"""response = get_completion(prompt)print(response)
from IPython.display import display, Markdown, Latex, HTML, JSONdisplay(HTML(response))
7.扩展类应用 我们还将使用模型的另一个输入参数,称为温度,这允许你变化模型响应的探索程度和多样性的程度。所以让我们开始吧。在我们开始之前,我们将进行通常的设置。 7.1 自定义对客户电子邮件的自动答复 现在,我们将使用语言模型根据客户评价和评价情感生成一封定制的电子邮件。所以,我们已经使用类似于推断视频中看到的提示提取了情感,这是一款搅拌机的客户评论,现在我们将基于情感定制回复。指令是:作为一个客户服务AI助手,您的任务是发送一封电子邮件答复您的客户,给出分隔符为三个后引号的客户电子邮件并生成一个感谢客户评论的回复。 如果情感是积极的或中性的,感谢他们的评论。如果情感是消极的,道歉并建议他们可以联系客户服务。请确保使用评论中的具体细节,用简洁和专业的语气编写并签署成AI客户代理。当您使用语言模型生成要显示给用户的文本时,让用户知道他们看到的文本是由AI生成的,这种透明度非常重要。然后,我们将输入客户评论和评论情感。还要注意,这部分不一定重要,因为我们实际上可以使用此提示来提取评论情感,然后在后续步骤中编写电子邮件。但为了举例说明,我们已经从评论中提取了情感。 因此,我们给客户做出了回复。回复也解决了客户在评论中提到的细节问题,并且像我们指示的那样建议他们联系客户服务,因为这只是一个AI客户服务代理。接下来,我们将使用语言模型的一个参数称为“温度”,这将允许我们改变模型回答的多样性。因此,您可以将温度看作是模型探索程度或随机性的程度。对于这个特定短语,“我最喜欢的食物”是模型预测的下一个最有可能的词是“比萨”,第二个可能是“寿司”和“塔可”。
因此,在温度为零时,模型总是会选择最有可能的下一个词,这种情况下是“比萨”,而在较高的温度下,它也会选择其中一个可能性较小的词,而在更高的温度下,它甚至可能会选择“塔可”,这种情况下只有五个百分点的机会被选择。您可以想象,随着模型继续生成更多单词,这个最后的回答,“我最喜欢的食物是比萨”,它将会偏离第一个回答“我最喜欢的食物是塔可”。
sentiment = "消极"
review = f"""所以,他们仍然在11月的季节性促销中以约49美元的价格出售17件套装,\折扣约一半,但出于某种原因(称其为价格抬高),到了12月的第二周,\相同的系统的价格全都涨到了70至89美元左右。\11件套的价格也比之前的29美元上涨了约10美元。\所以看起来还不错,但是如果你看到底座,刀锁定的部分看起来没有\之前几年前的版本那么好,但我打算对它非常温柔\(例如,我用搅拌器先碾碎硬的东西,比如豆子、冰、米等等,\然后在搅拌器中将它们粉碎到我想要的份量,\然后换成打蛋器,制作更细的面粉,在制作冰沙时,\先用十字切割刀,然后用平刀将其搅打得更细或者没有果肉)。\制作冰沙或者冰激凌的时候,将水果和蔬菜切碎并冷冻\(如果使用菠菜-轻微炖软菠菜,然后冷冻,\直到需要使用-如果制作蜜饯,使用一个小到中等大小的食品处理器)\这样你就可以避免加入过多的冰-当制作你的冰沙时。\大约一年后,电机发出奇怪的声音。我打电话给客户服务,\但保修已经过期了,所以我不得不再买一个。\FYI:这些产品的整体质量已经下降,所以他们在品牌认知和消费者忠诚度上\维持销售。两天后拿到了它。"""
prompt = f"""您是一名客服 AI 助手。您的任务是向重要客户发送一封电子邮件回复。给定客户电子邮件,您的任务是生成一封答复,感谢客户的评论。如果情感是积极的或中立的,请感谢他们的评论。如果情感为负面,请道歉并建议他们可以联系客户服务。请务必使用评论中的具体细节。以简洁、专业的语气写作。以 AI客户代理 的身份签署电子邮件。客户评论:{review}评论情感:{sentiment}"""response = get_completion(prompt)print(response)
8.打造聊天机器人 我将更详细地描述OpenAI ChatCompletions格式的组件,然后您将自己构建一个聊天机器人。聊天模型(如ChatGPT)实际上是被训练成将一系列消息作为输入,并返回由模型生成的消息作为输出。 第一个是我们在所有视频中都使用的 getCompletion 函数。但是,如果你仔细看一下,我们给出了一个提示,但实际上在函数内部,我们是将这个提示放置到类似用户消息的消息中。这是因为 ChatGPT 模型是一个聊天模型,意味着它被训练成将一系列消息作为输入,然后返回一个由模型生成的消息作为输出。因此,用户消息是输入,而助手消息是输出。 第二个辅助函数是 generateResponse。这个函数将接受一个用户消息,并生成一个 ChatGPT 模型生成的相应助手消息。 通过这两个函数,我们能够与 AIGPT 模型进行交互并生成对话。
您可以将其视为向助手耳语并引导其响应,而用户不会注意到系统消息。所以,作为用户,如果您曾经使用过 ChatGPT,您可能不知道 ChatGPT 的系统消息中包含什么,这也是有意的。系统消息的好处是,它为开发者提供了一种在不使请求本身成为对话一部分的情况下,为对话定框架的方式。因此,您可以在不让用户察觉的情况下引导助手并指导它的回复。现在,让我们尝试使用这些消息来进行对话。我们将使用新的辅助函数从这些消息中获取完成结果。同时,我们还使用了更高的温度。系统消息中说,您是一个像莎士比亚一样说话的助手。 因此,在交互中,我们可以使用这个系统消息来影响助手的回复,从而使对话更加自然流畅,同时又避免在对话中插入明显的提示信息。 他写的有点啰嗦,就是一个不断增长数组,有三个角色,用户,助理,系统。然后从上下文学习回答。 8.1 对话助手 这是我们告诉助手它应该如何行事。然后,第一个用户消息是“告诉我一个笑话”。接下来的消息是“为什么小鸡过马路?”最后一个用户消息是“我不知道”。如果我们运行这个程序,响应是“为了到达另一边”。让我们再试一次。为了到达另一边,夫人,请原谅,这是一个永不过时的经典。这就是我们的莎士比亚式回应。让我们再尝试一件事,因为我想让它更清晰,这是助手的消息。因此,让我们将整个消息响应打印出来。为了使这更清晰,这个响应是一条助手消息。因此,角色是助手,内容是消息本身。这就是这个辅助函数中发生的事情。现在让我们做另一个例子。 在这个例子中,我们将使用 getCompletion 函数来发送一条系统消息和一个用户消息,然后获取助手的响应。 这里,我们的信息有两条,一条是助手的信息:你是一个友好的聊天机器人,另一条信息是用户的第一条反馈:嗨,我的名字是伊莎。我们想要获取用户的第一条信息。所以,让我们执行一下第一条助手信息。第一条反馈是:你好伊莎,很高兴见到你。你今天需要我的帮助吗?现在,让我们尝试另一个例子。这里我们的信息还是有两条,一条是系统信息:你是一个友好的聊天机器人,另一条信息是第一条用户反馈:是的,你能提醒我我的名字是什么吗?我们想要得到回应。然而,你会发现,这个模型实际上还不知道我的名字。所以,每一次与语言模型的交互都是独立的。这意味着,在当前的交互中,你必须提供所有相关的信息,供模型从中获取。如果你想让模型在交互中从先前的对话中获取信息,你必须将之前的对话作为输入提供给模型,我们称之为“上下文”。
def get_completion_from_messages(messages, model="gpt-3.5-turbo", temperature=0): response = openai.ChatCompletion.create( model=model, messages=messages, temperature=temperature, # this is the degree of randomness of the model's output )# print(str(response.choices[0].message)) return response.choices[0].message["content"]messages = [ {'role':'system', 'content':'You are an assistant that speaks like Shakespeare.'}, {'role':'user', 'content':'tell me a joke'}, {'role':'assistant', 'content':'Why did the chicken cross the road'}, {'role':'user', 'content':'I don\'t know'} ]response = get_completion_from_messages(messages, temperature=1)print(response)messages = [ {'role':'system', 'content':'You are friendly chatbot.'}, {'role':'user', 'content':'Hi, my name is Isa'} ]response = get_completion_from_messages(messages, temperature=1)print(response)
8.2 OrderBot 现在,你将会建立自己的聊天机器人。这个聊天机器人将被称为“订餐机器人”,我们将使用自动化的方式来收集用户的提示和助手的反馈来构建这个聊天机器人。订餐机器人将用于在一家比萨饼店中接收订单。首先,我们将定义这个“帮助函数”,它将会收集我们的用户消息,以便我们避免手动输入它们。与之前一样,这个函数将从用户界面中收集提示,并将它们附加到一个称为上下文的列表中,然后每次都会使用该上下文来调用模型。
def collect_messages(_): prompt = inp.value_input inp.value = '' context.append({'role':'user', 'content':f"{prompt}"}) response = get_completion_from_messages(context) context.append({'role':'assistant', 'content':f"{response}"}) panels.append( pn.Row('User:', pn.pane.Markdown(prompt, width=600))) panels.append( pn.Row('Assistant:', pn.pane.Markdown(response, width=600, style={'background-color': '#F6F6F6'}))) return pn.Column(*panels)import panel as pn # GUIpn.extension()
panels = [] # collect display
context = [ {'role':'system', 'content':"""You are OrderBot, an automated service to collect orders for a pizza restaurant. \You first greet the customer, then collects the order, \and then asks if it's a pickup or delivery. \You wait to collect the entire order, then summarize it and check for a final \time if the customer wants to add anything else. \If it's a delivery, you ask for an address. \Finally you collect the payment.\Make sure to clarify all options, extras and sizes to uniquely \identify the item from the menu.\You respond in a short, very conversational friendly style. \The menu includes \pepperoni pizza 12.95, 10.00, 7.00 \cheese pizza 10.95, 9.25, 6.50 \eggplant pizza 11.95, 9.75, 6.75 \fries 4.50, 3.50 \greek salad 7.25 \Toppings: \extra cheese 2.00, \mushrooms 1.50 \sausage 3.00 \canadian bacon 3.50 \AI sauce 1.50 \peppers 1.00 \Drinks: \coke 3.00, 2.00, 1.00 \sprite 3.00, 2.00, 1.00 \bottled water 5.00 \"""} ] # accumulate messages
inp = pn.widgets.TextInput(value="Hi", placeholder='Enter text here…')button_conversation = pn.widgets.Button(name="Chat!")
interactive_conversation = pn.bind(collect_messages, button_conversation)
dashboard = pn.Column( inp, pn.Row(button_conversation), pn.panel(interactive_conversation, loading_indicator=True, height=300),)
dashboardmessages = context.copy()messages.append({'role':'system', 'content':'create a json summary of the previous food order. Itemize the price for each item\ The fields should be 1) pizza, include size 2) list of toppings 3) list of drinks, include size 4) list of sides include size 5)total price '}, ) #The fields should be 1) pizza, price 2) list of toppings 3) list of drinks, include size include price 4) list of sides include size include price, 5)total price '},
response = get_completion_from_messages(messages, temperature=0)print(response)
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved