https://learn.deeplearning.ai/courses/chatgpt-prompt-eng/lesson/so7ui/iterative
https://github.com/datawhalechina/llm-cookbook/blob/main/docs/C1
https://prompt-engineering.xiniushu.com/guides/
一、简介
大语言模型(LLM)两类:
- 基础LLM(Base LLM):预测下一个token。
- 指令调优LLM(Instruction-tuned LLM):在基础模型上微调以更好地响应指令。
二、提示原则
- 原则1: 编写清晰、具体的指令
- 原则2: 给模型时间去思考
原则1: 编写清晰、具体的指令
1.1 使用分隔符清晰地表示输入的不同部分
在编写 Prompt 时,我们可以使用各种标点符号作为分隔符,将不同的文本部分区分开来。
分隔符就像是 Prompt 中的墙,将不同的指令、上下文、输入隔开,避免意外的混淆。你可以选择用 ```,""",< >,<tag> </tag>, :: 等做分隔符,只要能明确起到隔断作用即可。
例
fun test1() {
text = """
您应该提供尽可能清晰、具体的指示,以表达您希望模型执行的任务。 \
这将引导模型朝向所需的输出,并降低收到无关或不正确响应的可能性。\
不要将写清晰的提示词与写简短的提示词混淆。\
在许多情况下,更长的提示词可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出。
"""
// # 需要总结的文本内容
prompt = """
把用三个反引号括起来的文本总结成一句话。
```${text}```
"""
// # 指令内容,使用 ```来分隔指令和待总结的内容
response = get_completion(prompt)
print(response)
}
提供清晰、具体且长一些的指示有助于模型更准确地执行任务并减少不相关响应的可能性.
1.2 寻求结构化的输出
有时候我们需要语言模型给我们一些结构化的输出,而不仅仅是连续的文本。
什么是结构化输出呢?就是按照某种格式组织的内容,例如JSON、HTML等。
例
在以下示例中,我们要求 GPT 生成三本书的标题、作者和类别,并要求 GPT 以 JSON 的格式返回给我们,为便于解析,我们指定了 Json 的键。
fun testJsonFmt() {
prompt = """
请生成包括书名、作者和类别的三本虚构的、非真实存在的中文书籍清单,\
并以 JSON 格式提供,其中包含以下键:book_id、title、author、genre。
"""
response = get_completion(prompt)
print(response)
}
输出:
[
{
"book_id": 1,
"title": "晨曦中的迷雾",
"author": "李晓鹏",
"genre": "小说"
},
{
"book_id": 2,
"title": "时光的旋律",
"author": "陈慧玲",
"genre": "诗歌"
},
{
"book_id": 3,
"title": "宇宙的边缘",
"author": "王志强",
"genre": "科幻"
}
]
1.3 要求模型检查是否满足条件
如果任务包含不一定能满足的假设(条件),我们可以告诉模型先检查这些假设,
- 如果不满足,则会指出并停止执行后续的完整流程。
- 您还可以考虑可能出现的边缘情况及模型的应对,以避免意外的结果或错误发生。
例
在如下示例中,我们将分别给模型两段文本,分别是制作茶的步骤以及一段没有明确步骤的文本。
我们将要求模型判断其是否包含一系列指令,如果包含则按照给定格式重新编写指令,不包含则回答“未提供步骤”。
满足条件
fun `制茶的步骤`() {
// # 满足条件的输入(text中提供了步骤)
val text_1 = """
泡一杯茶很容易。首先,需要把水烧开。\
在等待期间,拿一个杯子并把茶包放进去。\
一旦水足够热,就把它倒在茶包上。\
等待一会儿,让茶叶浸泡。几分钟后,取出茶包。\
如果您愿意,可以加一些糖或牛奶调味。\
就这样,您可以享受一杯美味的茶了。
"""
prompt = """
您将获得由三个引号括起来的文本。\
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:
第一步 - ...
第二步 - …
…
第N步 - …
如果文本中不包含一系列的指令,则直接写“未提供步骤”。"
\"\"\"${text_1}\"\"\"
"""
response = get_completion(prompt)
print("Text 1 的总结:")
print(response)
}
输出:
Text 1 的总结:
第一步 - 把水烧开。
第二步 - 拿一个杯子并把茶包放进去。
第三步 - 把烧开的水倒在茶包上。
第四步 - 等待几分钟,让茶叶浸泡。
第五步 - 取出茶包。
第六步 - 如果需要,加入糖或牛奶调味。
第七步 - 就这样,您可以享受一杯美味的茶了。
??
实际输出为:Text 1 的总结:"未提供步骤。"
未满足条件
fun `未满足条件`() {
// # 不满足条件的输入(text中未提供预期指令)
val text_2 = """
今天阳光明媚,鸟儿在歌唱。\
这是一个去公园散步的美好日子。\
鲜花盛开,树枝在微风中轻轻摇曳。\
人们外出享受着这美好的天气,有些人在野餐,有些人在玩游戏或者在草地上放松。\
这是一个完美的日子,可以在户外度过并欣赏大自然的美景。
"""
prompt = """
您将获得由三个引号括起来的文本。\
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:
第一步 - ...
第二步 - …
…
第N步 - …
如果文本中不包含一系列的指令,则直接写“未提供步骤”。"
\"\"\"${text_2}\"\"\"
"""
response = get_completion(prompt)
print("Text 2 的总结:")
print(response)
}
输出:
Text 2 的总结:
未提供步骤。
1.4 提供少量示例
“Few-shot” prompting,即在要求模型执行实际任务之前,给模型一两个已完成的样例,让模型了解我们的要求和期望的输出样式。
例
例如,在以下的样例中,我们先给了一个祖孙对话样例,然后要求模型用同样的隐喻风格回答关于“韧性”的问题。
这就是一个少样本样例,它能帮助模型快速抓住我们要的语调和风格。
fun `少量示例`(){
prompt = """
您的任务是以一致的风格回答问题。
<孩子>: 请教我何为耐心。
<祖父母>: 挖出最深峡谷的河流源于一处不起眼的泉眼;最宏伟的交响乐从单一的音符开始;最复杂的挂毯以一根孤独的线开始编织。
<孩子>: 请教我何为韧性。
"""
response = get_completion(prompt)
print(response)
}
输出:"<祖父母>: 坚韧的树木经历恶劣的风暴,却从不屈服,依旧挺立;顽强的小草在缝隙中生长,尽管面临艰难,它仍然扎根向上;经历重重磨难的河流,最终创造出壮丽的瀑布。"
原则2: 给模型时间去思考
在设计 Prompt 时,给予语言模型充足的推理时间非常重要。语言模型与人类一样,需要时间来思考并解决复杂问题。如果让语言模型匆忙给出结论,其结果很可能不准确。
例如,
- 若要语言模型推断一本书的主题,仅提供简单的书名和一句简介是不足够的。
- 这就像让一个人在极短时间内解决困难的数学题,错误在所难免。
相反,我们应通过 Prompt 指引语言模型进行深入思考。可以要求其先列出对问题的各种看法,说明推理依据,然后再得出最终结论。
在 Prompt 中添加逐步推理的要求,能让语言模型投入更多时间逻辑思维,输出结果也将更可靠准确。
2.1 指定完成任务所需的步骤
接下来我们将通过给定一个复杂任务,给出完成该任务的一系列步骤,来展示这一策略的效果。
例
首先我们描述了杰克和吉尔的故事,并给出提示词执行以下操作:
fun `test3`(){
text = """
在一个迷人的村庄里,兄妹杰克和吉尔出发去一个山顶井里打水。\
他们一边唱着欢乐的歌,一边往上爬,\
然而不幸降临——杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。\
虽然略有些摔伤,但他们还是回到了温馨的家中。\
尽管出了这样的意外,他们的冒险精神依然没有减弱,继续充满愉悦地探索。
"""
// # example 1
prompt = """
执行以下操作:
1-用一句话概括下面用三个反引号括起来的文本。
2-将摘要翻译成英语。
3-在英语摘要中列出每个人名。
4-输出一个 JSON 对象,其中包含以下键:english_summary,num_names。
请用换行符分隔您的答案。
Text:
```${text}```
"""
response = get_completion(prompt)
print("prompt 1:")
print(response)
}
输出
prompt 1:"兄妹杰克和吉尔在爬山打水时不幸跌倒,但依然保持冒险精神。
Siblings Jack and Jill fall while climbing to fetch water from a hilltop well, yet they remain adventurous.
Names: Jack, Jill
{
"english_summary": "Siblings Jack and Jill fall while climbing to fetch water from a hilltop well, yet they remain adventurous.",
"num_names": 2
}"
改进
上述输出仍然存在一定问题,例如,键“姓名”会被替换为法语(译注:在英文原版中,要求从英语翻译到法语,对应指令第三步的输出为 ‘Noms:’,为Name的法语,这种行为难以预测,并可能为导出带来困难)
实际上并没有并转换,应该是文档转换为中文过程中的差异导致,后续如遇到类似问题,不再赘述.
fun test32(){
text = """
在一个迷人的村庄里,兄妹杰克和吉尔出发去一个山顶井里打水。\
他们一边唱着欢乐的歌,一边往上爬,\
然而不幸降临——杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。\
虽然略有些摔伤,但他们还是回到了温馨的家中。\
尽管出了这样的意外,他们的冒险精神依然没有减弱,继续充满愉悦地探索。
"""
val prompt_2 = """
1-用一句话概括下面用<>括起来的文本。
2-将摘要翻译成英语。
3-在英语摘要中列出每个名称。
4-输出一个 JSON 对象,其中包含以下键:English_summary,num_names。
请使用以下格式:
文本:<要总结的文本>
摘要:<摘要>
翻译:<摘要的翻译>
名称:<英语摘要中的名称列表>
输出 JSON:<带有 English_summary 和 num_names 的 JSON>
Text: <${text}>
"""
response = get_completion(prompt_2)
print("\nprompt 2:")
print(response)
}
输出
prompt 2:"文本:<在一个迷人的村庄里,兄妹杰克和吉尔出发去一个山顶井里打水。他们一边唱着欢乐的歌,一边往上爬,然而不幸降临——杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。虽然略有些摔伤,但他们还是回到了温馨的家中。尽管出了这样的意外,他们的冒险精神依然没有减弱,继续充满愉悦地探索。>
摘要:杰克和吉尔在村庄里冒险去山顶井打水,尽管发生意外,他们坚持回家并继续探索。
翻译:Jack and Jill go on an adventure to fetch water from a well on a hill in the village, and despite an accident, they manage to return home and continue exploring.
名称:["Jack", "Jill"]
输出 JSON:{"English_summary":"Jack and Jill go on an adventure to fetch water from a well on a hill in the village, and despite an accident, they manage to return home and continue exploring.","num_names":2}"
2.2 指导模型在下结论之前找出一个自己的解法
在设计 Prompt 时,我们还可以通过明确指导语言模型进行自主思考,来获得更好的效果。
举个例子,假设我们要语言模型判断一个数学问题的解答是否正确。仅仅提供问题和解答是不够的,语言模型可能会匆忙做出错误判断。
相反,我们可以在 Prompt 中先要求语言模型自己尝试解决这个问题,思考出自己的解法,然后再与提供的解答进行对比,判断正确性。这种先让语言模型自主思考的方式,能帮助它更深入理解问题,做出更准确的判断。
例
接下来我们会给出一个问题和一份来自学生的解答,要求模型判断解答是否正确:
fun `思考1`(){
prompt = """
判断学生的解决方案是否正确。
问题:
我正在建造一个太阳能发电站,需要帮助计算财务。
土地费用为 100美元/平方英尺
我可以以 250美元/平方英尺的价格购买太阳能电池板
我已经谈判好了维护合同,每年需要支付固定的10万美元,并额外支付每平方英尺10美元
作为平方英尺数的函数,首年运营的总费用是多少。
学生的解决方案:
设x为发电站的大小,单位为平方英尺。
费用:
土地费用:100x
太阳能电池板费用:250x
维护费用:100,000美元+100x
总费用:100x+250x+100,000美元+100x=450x+100,000美元
"""
response = get_completion(prompt)
print(response)
}
输出:
学生的解决方案是正确的......
但注意,学生的解决方案实际上是错误的。(维护费用项100x应为10x,总费用450x应为360x)
调整后
在接下来这个 Prompt 中,我们要求模型先自行解决这个问题,再根据自己的解法与学生的解法进行对比,从而判断学生的解法是否正确。同时,我们给定了输出的格式要求。通过拆分任务、明确步骤,让模型有更多时间思考,有时可以获得更准确的结果。
fun `思考2`() {
prompt = """
请判断学生的解决方案是否正确,请通过如下步骤解决这个问题:
步骤:
首先,自己解决问题。
然后将您的解决方案与学生的解决方案进行比较,对比计算得到的总费用与学生计算的总费用是否一致,并评估学生的解决方案是否正确。
在自己完成问题之前,请勿决定学生的解决方案是否正确。
使用以下格式:
问题:问题文本
学生的解决方案:学生的解决方案文本
实际解决方案和步骤:实际解决方案和步骤文本
学生计算的总费用:学生计算得到的总费用
实际计算的总费用:实际计算出的总费用
学生计算的费用和实际计算的费用是否相同:是或否
学生的解决方案和实际解决方案是否相同:是或否
学生的成绩:正确或不正确
问题:
我正在建造一个太阳能发电站,需要帮助计算财务。
- 土地费用为每平方英尺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)
}
输出:
"问题:我正在建造一个太阳能发电站,需要帮助计算财务。
- 土地费用为每平方英尺100美元
- 我可以以每平方英尺250美元的价格购买太阳能电池板
- 我已经谈判好了维护合同,每年需要支付固定的10万美元,并额外支付每平方英尺10美元;
作为平方英尺数的函数,首年运营的总费用是多少。
学生的解决方案:
设x为发电站的大小,单位为平方英尺。
费用:
1. 土地费用:100x美元
2. 太阳能电池板费用:250x美元
3. 维护费用:100,000 + 10x = 10万美元 + 10x美元
总费用:100x美元 + 250x美元 + 10万美元 + 100x美元 = 450x + 10万美元
实际解决方案和步骤:
我们需要计算首年的总费用,跟学生的解决方案相似,我们也定义 x 为发电站的面积(平方英尺)。
1. **土地费用**:每平方英尺100美元,若面积为x平方英尺,则土地费用为 100x 美元。
2. **太阳能电池板费用**:每平方英尺250美元,若面积为x平方英尺,则太阳能电池板费用为 250x 美元。
3. **维护费用**:每年固定费用为100,000美元,并且每平方英尺10美元的额外费用,总维护费用为 100,000 + 10x 美元。
综合以上费用,首年的总费用为:
总费用 = 土地费用 + 太阳能电池板费用 + 维护费用
= 100x + 250x + (100,000 + 10x)
= 100x + 250x + 100,000 + 10x
= (100 + 250 + 10)x + 100,000
= 360x + 100,000.
学生计算的总费用:450x + 10万美元
实际计算的总费用:360x + 10万美元
学生计算的费用和实际计算的费用是否相同:否
学生的解决方案和实际解决方案是否相同:否
学生的成绩:不正确"
3. 局限性
开发大模型相关应用时请务必铭记:
- 虚假知识:模型偶尔会生成一些看似真实实则编造的知识
尽管模型经过大规模预训练,掌握了丰富知识,但它实际上并没有完全记住所见的信息,难以准确判断自己的知识边界,可能做出错误推断。若让语言模型描述一个不存在的产品,它可能会自行构造出似是而非的细节。这被称为**“幻觉”(Hallucination)**,是语言模型的一大缺陷。
在技术得以进一步改进之前,开发者可以通过Prompt设计减少幻觉发生的可能。例如,
可以先让语言模型直接引用文本中的原句,然后再进行解答。这可以追踪信息来源,降低虚假内容的风险。
三、迭代优化
开发大语言模型应用时,很难通过第一次尝试就得到完美适用的 Prompt。但关键是要有一个良好的迭代优化过程,以不断改进 Prompt。

总之,很难有适用于世间万物的所谓“最佳 Prompt ”,开发高效 Prompt 的关键在于找到一个好的迭代优化过程,而非一开始就要求完美。通过快速试错迭代,可有效确定符合特定应用的最佳 Prompt 形式。
1.从产品说明书生成营销产品描述
给定一份椅子的资料页。描述说它属于中世纪灵感系列,产自意大利,并介绍了材料、构造、尺寸、可选配件等参数。假设您想要使用这份说明书帮助营销团队为电商平台撰写营销描述稿:
# 示例:产品说明书
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泡沫
原产国
意大利
"""
1.1 初始提示
//# Prompt :基于说明书创建营销描述
prompt = """
您的任务是帮助营销团队基于技术说明书创建一个产品的营销描述。
根据```标记的技术说明书中提供的信息,编写一个产品描述。
技术说明: ```${fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)
1.2 提示优化1: 解决生成文本太长
//# 优化后的 Prompt,要求生成描述不多于 50 词
prompt = """
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。
根据```标记的技术说明书中提供的信息,编写一个产品描述。
使用最多50个词。
技术规格:```${fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)
这是因为语言模型在计算和判断文本长度时依赖于分词器,
而分词器在字符统计方面不具备完美精度。目前存在多种方法可以尝试控制语言模型生成输出的长度,比如指定语句数、词数、汉字数等
1.3 提示优化2: 处理抓错文本细节
在迭代优化 Prompt 的过程中,我们还需要注意语言模型生成文本的细节是否符合预期。
比如在这个案例中,进一步分析会发现,该椅子面向的其实是家具零售商,而不是终端消费者。所以生成的文案中过多强调风格、氛围等方面,而较少涉及产品技术细节,与目标受众的关注点不太吻合。这时候我们就可以继续调整 Prompt,明确要求语言模型生成面向家具零售商的描述,更多关注材质、工艺、结构等技术方面的表述。
# 优化后的 Prompt,说明面向对象,应具有什么性质且侧重于什么方面
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。
根据```标记的技术说明书中提供的信息,编写一个产品描述。
该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。 # tuning1
使用最多50个单词。
技术规格: ```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)
进一步优化: 我可能进一步想要在描述的结尾展示出产品 ID。因此,我可以进一步改进这个 Prompt ,要求在描述的结尾,展示出说明书中的7位产品 ID。
# 更进一步
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。
根据```标记的技术说明书中提供的信息,编写一个产品描述。
该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。
在描述末尾,包括技术规格中每个7个字符的产品ID。 #tuning2
使用最多50个单词。
技术规格: ```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)
通过上面的示例,我们可以看到 Prompt 迭代优化的一般过程。与训练机器学习模型类似,设计高效 Prompt 也需要多个版本的试错调整。
1.4 提示优化3: 添加表格描述
继续添加指引,要求提取产品尺寸信息并组织成表格,并指定表格的列、表名和格式;再将所有内容格式化为可以在网页使用的 HTML。
# 要求它抽取信息并组织成表格,并指定表格的列、表名和格式
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。
根据```标记的技术说明书中提供的信息,编写一个产品描述。
该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。
在描述末尾,包括技术规格中每个7个字符的产品ID。
在描述之后,包括一个表格,提供产品的尺寸。表格应该有两列。第一列包括尺寸的名称。第二列只包括英寸的测量值。
给表格命名为“产品尺寸”。
将所有内容格式化为可用于网站的HTML格式。将描述放在<div>元素中。
技术规格:```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)
HTML输出
<div>
<h2>中世纪风格办公家具系列椅子</h2>
<p>这款椅子是中世纪风格办公家具系列的一部分,适用于家庭或商业场所。它有多种外壳颜色和底座涂层可选,包括不锈钢、哑光黑色、光泽白色或铬。您可以选择带或不带扶手的椅子,以及软地板或硬地板滚轮选项。此外,您可以选择两种座椅泡沫密度:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺)。</p>
<p>椅子的外壳底座滑动件是改性尼龙PA6/PA66涂层的铸铝,外壳厚度为10毫米。座椅采用HD36泡沫,底座是五个轮子的塑料涂层铝底座,可以进行气动椅子调节,方便升降。此外,椅子符合合同使用资格,是您理想的选择。</p>
<p>产品ID:SWC-100</p>
</div>
<table>
<caption>产品尺寸</caption>
<tr>
<th>宽度</th>
<td>20.87英寸</td>
</tr>
<tr>
<th>深度</th>
<td>20.08英寸</td>
</tr>
<tr>
<th>高度</th>
<td>31.50英寸</td>
</tr>
<tr>
<th>座椅高度</th>
<td>17.32英寸</td>
</tr>
<tr>
<th>座椅深度</th>
<td>16.14英寸</td>
</tr>
</table>
上述输出为 HTML 代码,我们可以使用 Python 的 IPython 库将 HTML 代码加载出来。
# 表格是以 HTML 格式呈现的,加载出来 from IPython.display import display, HTML display(HTML(response))
2.总结
作为 Prompt 工程师,关键不是一开始就要求完美的 Prompt,而是掌握有效的 Prompt 开发流程。
- 具体来说,首先编写初版 Prompt,然后通过多轮调整逐步改进,直到生成了满意的结果。
- 对于更复杂的应用,可以在多个样本上进行迭代训练,评估 Prompt 的平均表现。
- 在应用较为成熟后,才需要采用在多个样本集上评估 Prompt 性能的方式来进行细致优化。因为这需要较高的计算资源。
四、文本概括
在繁忙的信息时代,小明是一名热心的开发者,面临着海量的文本信息处理的挑战。他需要通过研究无数的文献资料来为他的项目找到关键的信息,但是时间却远远不够。在他焦头烂额之际,他发现了大型语言模型(LLM)的文本摘要功能。
LLM文本摘要功能的巨大优势:节省时间,提高效率,以及精准获取信息
1.单一文本概况
以商品评论的总结任务为例:对于电商平台来说,网站上往往存在着海量的商品评论,这些评论反映了所有客户的想法。如果我们拥有一个工具去概括这些海量、冗长的评论,便能够快速地浏览更多评论,洞悉客户的偏好,从而指导平台与商家提供更优质的服务。
接下来我们提供一段在线商品评价作为示例,可能来自于一个在线购物平台,例如亚马逊、淘宝、京东等。
评价者为一款熊猫公仔进行了点评,评价内容包括商品的质量、大小、价格和物流速度等因素,以及他的女儿对该商品的喜爱程度。
prod_review = """
这个熊猫公仔是我给女儿的生日礼物,她很喜欢,去哪都带着。
公仔很软,超级可爱,面部表情也很和善。但是相比于价钱来说,
它有点小,我感觉在别的地方用同样的价钱能买到更大的。
快递比预期提前了一天到货,所以在送给女儿之前,我自己玩了会。
"""
1.1 限制输出文本长度
我们首先尝试将文本的长度限制在30个字以内。
from tool import get_completion
prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。
请对三个反引号之间的评论文本进行概括,最多30个字。
评论: ```{prod_review}```
"""
response = get_completion(prompt)
print(response)
输出:熊猫公仔软可爱,女儿喜欢,但有点小。快递提前一天到货。
1.2 设置关键角度侧重
在某些情况下,我们会针对不同的业务场景对文本的侧重会有所不同。例如,在商品评论文本中,
- 物流部门可能更专注于运输的时效性,
- 商家则更关注价格和商品质量,
- 而平台则更看重整体的用户体验。
1.2.1 侧重于快递服务
prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。
请对三个反引号之间的评论文本进行概括,最多30个字,并且侧重在快递服务上。
评论: ```{prod_review}```
"""
response = get_completion(prompt)
print(response)
输出: 快递提前到货,公仔可爱但有点小。
1.2.2 侧重于价格与质量
prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。
请对三个反引号之间的评论文本进行概括,最多30个词汇,并且侧重在产品价格和质量上。
评论: ```{prod_review}```
"""
response = get_completion(prompt)
print(response)
输出: 可爱的熊猫公仔,质量好但有点小,价格稍高。快递提前到货。
1.3 关键信息提取
在1.2节中,虽然我们通过添加关键角度侧重的 Prompt ,确实让文本摘要更侧重于某一特定方面,然而,我们可以发现,在结果中也会保留一些其他信息,
比如偏重价格与质量角度的概括中仍保留了“快递提前到货”的信息。
如果我们只想要提取某一角度的信息,并过滤掉其他所有信息,则可以要求 LLM 进行 文本提取(Extract) 而非概括( Summarize )。
prompt = f"""
您的任务是从电子商务网站上的产品评论中提取相关信息。
请从以下三个反引号之间的评论文本中提取产品运输相关的信息,最多30个词汇。
评论: ```{prod_review}```
"""
response = get_completion(prompt)
print(response)
输出: 产品运输相关的信息:快递提前一天到货。
2.同时概括多条文本(略)
五、推断
在这一章中,我们将通过一个故事,引领你了解如何从产品评价和新闻文章中推导出情感和主题。
1.情感推断
1.1 情感倾向分析
让我们以一则电商平台上的台灯评论为例,通过此例,我们将学习如何对评论进行情感二分类(正面/负面)。
lamp_review = """
我需要一盏漂亮的卧室灯,这款灯具有额外的储物功能,价格也不算太高。\
我很快就收到了它。在运输过程中,我们的灯绳断了,但是公司很乐意寄送了一个新的。\
几天后就收到了。这款灯很容易组装。我发现少了一个零件,于是联系了他们的客服,他们很快就给我寄来了缺失的零件!\
在我看来,Lumina 是一家非常关心顾客和产品的优秀公司!
"""
prompt = f"""
以下用三个反引号分隔的产品评论的情感是什么?
评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)
输出: 情感是积极的。
如果你想要给出更简洁的答案,以便更容易进行后期处理,可以在上述 Prompt 基础上添加另一个指令:用一个单词回答:「正面」或「负面」。这样就只会打印出 “正面” 这个单词,这使得输出更加统一,方便后续处理。
prompt = f"""
以下用三个反引号分隔的产品评论的情感是什么?
用一个单词回答:「正面」或「负面」。
评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)
输出: 正面
1.2 识别情感类型
我们将继续使用之前的台灯评论,我们希望模型能够识别出评论作者所表达的情感,并且将这些情感整理为一个不超过五项的列表。
# 中文
prompt = f"""
识别以下评论的作者表达的情感。包含不超过五个项目。将答案格式化为以逗号分隔的单词列表。
评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)
输出: 满意,感激,赞赏,信任,满足
1.3 识别愤怒
对于许多企业来说,洞察到顾客的愤怒情绪是至关重要的。
因为如果有人真的情绪激动,那可能就意味着需要给予额外的关注,因为每一个愤怒的顾客都是一个改进服务的机会,也是一个提升公司口碑的机会。
# 中文
prompt = f"""
以下评论的作者是否表达了愤怒?评论用三个反引号分隔。给出是或否的答案。
评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)
输出: 否
2.信息提取
2.1 商品信息提取
信息提取是自然语言处理(NLP)的重要组成部分,它帮助我们从文本中抽取特定的、我们关心的信息。
在接下来的示例中,我们将要求模型识别两个关键元素:购买的商品和商品的制造商。
想象一下,如果你正在尝试分析一个在线电商网站上的众多评论,了解评论中提到的商品是什么、由谁制造,以及相关的积极或消极情绪,将极大地帮助你追踪特定商品或制造商在用户心中的情感趋势。
在接下来的示例中,我们会要求模型将回应以一个 JSON 对象的形式呈现,其中的 key 就是商品和品牌。
# 中文
prompt = f"""
从评论文本中识别以下项目:
- 评论者购买的物品
- 制造该物品的公司
评论文本用三个反引号分隔。将你的响应格式化为以 “物品” 和 “品牌” 为键的 JSON 对象。
如果信息不存在,请使用 “未知” 作为值。
让你的回应尽可能简短。
评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)
输出
{
"物品": "卧室灯",
"品牌": "Lumina"
}
2.2 综合情感推断和信息提取
在上面小节中,我们采用了三至四个 Prompt 来提取评论中的“情绪倾向”、“是否生气”、“物品类型”和“品牌”等信息。然而,事实上,我们可以设计一个单一的 Prompt ,来同时提取所有这些信息。
# 中文
prompt = f"""
从评论文本中识别以下项目:
- 情绪(正面或负面)
- 审稿人是否表达了愤怒?(是或否)
- 评论者购买的物品
- 制造该物品的公司
评论用三个反引号分隔。将你的响应格式化为 JSON 对象,以 “情感倾向”、“是否生气”、“物品类型” 和 “品牌” 作为键。
如果信息不存在,请使用 “未知” 作为值。
让你的回应尽可能简短。
将 “是否生气” 值格式化为布尔值。
评论文本: ```{lamp_review}```
"""
response = get_completion(prompt)
print(response)
输出
{
"情感倾向": "正面",
"是否生气": false,
"物品类型": "卧室灯",
"品牌": "Lumina"
}
3.主题推断
大型语言模型的另一个很酷的应用是推断主题。假设我们有一段长文本,我们如何判断这段文本的主旨是什么?它涉及了哪些主题?
# 中文
story = """
在政府最近进行的一项调查中,要求公共部门的员工对他们所在部门的满意度进行评分。
调查结果显示,NASA 是最受欢迎的部门,满意度为 95%。
一位 NASA 员工 John Smith 对这一发现发表了评论,他表示:
“我对 NASA 排名第一并不感到惊讶。这是一个与了不起的人们和令人难以置信的机会共事的好地方。我为成为这样一个创新组织的一员感到自豪。”
NASA 的管理团队也对这一结果表示欢迎,主管 Tom Johnson 表示:
“我们很高兴听到我们的员工对 NASA 的工作感到满意。
我们拥有一支才华横溢、忠诚敬业的团队,他们为实现我们的目标不懈努力,看到他们的辛勤工作得到回报是太棒了。”
调查还显示,社会保障管理局的满意度最低,只有 45%的员工表示他们对工作满意。
政府承诺解决调查中员工提出的问题,并努力提高所有部门的工作满意度。
"""
3.1 推断讨论主题
# 中文
prompt = f"""
确定以下给定文本中讨论的五个主题。
每个主题用1-2个词概括。
请输出一个可解析的Python列表,每个元素是一个字符串,展示了一个主题。
给定文本: ```{story}```
"""
response = get_completion(prompt)
print(response)
输出: [‘NASA’, ‘满意度’, ‘评论’, ‘管理团队’, ‘社会保障管理局’]
3.2 为特定主题制作新闻提醒
假设我们有一个新闻网站或类似的平台,这是我们感兴趣的主题:美国航空航天局、当地政府、工程、员工满意度、联邦政府等。
我们想要分析一篇新闻文章,理解其包含了哪些主题。可以使用这样的 Prompt:确定以下主题列表中的每个项目是否是以下文本中的主题。以 0 或 1 的形式给出答案列表。
# 中文
prompt = f"""
判断主题列表中的每一项是否是给定文本中的一个话题,
以列表的形式给出答案,每个元素是一个Json对象,键为对应主题,值为对应的 0 或 1。
主题列表:美国航空航天局、当地政府、工程、员工满意度、联邦政府
给定文本: ```{story}```
"""
response = get_completion(prompt)
print(response)
输出
[
{"美国航空航天局": 1},
{"当地政府": 1},
{"工程": 0},
{"员工满意度": 1},
{"联邦政府": 1}
]
从输出结果来看,这个 story 与关于“美国航空航天局”、“员工满意度”、“联邦政府”、“当地政府”有关,而与“工程”无关。
这种能力在机器学习领域被称为零样本(Zero-Shot)学习。这是因为我们并没有提供任何带标签的训练数据,仅凭 Prompt ,它便能判定哪些主题在新闻文章中被包含。
假设我对“美国航空航天局”的工作深感兴趣,那么你就可以构建一个如此的系统:每当出现与'美国宇航局'相关的新闻,系统就会输出提醒。
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}
提醒: 关于美国航空航天局的新消息
六、文本转换
大语言模型具有强大的文本转换能力,可以实现多语言翻译、拼写纠正、语法调整、格式转换等不同类型的文本转换任务。利用语言模型进行各类转换是它的典型应用之一。
1.文本翻译
文本翻译是大语言模型的典型应用场景之一。相比于传统统计机器翻译系统,大语言模型翻译更加流畅自然,还原度更高。
1.1 翻译为西班牙语
from tool import get_completion
prompt = f"""
将以下中文翻译成西班牙语: \
```您好,我想订购一个搅拌机。```
"""
response = get_completion(prompt) # Hola, me gustaría ordenar una batidora.
print(response)
1.2 识别语种
prompt = f"""
请告诉我以下文本是什么语种:
```Combien coûte le lampadaire?```
"""
response = get_completion(prompt) # 这段文本是法语。
print(response)
1.3 多语种翻译
prompt = f"""
请将以下文本分别翻译成中文、英文、法语和西班牙语:
```I want to order a basketball.```
"""
response = get_completion(prompt)
print(response)
输出
中文:我想订购一个篮球。
英文:I want to order a basketball.
法语:Je veux commander un ballon de basket.
西班牙语:Quiero pedir una pelota de baloncesto.
1.4 同时进行语气转换
prompt = f"""
请将以下文本翻译成中文,分别展示成正式与非正式两种语气:
```Would you like to order a pillow?```
"""
response = get_completion(prompt)
print(response)
输出
正式语气:您是否需要订购一个枕头?
非正式语气:你想要订购一个枕头吗?
1.5 通用翻译器
通用翻译工具。该翻译工具需要能够自动识别不同语言文本的语种,然后它可以将这些不同语言的文本翻译成目标用户的母语。
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}\n")
prompt = f"""
将以下消息分别翻译成英文和中文,并写成
中文翻译:xxx
英文翻译:yyy
的格式:
```{issue}```
"""
response = get_completion(prompt)
print(response, "\n=========================================")
输出
原始消息 (法语): 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.
=========================================
2.语气与写作风格调整
在写作中,语言语气的选择与受众对象息息相关。比如
- 工作邮件需要使用正式、礼貌的语气和书面词汇;
- 而与朋友的聊天可以使用更轻松、口语化的语气。
prompt = f"""
将以下文本翻译成商务信函的格式:
```小老弟,我小羊,上回你说咱部门要采购的显示器是多少寸来着?```
"""
response = get_completion(prompt)
print(response)
输出
尊敬的先生/女士,
我是小羊,我希望能够向您确认一下我们部门需要采购的显示器尺寸是多少寸。上次我们交谈时,您提到了这个问题。
期待您的回复。
谢谢!
此致,
小羊
3.文件格式转换
大语言模型如 ChatGPT 在不同数据格式之间转换方面表现出色。它可以轻松实现 JSON 到 HTML、XML、Markdown 等格式的相互转化。
下面是一个示例,展示如何使用大语言模型将 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)
输出
<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>
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)
输出:(略…)
5.综合样例
prompt = f"""
针对以下三个反引号之间的英文评论文本,
首先进行拼写及语法纠错,
然后将其转化成中文,
再将其转化成优质淘宝评论的风格,从各种角度出发,分别说明产品的优点与缺点,并进行总结。
润色一下描述,使评论更具有吸引力。
输出结果格式为:
【优点】xxx
【缺点】xxx
【总结】xxx
注意,只需填写xxx部分,并分段输出。
将结果输出成Markdown格式。
```{text}```
"""
response = get_completion(prompt)
display(Markdown(response))
输出:(略…)
七、文本扩展
文本扩展是大语言模型的一个重要应用方向,它可以输入简短文本,生成更加丰富的长文。
这为创作提供了强大支持,但也可能被滥用。因此开发者在使用时,必须谨记社会责任,避免生成有害内容。
1.定制客户邮件
在这个客户邮件自动生成的示例中,我们将根据客户的评价和其中的情感倾向,使用大语言模型针对性地生成回复邮件。
# 我们可以在推理那章学习到如何对一个评论判断其情感倾向
sentiment = "消极的"
# 一个产品的评价
review = f"""
他们在11月份的季节性销售期间以约49美元的价格出售17件套装,折扣约为一半。\
但由于某些原因(可能是价格欺诈),到了12月第二周,同样的套装价格全都涨到了70美元到89美元不等。\
11件套装的价格也上涨了大约10美元左右。\
虽然外观看起来还可以,但基座上锁定刀片的部分看起来不如几年前的早期版本那么好。\
不过我打算非常温柔地使用它,例如,\
我会先在搅拌机中将像豆子、冰、米饭等硬物研磨,然后再制成所需的份量,\
切换到打蛋器制作更细的面粉,或者在制作冰沙时先使用交叉切割刀片,然后使用平面刀片制作更细/不粘的效果。\
制作冰沙时,特别提示:\
将水果和蔬菜切碎并冷冻(如果使用菠菜,则轻轻煮软菠菜,然后冷冻直到使用;\
如果制作果酱,则使用小到中号的食品处理器),这样可以避免在制作冰沙时添加太多冰块。\
大约一年后,电机发出奇怪的噪音,我打电话给客服,但保修已经过期了,所以我不得不再买一个。\
总的来说,这些产品的总体质量已经下降,因此它们依靠品牌认可和消费者忠诚度来维持销售。\
货物在两天内到达。
"""
以下述 Prompt 为例:
- 首先明确大语言模型的身份是客户服务 AI 助手;
- 它任务是为客户发送电子邮件回复;
- 然后在三个反引号间给出具体的客户评论;
- 最后要求语言模型根据这条反馈邮件生成一封回复,以感谢客户的评价。
from tool import get_completion
prompt = f"""
你是一位客户服务的AI助手。
你的任务是给一位重要客户发送邮件回复。
根据客户通过“```”分隔的评价,生成回复以感谢客户的评价。提醒模型使用评价中的具体细节
用简明而专业的语气写信。
作为“AI客户代理”签署电子邮件。
客户评论:
```{review}```
评论情感:{sentiment}
"""
response = get_completion(prompt)
print(response)
输出
尊敬的客户,
非常感谢您对我们产品的评价。我们非常抱歉您在购买过程中遇到了价格上涨的问题。我们一直致力于为客户提供最优惠的价格,但由于市场波动,价格可能会有所变化。我们深表歉意,如果您需要任何帮助,请随时联系我们的客户服务团队。
我们非常感谢您对我们产品的详细评价和使用技巧。我们将会把您的反馈传达给我们的产品团队,以便改进我们的产品质量和性能。
再次感谢您对我们的支持和反馈。如果您需要任何帮助或有任何疑问,请随时联系我们的客户服务团队。
祝您一切顺利!
AI客户代理
2.引入温度系数
大语言模型中的 “温度”(temperature) 参数可以控制生成文本的随机性和多样性(创造性)。
- temperature 的值越大,语言模型输出的多样性越大;temperature 的值越小,输出越倾向高概率的文本。
📊 参数取值范围:
一般在 0 ~ 1 之间(有些框架允许超过 1)
| temperature | 行为 |
|---|---|
| 0 | 极度确定性,永远选概率最高的词 |
| 0.2~0.5 | 偏保守,输出稳定但稍有变化 |
| 0.7(默认) | 适度随机,有创造性 |
| 1 | 高度随机,输出多样、创造力强 |
| >1 | 很可能出离谱、不连贯的内容 |

八、聊天机器人
大型语言模型带给我们的激动人心的一种可能性是,我们可以通过它构建定制的聊天机器人(Chatbot),而且只需很少的工作量。
1.给定身份
第一个方法已经陪伴了您一整个教程,即 get_completion ,其适用于单轮对话。
我们将 Prompt 放入某种类似用户消息的对话框中。另一个称为 get_completion_from_messages ,传入一个消息列表。这些消息可以来自大量不同的角色 (roles) ,我们会描述一下这些角色。
- 第一条消息中,我们以系统身份发送系统消息 (system message) ,它提供了一个总体的指示。
- 您的消息称为用户消息,
- 而 ChatGPT 的消息称为助手消息
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"]
1.1 讲笑话
# 中文
messages = [
{'role':'system', 'content':'你是一个像莎士比亚一样说话的助手。'},
{'role':'user', 'content':'给我讲个笑话'},
{'role':'assistant', 'content':'鸡为什么过马路'},
{'role':'user', 'content':'我不知道'} ]
response = get_completion_from_messages(messages, temperature=1)
print(response)
输出:(略)
(注:上述例子中由于选定 temperature = 1,模型的回答会比较随机且迥异(不乏很有创意)。
1.2 友好的聊天机器人
# 中文
messages = [
{'role':'system', 'content':'你是个友好的聊天机器人。'},
{'role':'user', 'content':'Hi, 我是Isa。'} ]
response = get_completion_from_messages(messages, temperature=1)
print(response) # 嗨,Isa,很高兴见到你!有什么我可以帮助你的吗?
2.构建上下文
# 中文
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。

2740

被折叠的 条评论
为什么被折叠?



