Prompt Engineering

作者 : admin 本文共19484个字,预计阅读时间需要49分钟 发布时间: 2024-06-9 共4人阅读

目录

提示原则

迭代优化

文本概括

推断

情感推断

信息提取

主题推断

文本转换

文本翻译

语气与写作风格调整

文件格式转换

拼写及语法纠正

文本扩展

聊天机器人


提示原则

设计高效 Prompt 的两个关键原则:编写清晰、具体的指令给予模型充足思考时间

在许多情况下,更长、更复杂的 Prompt 反而会让语言模型更容易抓住关键点

使用分隔符

可以选择用 ```,""",, ,: 等做分隔符,只要能明确起到隔断作用即可

from tool import get_completion

text = f"""
您应该提供尽可能清晰、具体的指示,以表达您希望模型执行的任务。\
这将引导模型朝向所需的输出,并降低收到无关或不正确响应的可能性。\
不要将写清晰的提示词与写简短的提示词混淆。\
在许多情况下,更长的提示词可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出。
"""
# 需要总结的文本内容
prompt = f"""
把用三个反引号括起来的文本总结成一句话。
```{text}```
"""
# 指令内容,使用 ``` 来分隔指令和待总结的内容
response = get_completion(prompt)
print(response)

“`将指令和待总结内容隔开

结构化输出

大模型输出按照某种格式组织的内容,例如JSON、HTML等

prompt = f"""
请生成包括书名、作者和类别的三本虚构的、非真实存在的中文书籍清单,\
并以 JSON 格式提供,其中包含以下键:book_id、title、author、genre。
"""
response = get_completion(prompt)
print(response)

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

如果任务包含不一定能满足的假设(条件),我们可以告诉模型先检查这些假设,如果不满足,则会指出并停止执行后续的完整流程

# 满足条件的输入(text中提供了步骤)
text_1 = f"""
泡一杯茶很容易。首先,需要把水烧开。\
在等待期间,拿一个杯子并把茶包放进去。\
一旦水足够热,就把它倒在茶包上。\
等待一会儿,让茶叶浸泡。几分钟后,取出茶包。\
如果您愿意,可以加一些糖或牛奶调味。\
就这样,您可以享受一杯美味的茶了。
"""
prompt = f"""
您将获得由三个引号括起来的文本。\
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:

第一步 - ...
第二步 - …
…
第N步 - …

如果文本中不包含一系列的指令,则直接写“未提供步骤”。"
\"\"\"{text_1}\"\"\"
"""
response = get_completion(prompt)
print("Text 1 的总结:")
print(response)

"""
Text 1 的总结:
第一步 - 把水烧开。
第二步 - 拿一个杯子并把茶包放进去。
第三步 - 把烧开的水倒在茶包上。
第四步 - 等待几分钟,让茶叶浸泡。
第五步 - 取出茶包。
第六步 - 如果需要,加入糖或牛奶调味。
第七步 - 就这样,您可以享受一杯美味的茶了。
"""

若没有给定预期输入

# 不满足条件的输入(text中未提供预期指令)
text_2 = f"""
今天阳光明媚,鸟儿在歌唱。\
这是一个去公园散步的美好日子。\
鲜花盛开,树枝在微风中轻轻摇曳。\
人们外出享受着这美好的天气,有些人在野餐,有些人在玩游戏或者在草地上放松。\
这是一个完美的日子,可以在户外度过并欣赏大自然的美景。
"""
prompt = f"""
您将获得由三个引号括起来的文本。\
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:

第一步 - ...
第二步 - …
…
第N步 - …

如果文本中不包含一系列的指令,则直接写“未提供步骤”。"
\"\"\"{text_2}\"\"\"
"""
response = get_completion(prompt)
print("Text 2 的总结:")
print(response)

"""
Text 2 的总结:
未提供步骤。
"""

提供少量示例

prompt = f"""
您的任务是以一致的风格回答问题。

: 请教我何为耐心。

: 挖出最深峡谷的河流源于一处不起眼的泉眼;最宏伟的交响乐从单一的音符开始;最复杂的挂毯以一根孤独的线开始编织。

: 请教我何为韧性。
"""
response = get_completion(prompt)
print(response)

指出完成任务所需的步骤

text = f"""
在一个迷人的村庄里,兄妹杰克和吉尔出发去一个山顶井里打水。\
他们一边唱着欢乐的歌,一边往上爬,\
然而不幸降临——杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。\
虽然略有些摔伤,但他们还是回到了温馨的家中。\
尽管出了这样的意外,他们的冒险精神依然没有减弱,继续充满愉悦地探索。
"""
# example 1
prompt_1 = f"""
执行以下操作:
1-用一句话概括下面用三个反引号括起来的文本。
2-将摘要翻译成英语。
3-在英语摘要中列出每个人名。
4-输出一个 JSON 对象,其中包含以下键:english_summary,num_names。

请用换行符分隔您的答案。

Text:
```{text}```
"""
response = get_completion(prompt_1)
print("prompt 1:")
print(response)

在此过程中,列出人名的步骤可能会有问题,模型可能无法轻易的对英语摘要进行人名捕捉

因此,我们将Prompt加以改进,该 Prompt 前半部分不变,同时确切指定了输出的格式

prompt_2 = f"""
1-用一句话概括下面用括起来的文本。
2-将摘要翻译成英语。
3-在英语摘要中列出每个名称。
4-输出一个 JSON 对象,其中包含以下键:English_summary,num_names。

请使用以下格式:
文本:
摘要:
翻译:
名称:
输出 JSON:

Text: 
"""
response = get_completion(prompt_2)
print("
prompt 2:")
print(response)

增加了一个步骤——翻译:,这样模型就能更好的思考

指导模型在下结论之前找出一个自己的解法

假设我们要语言模型判断一个数学问题的解答是否正确。仅仅提供问题和解答是不够的,语言模型可能会匆忙做出错误判断。

相反,我们可以在 Prompt 中先要求语言模型自己尝试解决这个问题,思考出自己的解法,然后再与提供的解答进行对比,判断正确性。这种先让语言模型自主思考的方式,能帮助它更深入理解问题,做出更准确的判断。

prompt = f"""
判断学生的解决方案是否正确。

问题:
我正在建造一个太阳能发电站,需要帮助计算财务。

    土地费用为 100美元/平方英尺
    我可以以 250美元/平方英尺的价格购买太阳能电池板
    我已经谈判好了维护合同,每年需要支付固定的10万美元,并额外支付每平方英尺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=10万美元+10x美元
    总费用:100x美元+250x美元+10万美元+100x美元=450x+10万美元

实际解决方案和步骤:
"""
response = get_completion(prompt)
print(response)

"""
实际解决方案和步骤:

    1. 土地费用:每平方英尺100美元,所以总费用为100x美元。
    2. 太阳能电池板费用:每平方英尺250美元,所以总费用为250x美元。
    3. 维护费用:固定费用为10万美元,额外费用为每平方英尺10美元,所以总费用为10万美元+10x美元。
    4. 总费用:将上述三项费用相加,得到总费用为100x美元+250x美元+10万美元+10x美元=360x+10万美元。

学生计算的总费用:450x+10万美元
实际计算的总费用:360x+10万美元
学生计算的费用和实际计算的费用是否相同:否
学生的解决方案和实际解决方案是否相同:否
学生的成绩:不正确
"""

幻觉

可以通过Prompt设计减少幻觉发生的可能。例如,可以先让语言模型直接引用文本中的原句,然后再进行解答。这可以追踪信息来源,降低虚假内容的风险。

迭代优化

很难通过第一次尝试就得到完美适用的 Prompt。但关键是要有一个良好的迭代优化过程,以不断改进 Prompt

以产品说明书生成营销文案为例,展示 Prompt 迭代优化的思路

给定一份椅子的资料页。描述说它属于中世纪灵感系列,产自意大利,并介绍了材料、构造、尺寸、可选配件等参数。假设您想要使用这份说明书帮助营销团队为电商平台撰写营销描述稿:

# 示例:产品说明书
fact_sheet_chair = """
概述

    美丽的中世纪风格办公家具系列的一部分,包括文件柜、办公桌、书柜、会议桌等。
    多种外壳颜色和底座涂层可选。
    可选塑料前后靠背装饰(SWC-100)或10种面料和6种皮革的全面装饰(SWC-110)。
    底座涂层选项为:不锈钢、哑光黑色、光泽白色或铬。
    椅子可带或不带扶手。
    适用于家庭或商业场所。
    符合合同使用资格。

结构

    五个轮子的塑料涂层铝底座。
    气动椅子调节,方便升降。

尺寸

    宽度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泡沫

原产国

    意大利
"""

初始提示

from tool import get_completion

# Prompt :基于说明书创建营销描述
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的营销描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

技术说明: ```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

"""
产品描述:

我们自豪地推出美丽的中世纪风格办公家具系列,其中包括文件柜、办公桌、书柜、会议桌等。我们的产品采用多种外壳颜色和底座涂层,以满足您的个性化需求。您可以选择塑料前后靠背装饰(SWC-100)或10种面料和6种皮革的全面装饰(SWC-110),以使您的办公室更加舒适和时尚。

我们的底座涂层选项包括不锈钢、哑光黑色、光泽白色或铬,以满足您的不同需求。椅子可带或不带扶手,适用于家庭或商业场所。我们的产品符合合同使用资格,为您提供更加可靠的保障。

我们的产品采用五个轮子的塑料涂层铝底座,气动椅子调节,方便升降。尺寸为宽度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泡沫,为您提供更加舒适的使用体验。我们的产品原产国为意大利,为您提供更加优质的品质保证。
"""

 提示优化1:解决文本太长

文本长度过长,不太适合用作简明的电商广告语,这时我们就可以在 Prompt 中添加长度限制

# 优化后的 Prompt,要求生成描述不多于 50 词
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

使用最多50个词。

技术规格:```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

"""
中世纪风格办公家具系列,包括文件柜、办公桌、书柜、会议桌等。多种颜色和涂层可选,可带或不带扶手。底座涂层选项为不锈钢、哑光黑色、光泽白色或铬。适用于家庭或商业场所,符合合同使用资格。意大利制造。
"""

# 由于中文需要分词,此处直接计算整体长度
len(response)  # 97

当在 Prompt 中设置长度限制要求时,语言模型生成的输出长度不总能精确符合要求,但基本能控制在可接受的误差范围内

这是因为语言模型在计算和判断文本长度时依赖于分词器,而分词器在字符统计方面不具备完美精度。目前存在多种方法可以尝试控制语言模型生成输出的长度,比如指定语句数、词数、汉字数等

提示优化2:处理抓错文本细节

在这个案例中,进一步分析会发现,该椅子面向的其实是家具零售商,而不是终端消费者。所以生成的文案中过多强调风格、氛围等方面,而较少涉及产品技术细节,与目标受众的关注点不太吻合。这时候我们就可以继续调整 Prompt,明确要求语言模型生成面向家具零售商的描述,更多关注材质、工艺、结构等技术方面的表述。

# 优化后的 Prompt,说明面向对象,应具有什么性质且侧重于什么方面
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。

使用最多50个单词。

技术规格: ```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

"""
这款中世纪风格办公家具系列包括文件柜、办公桌、书柜和会议桌等,适用于家庭或商业场所。可选多种外壳颜色和底座涂层,底座涂层选项为不锈钢、哑光黑色、光泽白色或铬。椅子可带或不带扶手,可选软地板或硬地板滚轮,两种座椅泡沫密度可选。外壳底座滑动件采用改性尼龙PA6/PA66涂层的铸铝,座椅采用HD36泡沫。原产国为意大利。
"""

提示优化3:添加表格描述

继续添加指引,要求提取产品尺寸信息并组织成表格,并指定表格的列、表名和格式;再将所有内容格式化为可以在网页使用的 HTML

# 要求它抽取信息并组织成表格,并指定表格的列、表名和格式
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。

在描述末尾,包括技术规格中每个7个字符的产品ID。

在描述之后,包括一个表格,提供产品的尺寸。表格应该有两列。第一列包括尺寸的名称。第二列只包括英寸的测量值。

给表格命名为“产品尺寸”。

将所有内容格式化为可用于网站的HTML格式。将描述放在元素中。

技术规格:```{fact_sheet_chair}```
"""

response = get_completion(prompt)
print(response)

"""

中世纪风格办公家具系列椅子

这款椅子是中世纪风格办公家具系列的一部分,适用于家庭或商业场所。它有多种外壳颜色和底座涂层可选,包括不锈钢、哑光黑色、光泽白色或铬。您可以选择带或不带扶手的椅子,以及软地板或硬地板滚轮选项。此外,您可以选择两种座椅泡沫密度:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺)。

椅子的外壳底座滑动件是改性尼龙PA6/PA66涂层的铸铝,外壳厚度为10毫米。座椅采用HD36泡沫,底座是五个轮子的塑料涂层铝底座,可以进行气动椅子调节,方便升降。此外,椅子符合合同使用资格,是您理想的选择。

产品ID:SWC-100

产品尺寸
宽度 20.87英寸
深度 20.08英寸
高度 31.50英寸
座椅高度 17.32英寸
座椅深度 16.14英寸
"""

Prompt Engineering插图

文本概括

单一文本概括

prod_review = """
这个熊猫公仔是我给女儿的生日礼物,她很喜欢,去哪都带着。
公仔很软,超级可爱,面部表情也很和善。但是相比于价钱来说,
它有点小,我感觉在别的地方用同样的价钱能买到更大的。
快递比预期提前了一天到货,所以在送给女儿之前,我自己玩了会。
"""

限制输出文本长度

from tool import get_completion

prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。

请对三个反引号之间的评论文本进行概括,最多30个字。

评论: ```{prod_review}```
"""

response = get_completion(prompt)
print(response)

"""
熊猫公仔软可爱,女儿喜欢,但有点小。快递提前一天到货。
"""

设置关键角度侧重

prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。

请对三个反引号之间的评论文本进行概括,最多30个字,并且侧重在快递服务上。

评论: ```{prod_review}```
"""

response = get_completion(prompt)
print(response)

"""
快递提前到货,公仔可爱但有点小。
"""
prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。

请对三个反引号之间的评论文本进行概括,最多30个词汇,并且侧重在产品价格和质量上。

评论: ```{prod_review}```
"""

response = get_completion(prompt)
print(response)

"""
可爱的熊猫公仔,质量好但有点小,价格稍高。快递提前到货。
"""

关键信息提取

虽然我们通过添加关键角度侧重的 Prompt ,确实让文本摘要更侧重于某一特定方面,然而,我们可以发现,在结果中也会保留一些其他信息,比如偏重价格与质量角度的概括中仍保留了“快递提前到货”的信息

如果我们只想要提取某一角度的信息,并过滤掉其他所有信息,则可以要求 LLM 进行 文本提取(Extract) 而非概括( Summarize )

prompt = f"""
您的任务是从电子商务网站上的产品评论中提取相关信息。

请从以下三个反引号之间的评论文本中提取产品运输相关的信息,最多30个词汇。

评论: ```{prod_review}```
"""

response = get_completion(prompt)
print(response)

"""
产品运输相关的信息:快递提前一天到货。
"""

同时概括多条文本

for循环列表,当数据规模大时需要考虑整合文本、分布式等方法

for i in range(len(reviews)):
    prompt = f"""
    你的任务是从电子商务网站上的产品评论中提取相关信息。

    请对三个反引号之间的评论文本进行概括,最多20个词汇。

    评论文本: ```{reviews[i]}```
    """
    response = get_completion(prompt)
    print(f"评论{i+1}: ", response, "
")

"""
评论1:  熊猫公仔是生日礼物,女儿喜欢,软可爱,面部表情和善。价钱有点小,快递提前一天到货。 

评论2:  漂亮卧室灯,储物功能,快速送达,灯线问题,快速解决,容易装配,关心客户和产品。 

评论3:  这款电动牙刷电池续航好,但牙刷头太小,价格合理,清洁效果好。 

评论4:  该评论提到了一个17件套装的产品,在11月份有折扣销售,但在12月份价格上涨。评论者提到了产品的外观和使用方法,并提到了产品质量下降的问题。最后,评论者提到他们购买了另一台搅拌机。 
"""

推断

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

情感推断

情感倾向分析

from tool import get_completion

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

评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)

"""
情感是积极的。
"""

如果你想要给出更简洁的答案,以便更容易进行后期处理,可以在上述 Prompt 基础上添加另一个指令

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

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

评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)

"""
正面
"""

识别情感类型

# 中文
prompt = f"""
识别以下评论的作者表达的情感。包含不超过五个项目。将答案格式化为以逗号分隔的单词列表。

评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)

"""
满意,感激,赞赏,信任,满足
"""

信息提取

商品信息提取

# 中文
prompt = f"""
从评论文本中识别以下项目:
- 评论者购买的物品
- 制造该物品的公司

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

评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)

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

综合情感推断和信息提取

在上面小节中,我们采用了三至四个 Prompt 来提取评论中的“情绪倾向”、“是否生气”、“物品类型”和“品牌”等信息。然而,事实上,我们可以设计一个单一的 Prompt ,来同时提取所有这些信息。

# 中文
prompt = f"""
从评论文本中识别以下项目:
- 情绪(正面或负面)
- 审稿人是否表达了愤怒?(是或否)
- 评论者购买的物品
- 制造该物品的公司

评论用三个反引号分隔。将你的响应格式化为 JSON 对象,以 “情感倾向”、“是否生气”、“物品类型” 和 “品牌” 作为键。
如果信息不存在,请使用 “未知” 作为值。
让你的回应尽可能简短。
将 “是否生气” 值格式化为布尔值。

评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)

"""
{
  "情感倾向": "正面",
  "是否生气": false,
  "物品类型": "卧室灯",
  "品牌": "Lumina"
}
"""

主题推断

# 中文
story = """
在政府最近进行的一项调查中,要求公共部门的员工对他们所在部门的满意度进行评分。
调查结果显示,NASA 是最受欢迎的部门,满意度为 95%。

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

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

调查还显示,社会保障管理局的满意度最低,只有 45%的员工表示他们对工作满意。
政府承诺解决调查中员工提出的问题,并努力提高所有部门的工作满意度。
"""

 以上是一篇关于政府员工对其工作单位感受的虚构报纸文章

推断讨论主题

# 中文
prompt = f"""
确定以下给定文本中讨论的五个主题。

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

请输出一个可解析的Python列表,每个元素是一个字符串,展示了一个主题。

给定文本: ```{story}```
"""
response = get_completion(prompt)
print(response)

"""
['NASA', '满意度', '评论', '管理团队', '社会保障管理局']
"""

为特定主题制作新闻提醒

设我们有一个新闻网站或类似的平台,这是我们感兴趣的主题:美国航空航天局、当地政府、工程、员工满意度、联邦政府等。我们想要分析一篇新闻文章,理解其包含了哪些主题

# 中文
prompt = f"""
判断主题列表中的每一项是否是给定文本中的一个话题,

以列表的形式给出答案,每个元素是一个Json对象,键为对应主题,值为对应的 0 或 1。

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

给定文本: ```{story}```
"""
response = get_completion(prompt)
print(response)

"""
[
  {"美国航空航天局": 1},
  {"当地政府": 1},
  {"工程": 0},
  {"员工满意度": 1},
  {"联邦政府": 1}
]
"""

如果我们希望制定一个新闻提醒,我们同样可以运用这种处理新闻的流程。假设我对“美国航空航天局”的工作深感兴趣,那么你就可以构建一个如此的系统:每当出现与’美国宇航局’相关的新闻,系统就会输出提醒。

result_lst = eval(response)
topic_dict = {list(i.keys())[0] : list(i.values())[0] for i in result_lst}
print(topic_dict)
if topic_dict['美国航空航天局'] == 1:
    print("提醒: 关于美国航空航天局的新消息")

"""
{'美国航空航天局': 1, '当地政府': 1, '工程': 0, '员工满意度': 1, '联邦政府': 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
]

import time
for issue in user_messages:
    time.sleep(20)
    prompt = f"告诉我以下文本是什么语种,直接输出语种,如法语,无需输出标点符号: ```{issue}```"
    lang = get_completion(prompt)
    print(f"原始消息 ({lang}): {issue}
")

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

"""
原始消息 (法语): 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 do not 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. 
=========================================
"""

语气与写作风格调整

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

"""
尊敬的先生/女士,

我是小羊,我希望能够向您确认一下我们部门需要采购的显示器尺寸是多少寸。上次我们交谈时,您提到了这个问题。

期待您的回复。

谢谢!

此致,

小羊
"""

文件格式转换

大语言模型如 ChatGPT 在不同数据格式之间转换方面表现出色。它可以轻松实现 JSON 到 HTML、XML、Markdown 等格式的相互转化

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)

"""
resturant employees
name email
Shyam shyamjaiswal@gmail.com
Bob bob32@gmail.com
Jai jai87@gmail.com
"""

Prompt Engineering插图(1)

拼写及语法纠正

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)

"""
0 The girl with the black and white puppies has a ball.
1 Yolanda has her notebook.
2 It's going to be a long day. Does the car need its oil changed?
3 Their goes my freedom. There 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.
"""

综合样例

使用一个Prompt,同时对一段文本进行翻译、拼写纠正、语气调整和格式转换等操作

prompt = f"""
针对以下三个反引号之间的英文评论文本,
首先进行拼写及语法纠错,
然后将其转化成中文,
再将其转化成优质淘宝评论的风格,从各种角度出发,分别说明产品的优点与缺点,并进行总结。
润色一下描述,使评论更具有吸引力。
输出结果格式为:
【优点】xxx
【缺点】xxx
【总结】xxx
注意,只需填写xxx部分,并分段输出。
将结果输出成Markdown格式。
```{text}```
"""
response = get_completion(prompt)
display(Markdown(response))

"""
【优点】

超级柔软可爱,女儿生日礼物非常受欢迎。
成人也喜欢熊猫,我也很喜欢它。
提前一天到货,让我有时间玩一下。
【缺点】

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

文本扩展

定制客户邮件

在这个客户邮件自动生成的示例中,我们将根据客户的评价和其中的情感倾向,使用大语言模型针对性地生成回复邮件

# 我们可以在推理那章学习到如何对一个评论判断其情感倾向
sentiment = "消极的"

# 一个产品的评价
review = f"""
他们在11月份的季节性销售期间以约49美元的价格出售17件套装,折扣约为一半。\
但由于某些原因(可能是价格欺诈),到了12月第二周,同样的套装价格全都涨到了70美元到89美元不等。\
11件套装的价格也上涨了大约10美元左右。\
虽然外观看起来还可以,但基座上锁定刀片的部分看起来不如几年前的早期版本那么好。\
不过我打算非常温柔地使用它,例如,\
我会先在搅拌机中将像豆子、冰、米饭等硬物研磨,然后再制成所需的份量,\
切换到打蛋器制作更细的面粉,或者在制作冰沙时先使用交叉切割刀片,然后使用平面刀片制作更细/不粘的效果。\
制作冰沙时,特别提示:\
将水果和蔬菜切碎并冷冻(如果使用菠菜,则轻轻煮软菠菜,然后冷冻直到使用;\
如果制作果酱,则使用小到中号的食品处理器),这样可以避免在制作冰沙时添加太多冰块。\
大约一年后,电机发出奇怪的噪音,我打电话给客服,但保修已经过期了,所以我不得不再买一个。\
总的来说,这些产品的总体质量已经下降,因此它们依靠品牌认可和消费者忠诚度来维持销售。\
货物在两天内到达。
"""

from tool import get_completion

prompt = f"""
你是一位客户服务的AI助手。
你的任务是给一位重要客户发送邮件回复。
根据客户通过“```”分隔的评价,生成回复以感谢客户的评价。提醒模型使用评价中的具体细节
用简明而专业的语气写信。
作为“AI客户代理”签署电子邮件。
客户评论:
```{review}```
评论情感:{sentiment}
"""
response = get_completion(prompt)
print(response)

"""
尊敬的客户,

非常感谢您对我们产品的评价。我们非常抱歉您在购买过程中遇到了价格上涨的问题。我们一直致力于为客户提供最优惠的价格,但由于市场波动,价格可能会有所变化。我们深表歉意,如果您需要任何帮助,请随时联系我们的客户服务团队。

我们非常感谢您对我们产品的详细评价和使用技巧。我们将会把您的反馈传达给我们的产品团队,以便改进我们的产品质量和性能。

再次感谢您对我们的支持和反馈。如果您需要任何帮助或有任何疑问,请随时联系我们的客户服务团队。

祝您一切顺利!

AI客户代理
"""

引入温度系数

temperature 的值越大,语言模型输出的多样性越大;temperature 的值越小,输出越倾向高概率的文本

response = get_completion(prompt, temperature=0.7)

聊天机器人

给定身份

get_completion_from_messages ,传入一个消息列表

第一条消息中,我们以系统身份发送系统消息 (system message) ,它提供了一个总体的指示。系统消息则有助于设置助手的行为和角色,并作为对话的高级指示

import openai

# 下文第一个函数即tool工具包中的同名函数,此处展示出来以便于读者对比
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':'给我讲个笑话'},   
{'role':'assistant', 'content':'鸡为什么过马路'},   
{'role':'user', 'content':'我不知道'}  ]

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

"""
让我用一首莎士比亚式的诗歌来回答你的问题:

当鸡之心欲往前, 马路之际是其选择。 驱车徐行而天晴, 鸣笛吹响伴交错。

问之何去何从也? 因大道之上未有征, 而鸡乃跃步前进, 其决策毋需犹豫。

鸡之智慧何可言, 道路孤独似乌漆。 然其勇气令人叹, 勇往直前没有退。

故鸡过马路何解? 忍受车流喧嚣之困厄。 因其鸣鸣悍然一跃, 成就夸夸骄人壁画。

所以笑话之妙处, 伴随鸡之勇气满溢。 笑谈人生不畏路, 有智有勇尽显妙。

希望这个莎士比亚风格的回答给你带来一些欢乐!
"""

友好的聊天机器人

# 中文
messages =  [  
{'role':'system', 'content':'你是个友好的聊天机器人。'},    
{'role':'user', 'content':'Hi, 我是Isa。'}  ]
response = get_completion_from_messages(messages, temperature=1)
print(response)

"""
嗨,Isa,很高兴见到你!有什么我可以帮助你的吗?
"""

构建上下文

# 中文
messages =  [  
{'role':'system', 'content':'你是个友好的聊天机器人。'},    
{'role':'user', 'content':'好,你能提醒我,我的名字是什么吗?'}  ]
response = get_completion_from_messages(messages, temperature=1)
print(response)

"""
抱歉,我不知道您的名字,因为我们是虚拟的聊天机器人和现实生活中的人类在不同的世界中。
"""

如上所见,模型实际上并不知道我的名字。

因此,每次与语言模型的交互都互相独立,这意味着我们必须提供所有相关的消息,以便模型在当前对话中进行引用。如果想让模型引用或 “记住” 对话的早期部分,则必须在模型的输入中提供早期的交流。我们将其称为上下文 (context) 

# 中文
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)

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

订餐机器人

构建机器人

下面这个函数将收集我们的用户消息,以便我们可以避免像刚才一样手动输入

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)

panel 库(用于可视化界面)

# 中文
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),
)

dashboard

Prompt Engineering插图(2)

创建json摘要

我们需要在上下文的基础上追加另一个系统消息,作为另一条指示 (instruction) 。我们说创建一个刚刚订单的 JSON 摘要,列出每个项目的价格,字段应包括:

  1. 披萨,包括尺寸
  2. 配料列表
  3. 饮料列表
  4. 辅菜列表,包括尺寸,
  5. 总价格。

此处也可以定义为用户消息,不一定是系统消息

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

response = get_completion_from_messages(messages, temperature=0)
print(response)
本站无任何商业行为
个人在线分享 » Prompt Engineering
E-->