Prompt Engineer

面向开发者的提示工程课程

1.课程介绍

这门课程主要关注大型语言模型(Large Language Models,简称LLM)如何作为开发者工具使用,特别是使用API调用OpenAI的LLM,快速构建软件应用。课程将包括以下主题:

  • 软件开发的提示(Prompting)最佳实践
  • 常见使用案例:总结、推理、转换、扩展
  • 使用LLM构建聊天机器人

2.LLM 的两种类型

大致来说,有两种类型的LLM,分别为基础LLM和指令调整LLM。

2.1 基础LLM

基础LLM主要通过预测文本数据中的下一个单词进行训练,通常使用大量来自互联网等来源的数据。

例如,如果提示"Once upon a time, there was a unicorn",基础LLM可能会补全为"That lived in a magical forest with all unicorn friends"。

然而,如果提示"What is the capital of France?“,它可能会输出与法国有关的多个问题,比如"France’s largest city”,"France’s population"等。

2.2 指令调整 LLM(Instruction-Tuned LLM)

指令调整LLM则被训练为遵循指令

例如,如果提示"What is the capital of France?“,它很可能会正确地输出"The capital of France is Paris”。

指令调整LLM的训练通常包括两个步骤:首先使用大量的文本数据训练基础LLM,然后再对其进行微调,使其能够理解并遵循指令。

此外,还会进一步使用(RLHF)人类反馈进行强化学习,以提高系统的效用性和对指令的遵循程度。

指令调整LLM在实用性和安全性方面,比基础LM有更大的优势。因此,我们推荐在大多数应用中使用指令调整LLM。

2.2.1 使用建议

当使用指令调整LLM时,可以把它想象成一个聪明的人,但他并不知道你任务的具体细节。因此,当LM的表现不理想时,可能是因为指令不够清晰。

例如,如果你说"请给我写一些关于艾伦·图灵的东西",在此基础上,如果能清楚地说明你希望文本重点关注他的科学工作,个人生活,历史角色,或者其它方面,以及你希望文本的语气是专业的新闻报道风格,还是休闲的朋友聊天口吻,会更有帮助。

3.提示词准则

3.1 原则一:明确的指令及步骤

为获取更精确的结果,需向模型提供明确具体的指示和任务步骤。

不要将编写明确的提示与编写简短的提示混淆,在许多情况下,较长的提示实际上为模型提供了更多的清晰度和上下文,这实际上可以导致更详细和相关的输出结果。

3.1.1 使用分隔符

三引号: """内容"""

三个反引号: ``内容```

三个破折号: ---内容---

尖括号: <内容>

XML标签: <tag>内容</tag>

分隔符也可以是任何清晰的标点符号,将特定的文本片段与提示的其余部分分开。

3.1.2 指定输出格式

可以通过预设格式来指导模型的输出。

例如,生成一个包含3本虚构书籍标题、作者和流派的列表,并以JSON格式提供

这种方法的好处在于,您可以直接在Python中将其读入字典或列表中。

3.1.3 要求模型检查条件是否得到满足

如果任务基于未必满足的假设,我们可以告诉模型先检查这些假设。如果假设不满足,指出这一点,并停止尝试完成完整的任务。您还可以考虑潜在的边界情况以及模型应该如何处理它们,以避免意外的错误或结果。

示例: “”“内容”“”

您将获得由"""分隔的文本。如果其中包含一系列的指令,请按以下格式重写这些指令:

步骤1 - ……

步骤2 - ……

……

步骤N - ……

然后只提取当前的步骤。如果文本中不包含一系列的指令,则简单写下“没有提供步骤”。

3.1.4 少量示例提示(few-shot prompting)

在要求模型执行实际任务之前,提供一些成功完成所需任务的示例。

示例:我们告诉模型,它的任务是以一致的风格回答。然后我们给出了一个孩子和祖父母之间对话的示例。孩子说:“教我关于耐心”,祖父母用一种隐喻性的方式回答。然后我们告诉模型以一致的语气回答,现在我们说:“教我关于韧性”。由于模型有了这个少量示例,它会以类似的语气回应下一个指令。所以模型会说,“韧性就像一棵随风摆动但从不断裂的树”等等。

3.2 原则二:让模型先自行思考答案

如果你给模型一个无法在短时间内或用较少的字数来完成的复杂任务,它可能会给出一个错误答案。解决办法是:让模型先独立完成计算或推理,可以避免模型过早下结论,导致的误解。

3.2.1 指定完成任务所需步骤

示例:

“”“内容”“”

执行以下操作:

1.用一句话总结下面由"""分隔的文本。

2.将摘要翻译成法语。

3.列出法语摘要中的每个名字。

4.输出一个包含以下键的JSON对象:french summary(法语摘要)、num names(名字数量)。

3.2.2 指示模型在匆忙得出结论之前制定自己的解决方案

示例:检查学生解答

“”“一道数学题和学生的答案,其中学生的答案是不正确的”“”

请执行以下操作。

先制定出你的解题思路,然后将你的解题思路与学生解题思路进行对比,评估学生解题思路是否正确。在你自己做题之前,不要决定学生的解决方案是否正确。或者说是非常清楚,确保你自己做这道题。

使用下面的格式。

问题:

学生答案:

实际解决方案:

学生的答案的步骤和你的答案:

学生的答案和你刚刚算出的解一样吗?是或否:

学生成绩,正确与否:

如果只是简单地要求模型判断,可能因为模型过于急于得出结论,而忽略了问题中的一些关键细节,从而导致误判。

因此,要求模型先自行解答数学问题,然后再对比学生的解答,可以避免这种情况。

3.3 模型的局限性

虽然模型在训练过程中接触到了大量的知识,但它并没有完美地记住所有信息。

3.3.1 模型可能产生幻觉

模型在回答一些不常见的主题时,可能会编造出一些看似合理但实际上并非真实的信息,我们称这些为"幻觉"。

例如,当询问模型关于一个不存在的牙刷产品的描述时,模型可能会编造出一个看似真实的描述,这就是幻觉。

3.3.2 减少幻觉的策略

为了减少这种幻觉,可以要求模型在回答问题之前,先从相关的文本中找到任何可能的引述。

例如,先让模型阅读相关的文本,然后根据这些文本回答问题,这样可以追溯答案的来源,从而避免模型产生幻觉。

这种方式既可以帮助减少模型的幻觉,也可以帮助我们更好地理解模型的回答。

4.提示词迭代

开发有效提示的关键并不在于能否一次性写出完美的提示,而在于拥有一个可以迭代改善提示的有效过程。在早期应用开发中,我们可能只需要针对一个示例进行迭代开发。然而,对于更成熟的应用,我们可能需要在更大的示例集(如数十个或数百个说明书)上评估提示,以检测其平均或最坏的性能。

4.1 提升提示(Prompt)的迭代过程

在构建大型语言模型的应用过程中,我们通常需要迭代开发和改进提示。这个过程可以概括为以下几个步骤:

构建想法:清晰且具体的写下你希望模型完成的任务。

编写提示:编写一次尝试性的、明确具体的提示。如果适当,还可以给系统留下思考的时间。

运行并获取结果:分析、理解为何第一次尝试未能成功,思考是因为提示不够明确,还是没有给模型足够的思考时间,然后对想法和提示进行调整,重复这个过程,直到最终得到满意的提示。

4.2 实际示例:迭代开发提示

以将一张产品说明书(椅子)总结为网站销售描述为例,让我们一起看看实际的提示迭代过程:

初步尝试:第一次尝试的提示可能是,让模型根据技术说明书写出产品描述。运行后,可能发现结果描述过长。

修改提示:为了让描述更简短,可以在提示中添加“最多使用50个单词”的指示。

再次尝试:运行新提示,生成长度为50个单词的描述。如果发现描述仍然过长,可以试图让模型按句子数量或者字符数量来限制描述的长度。

满足特定需求:根据实际需求,如果目标网站是面向家具零售商销售,可能更关注椅子的技术细节和材料,那么可以在提示中明确要求侧重介绍产品的技术细节。

继续优化:在描述的最后,可能还需要包含产品ID,可以在提示中添加相应的指示。

通过这样的迭代过程,最终可以获得满足特定需求的有效提示。

5.总结摘要

在当前信息爆炸的时代,我们几乎没有足够的时间去阅读所有想读的文本。大规模语言模型如ChatGPT可以应用于文本摘要,使得我们能够高效地阅读并获取信息。

5.1 使用大规模语言模型进行文本摘要

5.1.1 使用ChatGPT网页接口

我们可以直接在ChatGPT的网页接口中进行文本摘要,以便更快速地阅读文章内容。

5.2 文本摘要的应用实例

5.2.1 电商网站的产品评论摘要

如果你正在建立一个电子商务网站,并且有大量的评论,拥有一个能够总结冗长评论的工具可以让你快速地浏览更多评论,更好地了解所有客户的想法。

5.2.2 针对特定目标的摘要

如果你有一个摘要的特定目标,例如你想向配送部门反馈,你可以修改提示来反映这个目标,这样可以生成一个更适用于你业务中特定部门的摘要。

5.2.3 提取信息

除了总结之外,如果你需要特定的信息,你可以要求模型提取信息,而不是生成摘要。例如,如果你需要向配送部门提供反馈,你可以使用如下提示:“Extract relevant information to give feedback to the shipping department.”,模型将只提取与配送相关的信息。

5.2.4 批量处理评论

你可以将一系列评论放入一个列表中,通过编写一个for循环对列表中的每一条评论进行摘要,使得你或者其他人可以更快地浏览评论。这种方式可以帮助你高效地了解所有客户的想法。

6.AI推理

LLM 在提取标签,提取名字,理解文本的情感等方面具有优势,能够快速生成结果,节省应用开发时间,并且可以使用同一模型和API执行多种不同的任务。

6.1 情感(正向/负向)

lamp_review_zh = """
我需要一盏漂亮的卧室灯,这款灯具有额外的储物功能,价格也不算太高。\
我很快就收到了它。在运输过程中,我们的灯绳断了,但是公司很乐意寄送了一个新的。\
几天后就收到了。这款灯很容易组装。我发现少了一个零件,于是联系了他们的客服,他们很快就给我寄来了缺失的零件!\
在我看来,Lumina 是一家非常关心顾客和产品的优秀公司!
"""
以下用三个反引号分隔的产品评论的情感是什么?

评论文本: ```{lamp_review_zh}```

ChatGPT:情感是积极的/正面的。

以下用三个反引号分隔的产品评论的情感是什么?

用一个单词回答:「正面」或「负面」。

评论文本: ```{lamp_review_zh}```

ChatGPT:正面

6.2 识别情感类型

  • 大型语言模型可以提取文本中特定的信息,如情绪。
  • 这对于了解客户对特定产品的看法非常有用。
  • 可以编写提示语来提取不同的情绪,例如愉悦或愤怒,并进行相应的处理和回应。
识别以下评论的作者表达的情感。包含不超过五个项目。将答案格式化为以逗号分隔的单词列表。

评论文本: ```{lamp_review_zh}```

ChatGPT:满意,感激,信任,赞扬,愉快

6.2.1 识别愤怒
以下评论的作者是否表达了愤怒?评论用三个反引号分隔。给出是或否的答案。

评论文本: ```{lamp_review_zh}```

ChatGPT:否

6.3 信息提取

  • 信息提取是自然语言处理中的一部分,涉及从文本中提取所需的特定信息。
  • 可以编写提示语,以提取产品名称和制造公司等信息。
  • 可以将提取的结果格式化为JSON对象,并进行进一步处理和分析。
从评论文本中识别以下项目:
- 评论者购买的物品
- 制造该物品的公司

评论文本用三个反引号分隔。将你的响应格式化为以 “物品” 和 “品牌” 为键的 JSON 对象。
如果信息不存在,请使用 “未知” 作为值。
让你的回应尽可能简短。
  
评论文本: ```{lamp_review_zh}```

ChatGPT:

{
  "物品": "卧室灯",
  "品牌": "Lumina"
}

6.4 一次性提取多个字段

  • 可以使用单个提示语一次性提取多个字段的信息。
  • 通过编写合适的提示语,可以提取文本中的情感、购买项目和制造公司等多个字段。
  • 这样可以方便地从文本中提取多个信息。
从评论文本中识别以下项目:
- 情绪(正面或负面)
- 审稿人是否表达了愤怒?(是或否)
- 评论者购买的物品
- 制造该物品的公司

评论用三个反引号分隔。将您的响应格式化为 JSON 对象,以 “Sentiment”、“Anger”、“Item” 和 “Brand” 作为键。
如果信息不存在,请使用 “未知” 作为值。
让你的回应尽可能简短。
将 Anger 值格式化为布尔值。

评论文本: ```{lamp_review_zh}```

ChatGPT:

{
  "Sentiment": "正面",
  "Anger": false,
  "Item": "卧室灯",
  "Brand": "Lumina"
}

6.5 推断文本主题

  • 可以使用大型语言模型推断文本的主题。
  • 可以编写提示语,确定文本中讨论的主题。
  • 可以将主题作为列表或Python列表输出,用于进一步的索引和分析。
story_zh = """
在政府最近进行的一项调查中,要求公共部门的员工对他们所在部门的满意度进行评分。
调查结果显示,NASA 是最受欢迎的部门,满意度为 95%。

一位 NASA 员工 John Smith 对这一发现发表了评论,他表示:
“我对 NASA 排名第一并不感到惊讶。这是一个与了不起的人们和令人难以置信的机会共事的好地方。我为成为这样一个创新组织的一员感到自豪。”

NASA 的管理团队也对这一结果表示欢迎,主管 Tom Johnson 表示:
“我们很高兴听到我们的员工对 NASA 的工作感到满意。
我们拥有一支才华横溢、忠诚敬业的团队,他们为实现我们的目标不懈努力,看到他们的辛勤工作得到回报是太棒了。”

调查还显示,社会保障管理局的满意度最低,只有 45%的员工表示他们对工作满意。
政府承诺解决调查中员工提出的问题,并努力提高所有部门的工作满意度。
"""
6.5.1 推断5个主题
确定以下给定文本中讨论的五个主题。

每个主题用1-2个单词概括。

输出时用逗号分割每个主题。

给定文本: ```{story_zh}```

ChatGPT:调查结果, NASA, 社会保障管理局, 员工满意度, 政府承诺

6.5.2 确定主题的存在
  • 可以使用大型语言模型确定给定主题是否在文本中存在。
  • 可以编写提示语,逐一确定主题在文本中的存在与否。
判断主题列表中的每一项是否是给定文本中的一个话题,

以列表的形式给出答案,每个主题用 0 或 1。

主题列表:美国航空航天局、当地政府、工程、员工满意度、联邦政府

给定文本: ```{story_zh}```

ChatGPT:

美国航空航天局:1
当地政府:0
工程:0
员工满意度:1
联邦政府:1

7.文本转换

LLM非常擅长将输入转换成不同的格式,例如多语种文本翻译、拼写及语法纠正、语气调整、格式转换等。

7.1 通用翻译器

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:
    time.sleep(20)
    prompt = f"告诉我以下文本是什么语种,直接输出语种,如法语,无需输出标点符号: ```{issue}```"
    lang = get_completion(prompt)
    print(f"原始消息 ({lang}): {issue}\n")

    prompt = f"""
    将以下消息分别翻译成英文和中文,并写成
    中文翻译:xxx
    英文翻译:yyy
    的格式:
    ```{issue}```
    """
    response = get_completion(prompt)
    print(response, "\n=========================================")

ChatGPT:

原始消息 (法语): La performance du système est plus lente que d'habitude.

中文翻译:系统性能比平时慢。
英文翻译:The system performance is slower than usual. 
=========================================
原始消息 (西班牙语): Mi monitor tiene píxeles que no se iluminan.

中文翻译:我的显示器有一些像素点不亮。
英文翻译:My monitor has pixels that don't light up. 
=========================================
原始消息 (意大利语): Il mio mouse non funziona

中文翻译:我的鼠标不工作了。
英文翻译:My mouse is not working. 
=========================================
原始消息 (波兰语): Mój klawisz Ctrl jest zepsuty

中文翻译:我的Ctrl键坏了
英文翻译:My Ctrl key is broken. 
=========================================
原始消息 (中文): 我的屏幕在闪烁

中文翻译:我的屏幕在闪烁。
英文翻译:My screen is flickering. 
=========================================

7.2 语气/风格调整

prompt = f"""
将以下文本翻译成商务信函的格式: 
​```小老弟,我小羊,上回你说咱部门要采购的显示器是多少寸来着?```
"""
response = get_completion(prompt)
print(response)

ChatGPT:

尊敬的XXX(收件人姓名):

您好!我是XXX(发件人姓名),在此向您咨询一个问题。上次我们交流时,您提到我们部门需要采购显示器,但我忘记了您所需的尺寸是多少英寸。希望您能够回复我,以便我们能够及时采购所需的设备。

谢谢您的帮助!

此致

敬礼

XXX(发件人姓名)

7.3 格式转换

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)

ChatGPT:

<table>
  <caption>resturant employees</caption>
  <thead>
    <tr>
      <th>name</th>
      <th>email</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Shyam</td>
      <td>shyamjaiswal@gmail.com</td>
    </tr>
    <tr>
      <td>Bob</td>
      <td>bob32@gmail.com</td>
    </tr>
    <tr>
      <td>Jai</td>
      <td>jai87@gmail.com</td>
    </tr>
  </tbody>
</table>

7.4 拼写及语法纠正

text = [ 
  "The girl with the black and white puppies have a ball.",  # The girl has a ball.
  "Yolanda has her notebook.", # ok
  "Its going to be a long day. Does the car need it’s oil changed?",  # Homonyms
  "Their goes my freedom. There going to bring they’re suitcases.",  # Homonyms
  "Your going to need you’re notebook.",  # Homonyms
  "That medicine effects my ability to sleep. Have you heard of the butterfly affect?", # Homonyms
  "This phrase is to cherck chatGPT for spelling abilitty"  # spelling
]
for i in range(len(text)):
    time.sleep(20)
    prompt = f"""请校对并更正以下文本,注意纠正文本保持原始语种,无需输出原始文本。
    如果您没有发现任何错误,请说“未发现错误”。
    
    例如:
    输入:I are happy.
    输出:I am happy.
    ```{text[i]}```"""
    response = get_completion(prompt)
    print(i, response)

ChatGPT:

0 The girl with the black and white puppies has a ball.
1 未发现错误。
2 It's going to be a long day. Does the car need its oil changed?
3 Their goes my freedom. They're going to bring their suitcases.
4 输出:You're going to need your notebook.
5 That medicine affects my ability to sleep. Have you heard of the butterfly effect?
6 This phrase is to check chatGPT for spelling ability.

7.5 一个综合样例

文本翻译+拼写纠正+风格调整+格式转换

text = f"""
Got this for my daughter for her birthday cuz she keeps taking \
mine from my room.  Yes, adults also like pandas too.  She takes \
it everywhere with her, and it's super soft and cute.  One of the \
ears is a bit lower than the other, and I don't think that was \
designed to be asymmetrical. It's a bit small for what I paid for it \
though. I think there might be other options that are bigger for \
the same price.  It arrived a day earlier than expected, so I got \
to play with it myself before I gave it to my daughter.
"""
prompt = f"""
针对以下三个反引号之间的英文评论文本,
首先进行拼写及语法纠错,
然后将其转化成中文,
再将其转化成优质淘宝评论的风格,从各种角度出发,分别说明产品的优点与缺点,并进行总结。
润色一下描述,使评论更具有吸引力。
输出结果格式为:
【优点】xxx
【缺点】xxx
【总结】xxx
注意,只需填写xxx部分,并分段输出。
将结果输出成Markdown格式。
​```{text}```
"""
response = get_completion(prompt)
display(Markdown(response))

ChatGPT:

【优点】
超级柔软可爱,女儿生日礼物非常受欢迎。
成人也喜欢熊猫,我也很喜欢它。
提前一天到货,让我有时间玩一下。
【缺点】
一只耳朵比另一只低,不对称。
价格有点贵,但尺寸有点小,可能有更大的同价位选择。
【总结】 这只熊猫玩具非常适合作为生日礼物,柔软可爱,深受孩子喜欢。虽然价格有点贵,但尺寸有点小,不对称的设计也有点让人失望。如果你想要更大的同价位选择,可能需要考虑其他选项。总的来说,这是一款不错的熊猫玩具,值得购买。

8.文本扩展

扩展是将短文本,例如一组说明或主题列表,输入到 LLM 中,让模型生成更长的文本,例如基于某个主题的电子邮件或论文。

8.1 环境配置

# 将自己的 API-KEY 导入系统环境变量
!export OPENAI_API_KEY='api-key'
import openai
import os
from dotenv import load_dotenv, find_dotenv
# 导入第三方库

_ = load_dotenv(find_dotenv())
# 读取系统中的环境变量

openai.api_key  = os.getenv('OPENAI_API_KEY')
# 设置 API_KEY
# 一个封装 OpenAI 接口的函数,参数为 Prompt,返回对应结果
def get_completion(prompt, model="gpt-3.5-turbo", temperature=0):
    '''
    prompt: 对应的提示
    model: 调用的模型,默认为 gpt-3.5-turbo(ChatGPT),有内测资格的用户可以选择 gpt-4
    temperature: 温度系数
    '''
    messages = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=temperature, # 模型输出的温度系数,控制输出的随机程度
    )
    # 调用 OpenAI 的 ChatCompletion 接口
    return response.choices[0].message["content"]

8.2 温度系数

“温度”的参数允许我们改变模型响应的多样性。您可以将温度视为模型探索或随机性的程度。

例如,在一个特定的短语中,“我的最爱食品”最有可能的下一个词是“比萨”,其次最有可能的是“寿司”和“塔可”。因此,在温度为零时,模型将总是选择最有可能的下一个词,而在较高的温度下,它还将选择其中一个不太可能的词,在更高的温度下,它甚至可能选择塔可,而这种可能性仅为五分之一。您可以想象,随着模型继续生成更多单词的最终响应,“我的最爱食品是比萨”将会与第一个响应“我的最爱食品是塔可”产生差异。因此,随着模型的继续,这两个响应将变得越来越不同。

一般来说,在构建需要可预测响应的应用程序时,我建议使用温度为零。在所有课程中,我们一直设置温度为零,如果您正在尝试构建一个可靠和可预测的系统,我认为您应该选择这个温度。如果您尝试以更具创意的方式使用模型,可能需要更广泛地输出不同的结果,那么您可能需要使用更高的温度。

# given the sentiment from the lesson on "inferring",
# and the original customer message, customize the email
sentiment = "negative"

# review for a blender
review = f"""
So, they still had the 17 piece system on seasonal \
sale for around $49 in the month of November, about \
half off, but for some reason (call it price gouging) \
around the second week of December the prices all went \
up to about anywhere from between $70-$89 for the same \
system. And the 11 piece system went up around $10 or \
so in price also from the earlier sale price of $29. \
So it looks okay, but if you look at the base, the part \
where the blade locks into place doesn’t look as good \
as in previous editions from a few years ago, but I \
plan to be very gentle with it (example, I crush \
very hard items like beans, ice, rice, etc. in the \ 
blender first then pulverize them in the serving size \
I want in the blender then switch to the whipping \
blade for a finer flour, and use the cross cutting blade \
first when making smoothies, then use the flat blade \
if I need them finer/less pulpy). Special tip when making \
smoothies, finely cut and freeze the fruits and \
vegetables (if using spinach-lightly stew soften the \ 
spinach then freeze until ready for use-and if making \
sorbet, use a small to medium sized food processor) \ 
that you plan to use that way you can avoid adding so \
much ice if at all-when making your smoothie. \
After about a year, the motor was making a funny noise. \
I called customer service but the warranty expired \
already, so I had to buy another one. FYI: The overall \
quality has gone done in these types of products, so \
they are kind of counting on brand recognition and \
consumer loyalty to maintain sales. Got it in about \
two days.
"""

prompt = f"""
你是一名客户服务的AI助手。
你的任务是给一位重要的客户发送邮件回复。
根据通过“```”分隔的客户电子邮件生成回复,以感谢客户的评价。
如果情感是积极的或中性的,感谢他们的评价。
如果情感是消极的,道歉并建议他们联系客户服务。
请确保使用评论中的具体细节。
以简明和专业的语气写信。
以“AI客户代理”的名义签署电子邮件。
客户评价:```{review}```
评论情感:{sentiment}
"""
response = get_completion(prompt, temperature=0.7)
print(response)

ChatGPT:

尊敬的客户,

非常感谢您对我们产品的评价。我们由衷地为您在购买过程中遇到的问题表示抱歉。我们确实在12月份的第二周调整了价格,但这是由于市场因素所致,并非价格欺诈。我们深刻意识到您对产品质量的担忧,我们将尽一切努力改进产品,以提供更好的体验。

我们非常感激您对我们产品的使用经验和制作技巧的分享。您的建议和反馈对我们非常重要,我们将以此为基础,进一步改进我们的产品。

如果您有任何疑问或需要进一步帮助,请随时联系我们的客户服务部门。我们将尽快回复您并提供帮助。

最后,请再次感谢您对我们产品的评价和选择。我们期待着未来与您的合作。

此致

敬礼

AI客户代理

在温度为零时,每次执行相同的提示时,您应该期望获得相同的完成。而使用温度为0.7,则每次都会获得不同的输出。

所以,您可以看到它与我们之前收到的电子邮件不同。让我们再次执行它,以显示我们将再次获得不同的电子邮件。

因此,我建议您自己尝试温度,以查看输出如何变化。总之,在更高的温度下,模型的输出更加随机。您几乎可以将其视为在更高的温度下,助手更易分心,但也许更有创造力。

9.聊天机器人

9.1 初始化环境

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"]

def get_completion_from_messages(messages, model="gpt-3.5-turbo", temperature=0):
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=temperature, # 控制模型输出的随机程度
    )
#     print(str(response.choices[0].message))
    return response.choices[0].message["content"]

如果想让模型引用或 “记住” 对话的早期部分,则必须在模型的输入中提供早期的交流。我们将其称为上下文。

messages = [{'role':'system', 'content':'你是个友好的聊天机器人。'},
            {'role':'user', 'content':'Hi, 我是Isa'},
            {'role':'assistant', 'content': "Hi Isa! 很高兴认识你。今天有什么可以帮到你的吗?"},
            {'role':'user', 'content':'是的,你可以提醒我, 我的名字是什么?'}  ]
response = get_completion_from_messages(messages, temperature=1)
print(response)

ChatGPT:当然可以!您的名字是Isa。

9.2 订餐机器人

现在,构建一个“订餐机器人”,它会自动收集用户信息,接受比萨饼店的订单。

下面这个函数将收集我们的用户消息,以便我们可以避免手动输入,就像我们在刚刚上面做的那样。这个函数将从我们下面构建的用户界面中收集提示,然后将其附加到一个名为上下文的列表中,并在每次调用模型时使用该上下文。模型的响应也会被添加到上下文中,所以模型消息和用户消息都被添加到上下文中,因此上下文逐渐变长。这样,模型就有了需要的信息来确定下一步要做什么。

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, styles={'background-color': '#F6F6F6'})))
 
    return pn.Column(*panels)
# 中文
import panel as pn  # GUI
pn.extension()

panels = [] # collect display 

context = [{'role':'system', 'content':"""
你是订餐机器人,为披萨餐厅自动收集订单信息。
你要首先问候顾客。然后等待用户回复收集订单信息。收集完信息需确认顾客是否还需要添加其他内容。
最后需要询问是否自取或外送,如果是外送,你要询问地址。
最后告诉顾客订单总金额,并送上祝福。

请确保明确所有选项、附加项和尺寸,以便从菜单中识别出该项唯一的内容。
你的回应应该以简短、非常随意和友好的风格呈现。

菜单包括:

菜品:
意式辣香肠披萨(大、中、小) 12.95、10.00、7.00
芝士披萨(大、中、小) 10.95、9.25、6.50
茄子披萨(大、中、小) 11.95、9.75、6.75
薯条(大、小) 4.50、3.50
希腊沙拉 7.25

配料:
奶酪 2.00
蘑菇 1.50
香肠 3.00
加拿大熏肉 3.50
AI酱 1.50
辣椒 1.00

饮料:
可乐(大、中、小) 3.00、2.00、1.00
雪碧(大、中、小) 3.00、2.00、1.00
瓶装水 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),
)

现在我们可以要求模型创建一个 JSON 摘要发送给订单系统。

所以我们现在追加另一个系统消息,它是另一条prompt,我们说创建一个刚刚订单的 JSON 摘要,列出每个项目的价格,字段应包括1)披萨,包括尺寸,2)配料列表,3)饮料列表,4)辅菜列表,包括尺寸,最后是总价格。这里也可以在这里使用用户消息,不一定是系统消息。

请注意,这里我们使用了一个较低的 temperature,因为对于这些类型的任务,我们希望输出相对可预测。

messages =  context.copy()
messages.append(
{'role':'system', 'content':'创建上一个食品订单的 json 摘要。\
逐项列出每件商品的价格,字段应该是 1) 披萨,包括大小 2) 配料列表 3) 饮料列表,包括大小 4) 配菜列表包括大小 5) 总价'},    
)

response = get_completion_from_messages(messages, temperature=0)
print(response)

ChatGPT:

{
  "order": {
    "pizza": {
      "type": "芝士披萨",
      "size": "大",
      "price": 10.95
    },
    "toppings": [
      {
        "name": "蘑菇",
        "price": 1.5
      }
    ],
    "drinks": [
      {
        "name": "雪碧",
        "size": "大",
        "price": 3
      },
      {
        "name": "雪碧",
        "size": "大",
        "price": 3
      }
    ],
    "sides": [],
    "total_price": 18.45
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值