diff --git a/content/Prompt Engineering/1. 简介.md b/content/Prompt Engineering/1. 简介.md
index 195b906..5df6977 100644
--- a/content/Prompt Engineering/1. 简介.md
+++ b/content/Prompt Engineering/1. 简介.md
@@ -1,22 +1,21 @@
-# 简介
+# 第一章 简介
**作者 吴恩达教授**
-欢迎来到本课程,我们将为开发人员介绍 ChatGPT 提示词工程(Prompt Engineering)。本课程由 Isa Fulford 教授和我一起授课。Isa 是 OpenAI 的技术团队成员,曾开发过受欢迎的 ChatGPT 检索插件,并且在教授 LLM (Large Language Model,大语言模型)技术在产品中的应用方面做出了很大贡献。她还参与编写了教授人们使用 Prompt 的 OpenAI cookbook。
+欢迎来到本课程,我们将为开发人员介绍 ChatGPT 提示词工程(Prompt Engineering)。本课程由 Isa Fulford 教授和我一起授课。Isa 是 OpenAI 的技术团队成员,曾开发过受欢迎的 ChatGPT 检索插件,并且在教授 LLM (Large Language Model, 大语言模型)技术在产品中的应用方面做出了很大贡献。她还参与编写了教授人们使用 Prompt 的 OpenAI cookbook。
-互联网上有很多有关提示词(Prompt)的材料,例如《30 prompts everyone has to know》之类的文章。这些文章主要集中在 ChatGPT Web 用户界面上,许多人在使用它执行特定的、通常是一次性的任务。但是,我认为作为开发人员,LLM的更强大功能是能通过 API 调用,从而快速构建软件应用程序。我认为这方面还没有得到充分的重视。
-实际上,我们在 DeepLearning.AI 的姊妹公司 AI Fund 的团队一直在与许多初创公司合作,将这些技术应用于诸多应用程序上。很兴奋能看到 LLM API 能够让开发人员非常快速地构建应用程序。
+互联网上有很多有关提示词(Prompt, 本教程中将保留该术语)的材料,例如《30 prompts everyone has to know》之类的文章。这些文章主要集中在 ChatGPT 的 Web 界面上,许多人在使用它执行特定的、通常是一次性的任务。但是,我认为对于开发人员,LLM 的更强大功能是能通过 API 调用,从而快速构建软件应用程序。我认为这方面还没有得到充分的重视。实际上,我们在 DeepLearning.AI 的姊妹公司 AI Fund 的团队一直在与许多初创公司合作,将这些技术应用于诸多应用程序上。很兴奋能看到 LLM API 能够让开发人员非常快速地构建应用程序。
-在本课程中,我们将与您分享一些技巧,来挖掘LLM的潜力,也会提供应用上的最佳实践。过程中会涉及大量材料。首先,你会学习到用于软件开发的prompr最佳实践,随后会涉及到几个常用使用例,包括概括、推断、转换与扩展,最后会利用LLM构建chatbot(聊天机器人)。希望这能激发你的想象力,去开拓新应用。
+在本课程中,我们将与您分享一些技巧,来挖掘 LLM 的潜力,也会提供应用上的最佳实践。过程中会涉及大量材料。首先,你会学习到用于软件开发的 Prompt 最佳实践,随后会涉及到几个常用使用例,包括概括、推断、转换与扩展,最后会利用 LLM 构建 chatbot(聊天机器人)。希望这能激发你的想象力,去开拓新应用。
-随着LLM的发展,其大致可以分为两种类型,后续称为基础LLM和指令微调(Instruction Tuned)LLM。基础LLM是基于文本训练数据,训练出预测下一个单词能力的模型。其通常通过在互联网和其他来源的大量数据上训练,来确定紧接着出现的最可能的词。例如,如果你以“从前,有一只独角兽”作为提示词,基础LLM可能会继续预测“她与独角兽朋友共同生活在一片神奇森林中”。但是,如果你以“法国的首都是什么”为提示词,则基础LLM可能会根据互联网上的文章,将回答预测为“法国最大的城市是什么?法国的人口是多少?”,因为互联网上的文章很可能是有关法国国家的问答题目列表。
+随着 LLM 的发展,其大致可以分为两种类型,后续称为基础 LLM 和指令微调(Instruction Tuned)LLM。基础LLM是基于文本训练数据,训练出预测下一个单词能力的模型。其通常通过在互联网和其他来源的大量数据上训练,来确定紧接着出现的最可能的词。例如,如果你以“从前,有一只独角兽”作为 Prompt ,基础 LLM 可能会继续预测“她与独角兽朋友共同生活在一片神奇森林中”。但是,如果你以“法国的首都是什么”为 Prompt ,则基础 LLM 可能会根据互联网上的文章,将回答预测为“法国最大的城市是什么?法国的人口是多少?”,因为互联网上的文章很可能是有关法国国家的问答题目列表。
-而对于指令微调的LLM,相关研究和实践正甚嚣尘上,训练它们来遵循指示。因此,如果你问它,“法国的首都是什么?”,它有极大可能输出“法国的首都是巴黎”。指令微调的LLM的训练通常是基于预训练好的LLM的,即模型已经在大量文本数据上进行了训练。然后对其进行进一步训练与微调(finetune),使用的数据包括输入和理想输出(输入是指令、输出是遵循这些指令的良好回答)。然后通常使用一种称为 RLHF(reinforcement learning from human feedback,人类反馈强化学习)的技术进行进一步改进,使系统更能够有帮助地遵循指令。
+而对于指令微调的 LLM ,相关研究和实践正甚嚣尘上,训练它们来遵循指示。因此,如果你问它,“法国的首都是什么?”,它有极大可能输出“法国的首都是巴黎”。指令微调的LLM的训练通常是基于预训练好的LLM的,即模型已经在大量文本数据上进行了训练。然后对其进行进一步训练与微调(finetune),使用的数据包括输入和理想输出(输入是指令、输出是遵循这些指令的良好回答)。然后通常使用一种称为 RLHF(reinforcement learning from human feedback,人类反馈强化学习)的技术进行进一步改进,使系统更能够有帮助地遵循指令。
-因为指令微调的 LLM已经被训练成有益、诚实和无害的,所以与基础LLMs相比,它们更不可能输出有问题的文本,如有害输出。许多实际使用场景已经转向指令微调的LLMs。您在互联网上找到的一些最佳实践可能更适用于基础LLMs,但对于今天的大多数实际应用,我们建议将注意力集中在指令微调的LLMs上,这些LLMs更容易使用,而且由于OpenAI和其他LLM公司的工作,它们变得更加安全和更加协调。
+因为指令微调的 LLM 已经被训练成有益、诚实、无害的,所以与基础 LLM 相比,它们更不可能输出有问题的文本,如有害输出。许多实际使用场景已经转向指令微调的 LLM 。您在互联网上找到的一些最佳实践可能更适用于基础 LLM ,但对于今天的大多数实际应用,我们建议将注意力集中在指令微调的 LLM 上,这些 LLM 更容易使用,而且由于 OpenAI 和其他 LLM 公司的工作,它们变得更加安全,也更加协调。
-因此,本课程将重点介绍针对指令微调 LLM 的最佳实践,我们也建议您将其用于大多数使用场景。在继续之前,我想感谢 OpenAI 和 DeepLearning.ai 团队为 Isa 和我所提供的材料作出的贡献。我非常感激 OpenAI 的 Andrew Main、Joe Palermo、Boris Power、Ted Sanders 和 Lillian Weng,他们参与了我们的头脑风暴材料的制定和审核,为这个短期课程编制了课程大纲。我也感激 Deep Learning 方面的 Geoff Ladwig、Eddy Shyu 和 Tommy Nelson 的工作。
+因此,本课程将重点介绍**针对指令微调 LLM 的最佳实践**,我们也建议您将其用于大多数使用场景。在继续之前,我想感谢 OpenAI 和 DeepLearning.ai 团队为 Isa 和我所提供的材料作出的贡献。我非常感激 OpenAI 的 Andrew Main、Joe Palermo、Boris Power、Ted Sanders 和 Lillian Weng,他们参与了我们的头脑风暴材料的制定和审核,为这个短期课程编制了课程大纲。我也感激 Deep Learning 方面的 Geoff Ladwig、Eddy Shyu 和 Tommy Nelson 的工作。
-当您使用指令微调 LLM 时,可以类似于向另一个人提供指令(假设他很聪明但不知道您任务的具体细节)。因此,当 LLM 无法正常工作时,有时是因为指令不够清晰。例如,如果您想问“请为我写一些关于阿兰·图灵的东西”,在此基础上清楚表明您希望文本专注于他的科学工作、个人生活、历史角色或其他方面可能会更有帮助。另外您还可以指定回答的语调来更加满足您的需求,可选如专业记者写作,或者向朋友写的随笔等。
+当您使用指令微调 LLM 时,您可以类比为向另一个人提供指令(假设他很聪明但不知道您任务的具体细节)。因此,当 LLM 无法正常工作时,有时是因为指令不够清晰。例如,如果您想问“请为我写一些关于阿兰·图灵( Alan Turing )的东西”,在此基础上清楚表明您希望文本专注于他的科学工作、个人生活、历史角色或其他方面可能会更有帮助。另外您还可以指定回答的语调, 来更加满足您的需求,可选项包括*专业记者写作*,或者*向朋友写的随笔*等。
-如果你将LLM视为一名新毕业的大学生,要求他完成这个任务,你甚至可以提前指定他们应该阅读哪些文本片段来写关于 Alan Turing的文本,那么这能够帮助这位新毕业的大学生更好地完成这项任务。下一章你会看到提示词创建的两个原则,一是清晰明确,二是给LLM时间去思考。
+如果你将 LLM 视为一名新毕业的大学生,要求他完成这个任务,你甚至可以提前指定他们应该阅读哪些文本片段来写关于 Alan Turing 的文本,这样能够帮助这位新毕业的大学生更好地完成这项任务。下一章你会看到提示词创建的两个原则,一是**清晰明确**,二是**给LLM时间去思考**。
diff --git a/content/Prompt Engineering/2. 提示原则 Guidelines.ipynb b/content/Prompt Engineering/2. 提示原则 Guidelines.ipynb
index f256a89..b0941c6 100644
--- a/content/Prompt Engineering/2. 提示原则 Guidelines.ipynb
+++ b/content/Prompt Engineering/2. 提示原则 Guidelines.ipynb
@@ -10,6 +10,26 @@
" 本章的主要内容为编写 Prompt 的原则,在本章中,我们将给出两个编写 Prompt 的原则与一些相关的策略,你可以练习编写高效的 Prompt,从而便捷而有效地使用 LLM。"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
"
+ ]
+ },
{
"attachments": {},
"cell_type": "markdown",
@@ -91,7 +111,7 @@
"# 一个封装 OpenAI 接口的函数,参数为 Prompt,返回对应结果\n",
"def get_completion(prompt, model=\"gpt-3.5-turbo\"):\n",
" '''\n",
- " prompt: 对应的提示词\n",
+ " prompt: 对应的 Prompt \n",
" model: 调用的模型,默认为 gpt-3.5-turbo(ChatGPT),有内测资格的用户可以选择 gpt-4\n",
" '''\n",
" messages = [{\"role\": \"user\", \"content\": prompt}]\n",
@@ -117,9 +137,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "### 原则一:编写清晰、具体的指令\n",
+ "### 2.1 原则一:编写清晰、具体的指令\n",
"\n",
- "你应该通过提供尽可能清晰和具体的指令来表达您希望模型执行的操作。这将引导模型给出正确的输出,并降低你得到无关或不正确响应的可能性。清晰的指令不意味着必须简短,因为在许多情况下,更长的提示词实际上更清晰,且提供了更多上下文,也就可能产生更详细更相关的输出。"
+ "你应该通过提供尽可能清晰和具体的指令来表达您希望模型执行的操作。这将引导模型给出正确的输出,并降低你得到无关或不正确响应的可能性。清晰的指令不意味着必须简短,因为在许多情况下,更长的 Prompt 实际上更清晰,且提供了更多上下文,也就可能产生更详细更相关的输出。"
]
},
{
@@ -127,9 +147,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "**策略一:使用分隔符清晰地表示输入的不同部分**,分隔符可以是:```,\"\",<>,\\ \\, : 等\n",
+ "**2.1.1 使用分隔符清晰地表示输入的不同部分**,分隔符可以是:```,\"\",:,<>,\\ \\等\n",
"\n",
- "你可以使用任何明显的标点符号将特定的文本部分与提示词的其余部分分开。标记的形式不限,只需要让模型明确知道这是一个单独部分。使用分隔符可以有效避免提示词注入(Prompt injection)。提示词注入是指如果允许用户将某些输入添加到(开发者预定义的)提示词中,则所提供的指令可能会与开发者想要执行的操作相冲突,从而使LLM遵循用户输入的指令,而非执行开发者预期的操作。即,输入里面可能包含其他指令,会覆盖掉你的指令。对此,使用分隔符是一个不错的策略。\n",
+ "你可以使用任何明显的标点符号将特定的文本部分与 Prompt 的其余部分分开。标记的形式不限,只需要让模型明确知道这是一个单独部分。使用分隔符可以有效避免提示词注入(Prompt injection)。 Prompt 注入是指如果允许用户将某些输入添加到(开发者预定义的) Prompt 中,则所提供的指令可能会与开发者想要执行的操作相冲突,从而使 LLM 遵循用户输入的指令,而非执行开发者预期的操作。即,输入里面可能包含其他指令,会覆盖掉你的指令。对此,使用分隔符是一个不错的策略。\n",
"\n",
"在以下的例子中,我们给出一段话并要求 GPT 进行总结,在该示例中我们使用 ``` 来作为分隔符。\n"
]
@@ -179,8 +199,8 @@
"text = f\"\"\"\n",
"你应该提供尽可能清晰、具体的指示,以表达你希望模型执行的任务。\\\n",
"这将引导模型朝向所需的输出,并降低收到无关或不正确响应的可能性。\\\n",
- "不要将写清晰的提示词与写简短的提示词混淆。\\\n",
- "在许多情况下,更长的提示词可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出。\n",
+ "不要将写清晰的 Prompt 与写简短的 Prompt 混淆。\\\n",
+ "在许多情况下,更长的 Prompt 可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出。\n",
"\"\"\"\n",
"# 需要总结的文本内容\n",
"prompt = f\"\"\"\n",
@@ -200,22 +220,16 @@
"提供清晰具体的指示,避免无关或不正确响应,不要混淆写清晰和写简短,更长的提示可以提供更多清晰度和上下文信息,导致更详细和相关的输出。"
]
},
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": []
- },
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
- "**策略二:寻求结构化的输出**,可以是 Json、HTML 等格式\n",
+ "**2.1.2 寻求结构化的输出**,可以是 JSON、HTML 等格式\n",
"\n",
- "第二个策略是要求生成一个结构化的输出,这可以使模型的输出更容易被我们解析,例如,你可以在 Python 中将其读入字典或列表中。\n",
+ "第二个策略是要求生成一个结构化的输出,这可以使模型的输出更容易被我们解析。例如,你可以在 Python 中将其读入字典或列表中。\n",
"\n",
- "在以下示例中,我们要求 GPT 生成三本书的标题、作者和类别,并要求 GPT 以 Json 的格式返回给我们,为便于解析,我们指定了 Json 的键。"
+ "在以下示例中,我们要求 GPT 生成三本书的标题、作者和类别,并要求 GPT 以 JSON 的格式返回给我们,为便于解析,我们指定了 JSON 的键。"
]
},
{
@@ -309,15 +323,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- " "
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "**策略三:要求模型检查是否满足条件**\n",
+ "**2.1.3 要求模型检查是否满足条件**\n",
"\n",
"如果任务包含不一定能满足的假设,我们可以告诉模型先检查这些假设,如果不满足,则指出并停止执行后续的完整流程。你还可以考虑可能出现的边缘情况及模型的应对,以避免意外的结果或错误发生。\n",
"\n",
@@ -522,7 +528,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "**策略四:提供少量示例**(少样本提示词,Few-shot prompting)\n",
+ "**2.1.4 提供少量示例**(少样本 Prompt ,Few-shot prompting)\n",
"\n",
"即在要求模型执行实际任务之前,提供给它少量成功执行任务的示例。\n",
"\n",
@@ -591,9 +597,13 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "### 原则二:给模型时间去思考\n",
+ "### 2.2 原则二:给模型时间去思考\n",
"\n",
+<<<<<<< Updated upstream
"如果模型匆忙地得出了错误的结论,您应该尝试重新构思查询,请求模型在提供最终答案之前进行一系列相关的推理。换句话说,如果您给模型一个在短时间或用少量文字无法完成的任务,它可能会猜测错误。这种情况对人来说也是一样的。如果您让某人在没有时间计算出答案的情况下完成复杂的数学问题,他们也可能会犯错误。因此,在这些情况下,您可以指示模型花更多时间思考问题,这意味着它在任务上花费了更多的计算资源。"
+=======
+ "如果您发现模型推理过程过于匆忙,导致得出了错误的结论,那么您应该尝试重新构思 Prompt ,要求模型在提供最终答案之前开展思维链,或进行一系列相关推理(a chain or series of relevant reasoning)。换句话说,如果您给模型一个在短时间内或用少量文字无法完成的复杂任务,它的输出结果就容易出错。这种情况对人来说也是类似:如果您要求某人完成复杂的数学问题,又不给足够时间计算出答案,他们也可能会犯错误。因此,在这些情况下,您应该指示模型花更多时间思考问题,让它在任务上花费更多计算资源。"
+>>>>>>> Stashed changes
]
},
{
@@ -601,7 +611,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "**策略一:指定完成任务所需的步骤**\n",
+ "**2.2.1 指定完成任务所需的步骤**\n",
"\n",
"接下来我们将通过给定一个复杂任务,给出完成该任务的一系列步骤,来展示这一策略的效果"
]
@@ -611,7 +621,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"首先我们描述了杰克和吉尔的故事,并给出一个指令。该指令是执行以下操作。首先,用一句话概括三个反引号限定的文本。第二,将摘要翻译成法语。第三,在法语摘要中列出每个名称。第四,输出包含以下键的 JSON 对象:法语摘要和名称数。然后我们要用换行符分隔答案。"
+=======
+ "首先我们描述了杰克和吉尔的故事,并给出 Prompt 执行以下操作:首先,用一句话概括三个反引号限定的文本。第二,将摘要翻译成法语。第三,在法语摘要中列出每个名称。第四,输出包含以下键的 JSON 对象:法语摘要和人名个数。要求输出以换行符分隔。"
+>>>>>>> Stashed changes
]
},
{
@@ -714,6 +728,11 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
@@ -807,15 +826,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- " "
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "**策略二:指导模型在下结论之前找出一个自己的解法**\n",
+ "**2.2.2 指导模型在下结论之前找出一个自己的解法**\n",
"\n",
"有时候,在明确指导模型在做决策之前要思考解决方案时,我们会得到更好的结果。\n",
"\n",
@@ -900,6 +911,11 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
@@ -907,7 +923,7 @@
"source": [
"但是注意,学生的解决方案实际上是错误的。\n",
"\n",
- "我们可以通过指导模型先自行找出一个解法来解决这个问题。\n",
+ "我们可以通过**指导模型先自行找出一个解法**来解决这个问题。\n",
"\n",
"在接下来这个 Prompt 中,我们要求模型先自行解决这个问题,再根据自己的解法与学生的解法进行对比,从而判断学生的解法是否正确。同时,我们给定了输出的格式要求。通过明确步骤,让模型有更多时间思考,有时可以获得更准确的结果。在这个例子中,学生的答案是错误的,但如果我们没有先让模型自己计算,那么可能会被误导以为学生是正确的。"
]
@@ -1077,7 +1093,11 @@
"\n",
"如果模型在训练过程中接触了大量的知识,它并没有完全记住所见的信息,因此它并不很清楚自己知识的边界。这意味着它可能会尝试回答有关晦涩主题的问题,并编造听起来合理但实际上并不正确的答案。我们称这些编造的想法为幻觉。\n",
"\n",
+<<<<<<< Updated upstream
"例如在如下示例中,我们要求告诉我们 Boie 公司生产的 AeroGlide UltraSlim Smart Toothbrush 产品的信息,事实上,这个公司是真实存在的,但产品是编造的,模型则会一本正经地告诉我们编造的知识。\n",
+=======
+ "如下示例展示了大模型的幻觉。我们要求告诉我们 Boie 公司生产的 *AeroGlide UltraSlim Smart Toothbrush* 产品的信息,事实上,这个公司是真实存在的,但产品是编造的,而模型一本正经地提供了它编造的知识,而且迷惑性很强。\n",
+>>>>>>> Stashed changes
"\n"
]
},
@@ -1141,12 +1161,23 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"模型会输出看上去非常真实的编造知识,这有时会很危险。因此,请确保使用我们在本节中介绍的一些技巧,以尝试在构建自己的应用程序时避免这种情况。这是模型已知的一个弱点,也是我们正在积极努力解决的问题。在你希望模型根据文本生成答案的情况下,另一种减少幻觉的策略是先要求模型找到文本中的任何相关引用,然后要求它使用这些引用来回答问题,这种追溯源文档的方法通常对减少幻觉非常有帮助。"
+=======
+ "由于很容易以假乱真,请读者根据在本系列教程中所学知识,在构建自己的应用程序时尽量避免幻觉情况。幻觉是大模型的一个已知缺陷(译注:截至2023年7月),OpenAI也在努力解决该问题。\n",
+ "\n",
+ "在你希望模型根据文本生成回答时,另一种减少幻觉的策略是先要求模型获取来源于该文本的所有引用信息(任何相关引用,any relevant quotes),然后要求它基于所引用的信息来回答问题,这使得我们能根据答案追溯源文档,通常对减少幻觉非常有帮助。"
+>>>>>>> Stashed changes
]
},
{
diff --git a/content/Prompt Engineering/3. 迭代优化 Iterative.ipynb b/content/Prompt Engineering/3. 迭代优化 Iterative.ipynb
index 74a4e8a..fb3d94c 100644
--- a/content/Prompt Engineering/3. 迭代优化 Iterative.ipynb
+++ b/content/Prompt Engineering/3. 迭代优化 Iterative.ipynb
@@ -4,6 +4,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"# 迭代式提示开发\n",
"\n",
"当使用 LLM 构建应用程序时,我从来没有在第一次尝试中就成功使用最终应用程序中所需的 Prompt。但这并不重要,只要您有一个好的迭代过程来不断改进您的 Prompt,那么你就能够得到一个适合任务的 Prompt。我认为在提示方面,第一次成功的几率可能会高一些,但正如上所说,第一个提示是否有效并不重要。最重要的是为您的应用程序找到有效提示的过程。\n",
@@ -14,10 +15,44 @@
]
},
{
+=======
+ "# 第三章 迭代式提示词开发\n",
+ "\n",
+ "当使用 LLM 构建应用程序时,实践层面上很难第一次尝试就成功获得适合最终应用的 Prompt。但这并不重要,只要您有一个好的迭代过程来不断改进您的 Prompt,那么您就能够得到一个适合任务的 Prompt。虽然相比训练机器学习模型,在提示词方面一次成功的几率可能会高一些,但正如上所说,第一版提示词是否有效并不重要。最重要的是**层层迭代**为您的应用程序找到有效提示词的过程。\n",
+ "\n",
+ "因此在本章中,我们将以产品说明书中生成营销文案为例,来展示一些流程框架,并提示您思考如何层层迭代地分析和完善您的 Prompt。\n",
+ "\n",
+ "在吴恩达(Andrew Ng,原教程作者)的机器学习课程中展示过一张图表,说明了机器学习开发的流程。通常是先有一个想法,然后再用以下流程实现:编写代码,获取数据,训练模型,获得实验结果。然后您可以查看结果,分析误差与错误,找出适用领域,甚至可以更改您对具体问题的具体思路或解决方法。此后再次更改实现,并运行另一个实验等,反复迭代,最终获得有效的机器学习模型。在编写基于 LLM 的应用程序的 Prompt 时,流程可能非常相似。您产生了关于要完成的任务的想法后,可以尝试编写第一个 Prompt ,注意要满足上一章说过的两个原则:**清晰明确,并且给系统足够的时间思考**。然后您可以运行并查看结果。如果第一次效果不好,那么迭代的过程就是找出为什么指令不够清晰或为什么没有给算法足够的时间思考,以便改进想法、改进提示词等等,循环多次,直到找到适合您的应用程序的 Prompt。\n",
+ "\n",
+ "很难有适用于世间万物的所谓“最佳提示词”,更好的方法是找到有效的迭代过程,以便您可以快速地找到一个适合您的应用程序的提示词。\n"
+ ]
+ },
+ {
"cell_type": "markdown",
"metadata": {},
"source": [
- "## 环境配置\n",
+ ""
+ ]
+ },
+ {
+ "attachments": {},
+>>>>>>> Stashed changes
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 一、环境配置\n",
"\n",
"同上一章,我们首先需要配置使用 OpenAI API 的环境"
]
@@ -66,14 +101,18 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "## 任务——从产品说明书生成一份营销产品描述"
+ "## 二、任务——从产品说明书生成一份营销产品描述"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"这里有一个椅子的产品说明书,描述说它是一个中世纪灵感家族的一部分,讨论了构造、尺寸、椅子选项、材料等等,产地是意大利。假设您想要使用这份说明书帮助营销团队为在线零售网站撰写营销式描述"
+=======
+ "给定一份椅子的资料页。描述说它属于*中世纪灵感*系列,产自意大利,并介绍了材料、构造、尺寸、可选配件等参数。假设您想要使用这份说明书帮助营销团队为电商平台撰写营销描述稿:"
+>>>>>>> Stashed changes
]
},
{
@@ -240,7 +279,7 @@
"source": [
"# 提示:基于说明书创建营销描述\n",
"prompt = f\"\"\"\n",
- "你的任务是帮助营销团队基于技术说明书创建一个产品的营销描述。\n",
+ "您的任务是帮助营销团队基于技术说明书创建一个产品的营销描述。\n",
"\n",
"根据```标记的技术说明书中提供的信息,编写一个产品描述。\n",
"\n",
@@ -254,7 +293,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "## 问题一:生成文本太长\n",
+ "## 2.1 问题一:生成文本太长\n",
"\n",
"它似乎很好地写了一个描述,介绍了一个惊人的中世纪灵感办公椅,很好地完成了要求,即从技术说明书开始编写产品描述。但是当我看到这个时,我会觉得这个太长了。\n",
"\n",
@@ -373,16 +412,26 @@
"cell_type": "markdown",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"LLM在遵循非常精确的字数限制方面表现得还可以,但并不那么出色。有时它会输出60或65个单词的内容,但这还算是合理的。这原因是 LLM 解释文本使用一种叫做分词器的东西,但它们往往在计算字符方面表现一般般。有很多不同的方法来尝试控制你得到的输出的长度。"
+=======
+ "LLM在遵循非常精确的字数限制方面表现得还可以,但并不那么出色。有时它会输出60或65个单词的内容,但这也还算合理。这原因是 LLM 使用分词器(tokenizer)解释文本,但它们往往在计算字符方面表现一般般。有很多不同的方法来尝试控制您得到的输出的长度(如xx句话/词/个汉字/个字母 (characters) 等)。"
+>>>>>>> Stashed changes
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"## 问题二:文本关注在错误的细节上\n",
"\n",
"我们会发现的第二个问题是,这个网站并不是直接向消费者销售,它实际上旨在向家具零售商销售家具,他们会更关心椅子的技术细节和材料。在这种情况下,你可以修改这个提示,让它更精确地描述椅子的技术细节。\n",
+=======
+ "## 2.2 问题二:抓错文本细节\n",
+ "\n",
+ "我们继续完善这段推广词,会发现的第二个问题是,这个网站并不是直接向消费者销售,它实际上面向的是家具零售商,他们会更关心椅子的技术细节和材料。在这种情况下,您可以继续修改这个提示词,让它更精确地描述椅子的技术细节。\n",
+>>>>>>> Stashed changes
"\n",
"解决方法:要求它专注于与目标受众相关的方面。"
]
@@ -534,6 +583,7 @@
]
},
{
+<<<<<<< Updated upstream
"cell_type": "markdown",
"metadata": {},
"source": [
@@ -542,6 +592,27 @@
"以上是许多开发人员通常会经历的迭代提示开发的简短示例。我的建议是,像上一章中所演示的那样,Prompt 应该保持清晰和明确,并在必要时给模型一些思考时间。在这些要求的基础上,通常值得首先尝试编写 Prompt ,看看会发生什么,然后从那里开始迭代地完善 Prompt,以逐渐接近所需的结果。因此,许多成功的Prompt都是通过这种迭代过程得出的。我将向您展示一个更复杂的提示示例,可能会让您对ChatGPT的能力有更深入的了解。\n",
"\n",
"这里我添加了一些额外的说明,要求它抽取信息并组织成表格,并指定表格的列、表名和格式,还要求它将所有内容格式化为可以在网页使用的 HTML。"
+=======
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "以上是许多开发人员通常会经历的提示词开发的迭代过程简短示例。我的建议是,像上一章中所演示的那样,Prompt 应该保持清晰和明确,并在必要时给模型一些思考时间。在这些要求的基础上,通常值得首先尝试编写一版 Prompt ,看看会发生什么,然后继续迭代完善 Prompt,以逐渐接近所需的结果。许多成功的 Prompt 都是通过这种迭代过程得出的。我将向您展示一个更复杂的提示词示例,可能会让您对 ChatGPT 的能力有更深入的了解。"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.3 问题三:添加表格描述\n",
+ "\n",
+ "继续添加指引,要求提取产品尺寸信息,组织成表格,并指定表格的列、表名和格式;将所有内容格式化为可以在网页使用的 HTML。"
+>>>>>>> Stashed changes
]
},
{
@@ -809,15 +880,16 @@
"cell_type": "markdown",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"本章的主要内容是 LLM 在开发应用程序中的迭代式提示开发过程。开发者需要先尝试编写提示,然后通过迭代逐步完善它,直至得到需要的结果。关键在于拥有一种有效的开发Prompt的过程,而不是知道完美的Prompt。对于一些更复杂的应用程序,可以对多个样本进行迭代开发提示并进行评估。最后,可以在更成熟的应用程序中测试多个Prompt在多个样本上的平均或最差性能。在使用 Jupyter 代码笔记本示例时,请尝试不同的变化并查看结果。"
+=======
+ "本章的主要内容是在开发基于 LLM 的应用程序中的**迭代式**提示词开发过程。开发者需要先尝试编写提示词,然后通过迭代逐步完善它,直至得到需要的结果。作为一名高效的提示词工程师(Prompt Engineer),关键在于掌握有效的开发Prompt的过程,而不是去寻求得到“完美的” Prompt 。对于一些更复杂的应用程序,可以对多个样本(如数百张说明书)进行提示词的迭代开发,并在样本集上进行评估。\n",
+ "\n",
+ "最后,在更成熟的应用程序中,可以观察多个Prompt在多个样本集上的表现,测试平均或最差性能。但通常,**仅当**应用较成型之后,才推荐您通过这种评估方式,来精益求精。\n",
+ "\n",
+ "请使用 Jupyter Notebook,动手实践本节给出的示例,并尝试不同的变化,查看结果。"
+>>>>>>> Stashed changes
]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
}
],
"metadata": {
diff --git a/content/Prompt Engineering/4. 文本概括 Summarizing.ipynb b/content/Prompt Engineering/4. 文本概括 Summarizing.ipynb
index d135871..8c390e5 100644
--- a/content/Prompt Engineering/4. 文本概括 Summarizing.ipynb
+++ b/content/Prompt Engineering/4. 文本概括 Summarizing.ipynb
@@ -5,7 +5,28 @@
"id": "b58204ea",
"metadata": {},
"source": [
- "# 文本概括 Summarizing"
+ "# 第四章 文本概括"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c3182141",
+ "metadata": {},
+ "source": [
+ ""
]
},
{
@@ -13,6 +34,7 @@
"id": "b70ad003",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"## 1 引言"
]
},
@@ -22,6 +44,10 @@
"metadata": {},
"source": [
"当今世界上有太多的文本信息,几乎没有人能够拥有足够的时间去阅读所有我们想了解的东西。但令人感到欣喜的是,目前LLM在文本概括任务上展现了强大的水准,也已经有不少团队将这项功能插入了自己的软件应用中。\n",
+=======
+ "## 一、引言\n",
+ "当今世界上文本信息浩如烟海,我们很难拥有足够的时间去阅读所有想了解的东西。但欣喜的是,目前LLM在文本概括任务上展现了强大的水准,也已经有不少团队将概括功能实现在多种应用中。\n",
+>>>>>>> Stashed changes
"\n",
"本章节将介绍如何使用编程的方式,调用API接口来实现“文本概括”功能。"
]
@@ -31,7 +57,7 @@
"id": "1de4fd1e",
"metadata": {},
"source": [
- "首先,我们需要OpenAI包,加载API密钥,定义getCompletion函数。"
+ "首先,我们需要 OpenAI 包,加载 API 密钥,定义 getCompletion 函数。"
]
},
{
@@ -61,7 +87,7 @@
"id": "9cca835b",
"metadata": {},
"source": [
- "## 2 单一文本概括Prompt实验"
+ "## 二、单一文本概括实验"
]
},
{
@@ -207,7 +233,7 @@
"id": "e9ab145e",
"metadata": {},
"source": [
- "### 2.2 关键角度侧重"
+ "### 2.2 设置关键角度侧重"
]
},
{
@@ -378,6 +404,16 @@
]
},
{
+<<<<<<< Updated upstream
+=======
+ "cell_type": "markdown",
+ "id": "6a5fe085",
+ "metadata": {},
+ "source": []
+ },
+ {
+ "attachments": {},
+>>>>>>> Stashed changes
"cell_type": "markdown",
"id": "972dbb1b",
"metadata": {},
@@ -398,7 +434,7 @@
"id": "ba6f5c25",
"metadata": {},
"source": [
- "在2.2节中,虽然我们通过添加关键角度侧重的Prompt,使得文本摘要更侧重于某一特定方面,但是可以发现,结果中也会保留一些其他信息,如价格与质量角度的概括中仍保留了“快递提前到货”的信息。有时这些信息是有帮助的,但如果我们只想要提取某一角度的信息,并过滤掉其他所有信息,则可以要求LLM进行“文本提取(Extract)”而非“文本概括(Summarize)”。"
+ "在2.2节中,虽然我们通过添加关键角度侧重的Prompt,使得文本摘要更侧重于某一特定方面,但是可以发现,结果中也会保留一些其他信息,如价格与质量角度的概括中仍保留了“快递提前到货”的信息。如果我们只想要提取某一角度的信息,并过滤掉其他所有信息,则可以要求LLM进行“文本提取(Extract)”而非“概括(Summarize)”。"
]
},
{
@@ -472,7 +508,11 @@
"id": "50498a2b",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"## 3 多条文本概括Prompt实验"
+=======
+ "## 三、同时概括多条文本"
+>>>>>>> Stashed changes
]
},
{
@@ -480,7 +520,11 @@
"id": "a291541a",
"metadata": {},
"source": [
+<<<<<<< Updated upstream
"在实际的工作流中,我们往往有许许多多的评论文本,以下展示了一个基于for循环调用“文本概括”工具并依次打印的示例。当然,在实际生产中,对于上百万甚至上千万的评论文本,使用for循环也是不现实的,可能需要考虑整合评论、分布式等方法提升运算效率。"
+=======
+ "在实际的工作流中,我们往往有许许多多的评论文本,以下示例将多条用户评价放进列表,并利用 for 循环,使用文本概括(Summarize)提示词,将评价概括至小于20词,并按顺序打印。当然,在实际生产中,对于不同规模的评论文本,除了使用 for 循环以外,还可能需要考虑整合评论、分布式等方法提升运算效率。您可以搭建主控面板,来总结大量用户评论,来方便您或他人快速浏览,还可以点击查看原评论。这样您能高效掌握顾客的所有想法。"
+>>>>>>> Stashed changes
]
},
{
@@ -539,16 +583,16 @@
"where the blade locks into place doesn’t look as good \\\n",
"as in previous editions from a few years ago, but I \\\n",
"plan to be very gentle with it (example, I crush \\\n",
- "very hard items like beans, ice, rice, etc. in the \\ \n",
+ "very hard items like beans, ice, rice, etc. in the \\\n",
"blender first then pulverize them in the serving size \\\n",
"I want in the blender then switch to the whipping \\\n",
"blade for a finer flour, and use the cross cutting blade \\\n",
"first when making smoothies, then use the flat blade \\\n",
"if I need them finer/less pulpy). Special tip when making \\\n",
"smoothies, finely cut and freeze the fruits and \\\n",
- "vegetables (if using spinach-lightly stew soften the \\ \n",
+ "vegetables (if using spinach-lightly stew soften the \\\n",
"spinach then freeze until ready for use-and if making \\\n",
- "sorbet, use a small to medium sized food processor) \\ \n",
+ "sorbet, use a small to medium sized food processor) \\\n",
"that you plan to use that way you can avoid adding so \\\n",
"much ice if at all-when making your smoothie. \\\n",
"After about a year, the motor was making a funny noise. \\\n",
@@ -602,10 +646,29 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "eb878522",
+ "id": "ccf14427",
"metadata": {},
"outputs": [],
- "source": []
+ "source": [
+ "for i in range(len(reviews)):\n",
+ " prompt = f\"\"\"\n",
+ " 你的任务是从电子商务网站上的产品评论中提取相关信息。\n",
+ "\n",
+ " 请对三个反引号之间的评论文本进行概括,最多20个词汇。\n",
+ "\n",
+ " 评论: ```{reviews[i]}```\n",
+ " \"\"\"\n",
+ " response = get_completion(prompt)\n",
+ " print(i, response, \"\\n\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c1616fdb",
+ "metadata": {},
+ "source": [
+ "**回答暂缺**"
+ ]
}
],
"metadata": {
diff --git a/content/Prompt Engineering/6. 文本转换 Transforming.ipynb b/content/Prompt Engineering/6. 文本转换 Transforming.ipynb
index d1a43ef..343afb3 100644
--- a/content/Prompt Engineering/6. 文本转换 Transforming.ipynb
+++ b/content/Prompt Engineering/6. 文本转换 Transforming.ipynb
@@ -13,7 +13,7 @@
"id": "2fac57c2",
"metadata": {},
"source": [
- "LLM非常擅长将输入转换成不同的格式,例如多语种文本翻译、拼写及语法纠正、语气调整、格式转换等。\n",
+ "LLM非常擅长将输入转换成不同的格式,典型应用包括多语种文本翻译、拼写及语法纠正、语气调整、格式转换等。\n",
"\n",
"本章节将介绍如何使用编程的方式,调用API接口来实现“文本转换”功能。"
]
@@ -640,6 +640,57 @@
},
{
"cell_type": "code",
+<<<<<<< Updated upstream
+=======
+ "execution_count": null,
+ "id": "83235c7b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "prompt = f\"\"\"\n",
+ "proofread and correct this review. Make it more compelling. \n",
+ "Ensure it follows APA style guide and targets an advanced reader. \n",
+ "Output in markdown format.\n",
+ "Text: ```{text}```\n",
+ "\"\"\"\n",
+ "# 校对注:APA style guide是APA Style Guide是一套用于心理学和相关领域的研究论文写作和格式化的规则。\n",
+ "# 它包括了文本的缩略版,旨在快速阅读,包括引用、解释和参考列表,\n",
+ "# 其详细内容可参考:https://apastyle.apa.org/about-apa-style\n",
+ "# 下一单元格内的汉化prompt内容由译者进行了本地化处理,仅供参考\n",
+ "response = get_completion(prompt)\n",
+ "display(Markdown(response))\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "4bd30c51",
+ "metadata": {},
+ "source": [
+ "注:以下结果暂时由new bing生成(2023年7月5日,more creative)经校对与原视频输出结构与内容大致相同。\n",
+ "\n",
+ "**Review of Panda Plush Toy**\n",
+ "\n",
+ "**Introduction**\n",
+ "\n",
+ "I bought this panda plush toy as a birthday gift for my daughter, who loves pandas as much as I do. This toy is very soft and adorable, and my daughter enjoys carrying it around with her everywhere. However, I also noticed some flaws in the toy’s design and size that made me question its value for money.\n",
+ "\n",
+ "**Appearance and Quality**\n",
+ "\n",
+ "The toy has a realistic black and white fur pattern and a cute expression on its face. It is made of high-quality material that feels smooth and gentle to the touch. One of the ears is slightly lower than the other, which may be a manufacturing defect or an intentional asymmetry to make it look more natural. The toy is also quite small, measuring about 12 inches in height. I expected it to be bigger for the price I paid, as I have seen other plush toys that are larger and cheaper.\n",
+ "\n",
+ "**Delivery and Service**\n",
+ "\n",
+ "The toy arrived a day earlier than the estimated delivery date, which was a pleasant surprise. It was well-packaged and in good condition when I received it. The seller also included a thank-you note and a coupon for my next purchase, which I appreciated.\n",
+ "\n",
+ "**Conclusion**\n",
+ "\n",
+ "Overall, this panda plush toy is a lovely and cuddly gift for any panda lover, especially children. It has a high-quality feel and a charming appearance, but it also has some minor flaws in its design and size that may affect its value. I would recommend this toy to anyone who is looking for a small and cute panda plush, but not to those who want a large and realistic one."
+ ]
+ },
+ {
+ "cell_type": "code",
+>>>>>>> Stashed changes
"execution_count": 24,
"id": "5061d6a3",
"metadata": {