diff --git a/content/Prompt Engineering/4. 文本概括 Summarizing.ipynb b/content/Prompt Engineering/4. 文本概括 Summarizing.ipynb
index 0eb3c7a..bd64e9f 100644
--- a/content/Prompt Engineering/4. 文本概括 Summarizing.ipynb
+++ b/content/Prompt Engineering/4. 文本概括 Summarizing.ipynb
@@ -269,7 +269,7 @@
"id": "d6f8509a",
"metadata": {},
"source": [
- "**侧重于快递服务**"
+ "### 2.2.1 侧重于快递服务"
]
},
{
@@ -354,7 +354,7 @@
"id": "83275907",
"metadata": {},
"source": [
- "**侧重于价格与质量**"
+ "### 2.2.2 侧重于价格与质量"
]
},
{
@@ -677,7 +677,13 @@
"id": "d757b389",
"metadata": {},
"source": [
- "**回答暂缺**"
+ "0 概括:可爱的熊猫毛绒玩具,质量好,送货快,但有点小。 \n",
+ "\n",
+ "1 这个评论是关于一款具有额外储存空间的床头灯,价格适中。客户对公司的服务和产品表示满意。 \n",
+ "\n",
+ "2 评论概括:电动牙刷电池寿命长,但刷头太小,需要更长的刷毛。价格合理,使用后牙齿感觉干净。 \n",
+ "\n",
+ "3 评论概括:产品价格在12月份上涨,质量不如以前,但交付速度快。 "
]
}
],
diff --git a/content/Prompt Engineering/5. 推断 Inferring.ipynb b/content/Prompt Engineering/5. 推断 Inferring.ipynb
index b28c928..84353de 100644
--- a/content/Prompt Engineering/5. 推断 Inferring.ipynb
+++ b/content/Prompt Engineering/5. 推断 Inferring.ipynb
@@ -5,16 +5,49 @@
"id": "3630c235-f891-4874-bd0a-5277d4d6aa82",
"metadata": {},
"source": [
- "# 推断\n",
+ "# 第五章 推断\n",
"\n",
"在这节课中,你将从产品评论和新闻文章中推断情感和主题。\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aeb0eaf6",
+ "metadata": {},
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5f3abbee",
+ "metadata": {},
+ "source": [
+ "## 一、引言\n",
"\n",
- "这些任务可以看作是模型接收文本作为输入并执行某种分析的过程。这可能涉及提取标签、提取实体、理解文本情感等等。如果你想要从一段文本中提取正面或负面情感,在传统的机器学习工作流程中,需要收集标签数据集、训练模型、确定如何在云端部署模型并进行推断。这样做可能效果还不错,但是这个过程需要很多工作。而且对于每个任务,如情感分析、提取实体等等,都需要训练和部署单独的模型。\n",
+ "推断任务可以看作是模型接收文本作为输入,并执行某种分析的过程。其中涉及提取标签、提取实体、理解文本情感等等。如果你想要从一段文本中提取正面或负面情感,在传统的机器学习工作流程中,需要收集标签数据集、训练模型、确定如何在云端部署模型并进行推断。这样做可能效果还不错,但是执行全流程需要很多工作。而且对于每个任务,如情感分析、提取实体等等,都需要训练和部署单独的模型。\n",
"\n",
- "大型语言模型的一个非常好的特点是,对于许多这样的任务,你只需要编写一个prompt即可开始产生结果,而不需要进行大量的工作。这极大地加快了应用程序开发的速度。你还可以只使用一个模型和一个 API 来执行许多不同的任务,而不需要弄清楚如何训练和部署许多不同的模型。\n",
- "\n",
- "\n",
- "## 启动"
+ "LLM 的一个非常好的特点是,对于许多这样的任务,你只需要编写一个 Prompt 即可开始产出结果,而不需要进行大量的工作。这极大地加快了应用程序开发的速度。你还可以只使用一个模型和一个 API 来执行许多不同的任务,而不需要弄清楚如何训练和部署许多不同的模型。"
]
},
{
@@ -57,9 +90,10 @@
"id": "51d2fdfa-c99f-4750-8574-dba7712cd7f0",
"metadata": {},
"source": [
- "## 商品评论文本\n",
+ "## 二、情感推断与信息提取\n",
+ "### 2.1 情感分类\n",
"\n",
- "这是一盏台灯的评论。"
+ "以电商平台关于一盏台灯的评论为例,可以对其传达的情感进行二分类(正向/负向)。"
]
},
{
@@ -100,14 +134,18 @@
"\"\"\""
]
},
+ {
+ "cell_type": "markdown",
+ "id": "cc4ec4ca",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "30d6e4bd-3337-45a3-8c99-a734cdd06743",
"metadata": {},
"source": [
- "## 情感(正向/负向)\n",
- "\n",
- "现在让我们来编写一个prompt来分类这个评论的情感。如果我想让系统告诉我这个评论的情感是什么,只需要编写 “以下产品评论的情感是什么” 这个prompt,加上通常的分隔符和评论文本等等。\n",
+ "现在让我们来编写一个 Prompt 来分类这个评论的情感。如果我想让系统告诉我这个评论的情感是什么,只需要编写 “以下产品评论的情感是什么” 这个 Prompt ,加上通常的分隔符和评论文本等等。\n",
"\n",
"然后让我们运行一下。结果显示这个产品评论的情感是积极的,这似乎是非常正确的。虽然这盏台灯不完美,但这个客户似乎非常满意。这似乎是一家关心客户和产品的伟大公司,可以认为积极的情感似乎是正确的答案。"
]
@@ -164,12 +202,18 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "a562e656",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "76be2320",
"metadata": {},
"source": [
- "如果你想要给出更简洁的答案,以便更容易进行后处理,可以使用上面的prompt并添加另一个指令,以一个单词 “正面” 或 “负面” 的形式给出答案。这样就只会打印出 “正面” 这个单词,这使得文本更容易接受这个输出并进行处理。"
+ "如果你想要给出更简洁的答案,以便更容易进行后处理,可以在上述 Prompt 基础上添加另一个指令:*用一个单词回答:「正面」或「负面」*。这样就只会打印出 “正面” 这个单词,这使得输出更加统一,方便后续处理。"
]
},
{
@@ -233,9 +277,9 @@
"id": "81d2a973-1fa4-4a35-ae35-a2e746c0e91b",
"metadata": {},
"source": [
- "## 识别情感类型\n",
+ "### 2.2 识别情感类型\n",
"\n",
- "让我们看看另一个prompt,仍然使用台灯评论。这次我要让它识别出以下评论作者所表达的情感列表,不超过五个。"
+ "仍然使用台灯评论,我们尝试另一个 Prompt 。这次我需要模型识别出评论作者所表达的情感,并归纳为列表,不超过五项。"
]
},
{
@@ -292,12 +336,18 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "c7743a53",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "cc4444f7",
"metadata": {},
"source": [
- "大型语言模型非常擅长从一段文本中提取特定的东西。在上面的例子中,评论正在表达情感,这可能有助于了解客户如何看待特定的产品。"
+ "大型语言模型非常擅长从一段文本中提取特定的东西。在上面的例子中,评论所表达的情感有助于了解客户如何看待特定的产品。"
]
},
{
@@ -305,9 +355,9 @@
"id": "a428d093-51c9-461c-b41e-114e80876409",
"metadata": {},
"source": [
- "## 识别愤怒\n",
+ "### 2.3 识别愤怒\n",
"\n",
- "对于很多企业来说,了解某个顾客是否非常生气很重要。所以你可能有一个类似这样的分类问题:以下评论的作者是否表达了愤怒情绪?因为如果有人真的很生气,那么可能值得额外关注,让客户支持或客户成功团队联系客户以了解情况,并为客户解决问题。"
+ "对于很多企业来说,了解某个顾客是否非常生气很重要。所以产生了下述分类问题:以下评论的作者是否表达了愤怒情绪?因为如果有人真的很生气,那么可能值得额外关注,让客户支持或客户成功团队联系客户以了解情况,并为客户解决问题。"
]
},
{
@@ -363,12 +413,18 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "77905fd8",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "11ca57a2",
"metadata": {},
"source": [
- "上面这个例子中,客户并没有生气。注意,如果使用常规的监督学习,如果想要建立所有这些分类器,不可能在几分钟内就做到这一点。我们鼓励大家尝试更改一些这样的prompt,也许询问客户是否表达了喜悦,或者询问是否有任何遗漏的部分,并看看是否可以让prompt对这个灯具评论做出不同的推论。"
+ "上面这个例子中,客户并没有生气。注意,如果使用常规的监督学习,如果想要建立所有这些分类器,不可能在几分钟内就做到这一点。我们鼓励大家尝试更改一些这样的 Prompt ,也许询问客户是否表达了喜悦,或者询问是否有任何遗漏的部分,并看看是否可以让 Prompt 对这个灯具评论做出不同的推论。"
]
},
{
@@ -376,13 +432,13 @@
"id": "936a771e-ca78-4e55-8088-2da6f3820ddc",
"metadata": {},
"source": [
- "## 从客户评论中提取产品和公司名称\n",
+ "### 2.4 商品信息提取\n",
"\n",
- "接下来,让我们从客户评论中提取更丰富的信息。信息提取是自然语言处理(NLP)的一部分,与从文本中提取你想要知道的某些事物相关。因此,在这个prompt中,我要求它识别以下内容:购买物品和制造物品的公司名称。\n",
+ "接下来,让我们从客户评论中提取更丰富的信息。信息提取是自然语言处理(NLP)的一部分,与从文本中提取你想要知道的某些事物相关。因此,在这个 Prompt 中,我要求它识别以下内容:购买物品和制造物品的公司名称。\n",
"\n",
- "同样,如果你试图总结在线购物电子商务网站的许多评论,对于这些评论来说,弄清楚是什么物品,谁制造了该物品,弄清楚积极和消极的情感,以跟踪特定物品或特定制造商的积极或消极情感趋势,可能会很有用。\n",
+ "同样,如果你试图总结在线购物电子商务网站的许多评论,对于这些评论来说,弄清楚是什么物品、谁制造了该物品,弄清楚积极和消极的情感,有助于追踪特定物品或制造商收获的用户情感趋势。\n",
"\n",
- "在下面这个示例中,我们要求它将响应格式化为一个 JSON 对象,其中物品和品牌是键。"
+ "在下面这个示例中,我们要求它将响应格式化为一个 JSON 对象,其中物品和品牌作为键。"
]
},
{
@@ -457,6 +513,12 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "1342c732",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "954d125d",
@@ -470,9 +532,9 @@
"id": "a38880a5-088f-4609-9913-f8fa41fb7ba0",
"metadata": {},
"source": [
- "## 一次完成多项任务\n",
+ "### 2.5 综合完成任务\n",
"\n",
- "提取上面所有这些信息使用了 3 或 4 个prompt,但实际上可以编写单个prompt来同时提取所有这些信息。"
+ "提取上述所有信息使用了 3 或 4 个 Prompt ,但实际上可以编写单个 Prompt 来同时提取所有这些信息。"
]
},
{
@@ -564,7 +626,7 @@
"id": "5e09a673",
"metadata": {},
"source": [
- "这个例子中,我们告诉它将愤怒值格式化为布尔值,然后输出一个 JSON。大家可以自己尝试不同的变化,或者甚至尝试完全不同的评论,看看是否仍然可以准确地提取这些内容。"
+ "这个例子中,我们告诉它将愤怒值格式化为布尔值,然后输出一个 JSON。您可以自己尝试不同的变化,或者甚至尝试完全不同的评论,看看是否仍然可以准确地提取这些内容。"
]
},
{
@@ -572,9 +634,9 @@
"id": "235fc223-2c89-49ec-ac2d-78a8e74a43ac",
"metadata": {},
"source": [
- "## 推断主题\n",
+ "## 三、主题推断\n",
"\n",
- "大型语言模型的一个很酷的应用是推断主题。给定一段长文本,这段文本是关于什么的?有什么话题?"
+ "大型语言模型的另一个很酷的应用是推断主题。给定一段长文本,这段文本是关于什么的?有什么话题?以以下一段虚构的报纸报道为例。"
]
},
{
@@ -644,7 +706,7 @@
"id": "a8ea91d6-e841-4ee2-bed9-ca4a36df177f",
"metadata": {},
"source": [
- "## 推断5个主题\n",
+ "### 3.1 推断讨论主题\n",
"\n",
"上面是一篇虚构的关于政府工作人员对他们工作机构感受的报纸文章。我们可以让它确定五个正在讨论的主题,用一两个字描述每个主题,并将输出格式化为逗号分隔的列表。"
]
@@ -737,12 +799,18 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "790d1435",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "34be1d2a-1309-4512-841a-b6f67338938b",
"metadata": {},
"source": [
- "## 为特定主题制作新闻提醒\n",
+ "### 3.2 为特定主题制作新闻提醒\n",
"\n",
"假设我们有一个新闻网站或类似的东西,这是我们感兴趣的主题:NASA、地方政府、工程、员工满意度、联邦政府等。假设我们想弄清楚,针对一篇新闻文章,其中涵盖了哪些主题。可以使用这样的prompt:确定以下主题列表中的每个项目是否是以下文本中的主题。以 0 或 1 的形式给出答案列表。"
]
@@ -853,12 +921,18 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "8f39f24a",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "08247dbf",
"metadata": {},
"source": [
- "所以,这个故事是关于 NASA 的。它不是关于当地政府的,不是关于工程的。它是关于员工满意度的,它是关于联邦政府的。这在机器学习中有时被称为 Zero-Shot 学习算法,因为我们没有给它任何标记的训练数据。仅凭prompt,它就能确定哪些主题在新闻文章中涵盖了。\n",
+ "有结果可见,这个故事是与关于 NASA 、员工满意度、联邦政府有关,而与当地政府的、工程学无关。这在机器学习中有时被称为 Zero-Shot (零样本)学习算法,因为我们没有给它任何标记的训练数据。仅凭 Prompt ,它就能确定哪些主题在新闻文章中有所涵盖。\n",
"\n",
"如果我们想生成一个新闻提醒,也可以使用这个处理新闻的过程。假设我非常喜欢 NASA 所做的工作,就可以构建一个这样的系统,每当 NASA 新闻出现时,输出提醒。"
]
@@ -885,29 +959,17 @@
},
{
"cell_type": "markdown",
- "id": "76ccd189",
+ "id": "9fc2c643",
"metadata": {},
- "source": [
- "这就是关于推断的全部内容了,仅用几分钟时间,我们就可以构建多个用于对文本进行推理的系统,而以前则需要熟练的机器学习开发人员数天甚至数周的时间。这非常令人兴奋,无论是对于熟练的机器学习开发人员还是对于新手来说,都可以使用prompt来非常快速地构建和开始相当复杂的自然语言处理任务。"
- ]
+ "source": []
},
{
"cell_type": "markdown",
- "id": "f88408ae-469a-4b02-a043-f6b4f0b14bf9",
+ "id": "76ccd189",
"metadata": {},
"source": [
- "## 尝试你的实验!"
+ "这就是关于推断的全部内容了,仅用几分钟时间,我们就可以构建多个用于对文本进行推理的系统,而以前则需要熟练的机器学习开发人员数天甚至数周的时间。这非常令人兴奋,无论是对于熟练的机器学习开发人员,还是对于新手来说,都可以使用 Prompt 来非常快速地构建和开始相当复杂的自然语言处理任务。"
]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "1bd3553f",
- "metadata": {
- "height": 30
- },
- "outputs": [],
- "source": []
}
],
"metadata": {
diff --git a/content/Prompt Engineering/6. 文本转换 Transforming.ipynb b/content/Prompt Engineering/6. 文本转换 Transforming.ipynb
index 6cbb33d..9d88f7d 100644
--- a/content/Prompt Engineering/6. 文本转换 Transforming.ipynb
+++ b/content/Prompt Engineering/6. 文本转换 Transforming.ipynb
@@ -1,12 +1,46 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "08879154",
+ "metadata": {},
+ "source": [
+ "# 第六章 文本转换"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c885ce7b",
+ "metadata": {},
+ "source": [
+ "\n",
+ "
\n",
+ " - 一、引言
\n",
+ " - \n",
+ " 二、文本翻译\n",
+ " \n",
+ "
\n",
+ " - 三、语气与写作风格调整
\n",
+ " - 四、文件格式转换
\n",
+ " - 五、拼写及语法纠正
\n",
+ " - 六、综合样例
\n",
+ "
\n",
+ "
"
+ ]
+ },
{
"attachments": {},
"cell_type": "markdown",
"id": "78624add",
"metadata": {},
"source": [
- "## 1 引言"
+ "## 一、引言"
]
},
{
@@ -66,7 +100,7 @@
"id": "bf3733d4",
"metadata": {},
"source": [
- "## 2 文本翻译"
+ "## 二、文本翻译"
]
},
{
@@ -75,7 +109,7 @@
"id": "1b418e32",
"metadata": {},
"source": [
- "**中文转西班牙语**"
+ "### 2.1 中文转西班牙语"
]
},
{
@@ -118,13 +152,19 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "7e7be208",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
"id": "e3e922b4",
"metadata": {},
"source": [
- "**识别语种**"
+ "### 2.2 识别语种"
]
},
{
@@ -165,13 +205,19 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "8a9477e9",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
"id": "c1841354",
"metadata": {},
"source": [
- "**多语种翻译**"
+ "### 2.3 多语种翻译"
]
},
{
@@ -216,13 +262,19 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "8d5022c7",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
"id": "68723ba5",
"metadata": {},
"source": [
- "**翻译+正式语气**"
+ "### 2.4 同时进行语气转换"
]
},
{
@@ -265,13 +317,19 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "7b7f6c87",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
"id": "b2dc4c56",
"metadata": {},
"source": [
- "**通用翻译器**"
+ "### 2.5 通用翻译器"
]
},
{
@@ -375,13 +433,19 @@
" print(response, \"\\n=========================================\")"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "607cdcba",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
"id": "6ab558a2",
"metadata": {},
"source": [
- "## 3 语气/ 写作风格调整"
+ "## 三、语气与写作风格调整"
]
},
{
@@ -441,13 +505,19 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "79da6b29",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
"id": "98df9009",
"metadata": {},
"source": [
- "## 4 格式转换"
+ "## 四、文件格式转换"
]
},
{
@@ -488,6 +558,14 @@
"print(response)\n"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "e1c7f30c",
+ "metadata": {},
+ "source": [
+ "结果同下"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 10,
@@ -584,7 +662,7 @@
"id": "29b7167b",
"metadata": {},
"source": [
- "## 5 拼写及语法纠正"
+ "## 五、拼写及语法纠正"
]
},
{
@@ -667,13 +745,19 @@
" print(i, response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "ef7e1dae",
+ "metadata": {},
+ "source": []
+ },
{
"attachments": {},
"cell_type": "markdown",
"id": "538181e0",
"metadata": {},
"source": [
- "以下是一个简单的语法纠错示例(译注:与Grammarly功能类似),输入文本为一段关于熊猫玩偶的评价,输出为纠正后的文本。本例使用的prompt较为简单,你也可以进一步要求进行语调的更改。"
+ "以下是一个简单的语法纠错示例(译注:与 Grammarly 功能类似),输入文本为一段关于熊猫玩偶的评价,输出为纠正后的文本。本例使用的 Prompt 较为简单,你也可以进一步要求进行语调的更改。"
]
},
{
@@ -707,6 +791,14 @@
"print(response)\n"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "63871b58",
+ "metadata": {},
+ "source": [
+ "结果同下"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 14,
@@ -733,7 +825,7 @@
"id": "2e2d1f6a",
"metadata": {},
"source": [
- "引入Redlines包,详细显示并对比纠错过程:"
+ "引入 ```Redlines``` 包,详细显示并对比纠错过程:"
]
},
{
@@ -780,7 +872,7 @@
"id": "3ee5d487",
"metadata": {},
"source": [
- "## 6 综合样例\n",
+ "## 六、综合样例\n",
"下述例子展示了同一段评论,用一段prompt同时进行文本翻译+拼写纠正+风格调整+格式转换。"
]
},
diff --git a/content/Prompt Engineering/7. 文本扩展 Expanding.ipynb b/content/Prompt Engineering/7. 文本扩展 Expanding.ipynb
index 9517f32..ac9a64a 100644
--- a/content/Prompt Engineering/7. 文本扩展 Expanding.ipynb
+++ b/content/Prompt Engineering/7. 文本扩展 Expanding.ipynb
@@ -4,18 +4,34 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# 第七章 扩展\n",
- "\n",
- "扩展是将短文本,例如一组说明或主题列表,输入到大型语言模型中,让模型生成更长的文本,例如基于某个主题的电子邮件或论文。这样做有一些很好的用途,例如将大型语言模型用作头脑风暴的伙伴。但这种做法也存在一些问题,例如某人可能会使用它来生成大量垃圾邮件。因此,当你使用大型语言模型的这些功能时,请仅以负责任的方式和有益于人们的方式使用它们。\n",
- "\n",
- "在本章中,你将学会如何基于 OpenAI API 生成适用于每个客户评价的客户服务电子邮件。我们还将使用模型的另一个输入参数称为温度,这种参数允许您在模型响应中变化探索的程度和多样性。\n"
+ "# 第七章 文本扩展"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "## 一、环境配置\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 一、引言\n",
+ "\n",
+ "扩展是将短文本(例如一组说明或主题列表)输入到大型语言模型中,让模型生成更长的文本(例如基于某个主题的电子邮件或论文)。这种应用是一把双刃剑,好处例如将大型语言模型用作头脑风暴的伙伴;但也存在问题,例如某人可能会使用它来生成大量垃圾邮件。因此,当你使用大型语言模型的这些功能时,请仅以**负责任** (responsible) 和**有益于人们** (helps people) 的方式使用它们。\n",
+ "\n",
+ "在本章中,你将学会如何基于 OpenAI API 生成*针对每位客户评价优化*的客服电子邮件。我们还将利用模型的另一个输入参数称为温度,这种参数允许您在模型响应中变化探索的程度和多样性。\n",
"\n",
"同以上几章,你需要类似的代码来配置一个可以使用 OpenAI API 的环境"
]
@@ -67,14 +83,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "我们将根据客户评价和情感撰写自定义电子邮件响应。因此,我们将给定客户评价和情感,并生成自定义响应即使用 LLM 根据客户评价和评论情感生成定制电子邮件。"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "我们首先给出一个示例,包括一个评论及对应的情感"
+ "我们将根据客户评价和情感,针对性写自动回复邮件。因此,我们将给定客户评价和情感,使用 LLM 针对性生成响应,即根据客户评价和评论情感生成定制电子邮件。\n",
+ "\n",
+ "我们首先给出一个示例,包括一个评论及对应的情感。"
]
},
{
@@ -149,13 +160,18 @@
"\"\"\""
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "我们已经使用推断课程中学到的提取了情感,这是一个关于搅拌机的客户评价,现在我们将根据情感定制回复。\n",
+ "我们已经使用推断课程中所学方法提取了情感,这是一个关于搅拌机的客户评价,现在我们将根据情感定制回复。\n",
"\n",
- "这里的指令是:假设你是一个客户服务AI助手,你的任务是为客户发送电子邮件回复,根据通过三个反引号分隔的客户电子邮件,生成一封回复以感谢客户的评价。"
+ "以下述 Prompt 为例:假设你是一个客户服务 AI 助手,你的任务是为客户发送电子邮件回复,根据通过三个反引号分隔的客户电子邮件,生成一封回复以感谢客户的评价。"
]
},
{
@@ -239,62 +255,29 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "## 三、使用温度系数\n",
+ "## 三、引入温度系数\n",
"\n",
- "接下来,我们将使用语言模型的一个称为“温度”的参数,它将允许我们改变模型响应的多样性。您可以将温度视为模型探索或随机性的程度。\n",
+ "接下来,我们将使用语言模型的一个称为“温度” (Temperature) 的参数,它将允许我们改变模型响应的多样性。您可以将温度视为模型探索或随机性的程度。\n",
"\n",
- "例如,在一个特定的短语中,“我的最爱食品”最有可能的下一个词是“比萨”,其次最有可能的是“寿司”和“塔可”。因此,在温度为零时,模型将总是选择最有可能的下一个词,而在较高的温度下,它还将选择其中一个不太可能的词,在更高的温度下,它甚至可能选择塔可,而这种可能性仅为五分之一。您可以想象,随着模型继续生成更多单词的最终响应,“我的最爱食品是比萨”将会与第一个响应“我的最爱食品是塔可”产生差异。因此,随着模型的继续,这两个响应将变得越来越不同。\n",
+ "例如,在一个特定的短语中,“我的最爱食品”最有可能的下一个词是“比萨”,其次最有可能的是“寿司”和“塔可”。因此,在温度为零时,模型将总是选择最有可能的下一个词,而在较高的温度下,它还将选择其中一个不太可能的词,在更高的温度下,它甚至可能选择塔可,而这种可能性仅为五分之一。您可以想象,随着模型继续生成更多单词的最终响应,“我的最爱食品是比萨”将会与第一个响应“我的最爱食品是塔可”产生差异。随着模型的继续,这两个响应也将变得越来越不同。\n",
"\n",
- "一般来说,在构建需要可预测响应的应用程序时,我建议使用温度为零。在所有课程中,我们一直设置温度为零,如果您正在尝试构建一个可靠和可预测的系统,我认为您应该选择这个温度。如果您尝试以更具创意的方式使用模型,可能需要更广泛地输出不同的结果,那么您可能需要使用更高的温度。"
+ "一般来说,在构建需要可预测响应的应用程序时,我建议**设置温度为零**。在所有课程中,我们一直设置温度为零,如果您正在尝试构建一个可靠和可预测的系统,我认为您应该选择这个温度。如果您尝试以更具创意的方式使用模型,可能需要更广泛地输出不同的结果,那么您可能需要使用更高的温度。"
]
},
{
- "cell_type": "code",
- "execution_count": 7,
+ "cell_type": "markdown",
"metadata": {},
- "outputs": [],
"source": [
- "# given the sentiment from the lesson on \"inferring\",\n",
- "# and the original customer message, customize the email\n",
- "sentiment = \"negative\"\n",
- "\n",
- "# review for a blender\n",
- "review = f\"\"\"\n",
- "So, they still had the 17 piece system on seasonal \\\n",
- "sale for around $49 in the month of November, about \\\n",
- "half off, but for some reason (call it price gouging) \\\n",
- "around the second week of December the prices all went \\\n",
- "up to about anywhere from between $70-$89 for the same \\\n",
- "system. And the 11 piece system went up around $10 or \\\n",
- "so in price also from the earlier sale price of $29. \\\n",
- "So it looks okay, but if you look at the base, the part \\\n",
- "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",
- "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",
- "spinach then freeze until ready for use-and if making \\\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",
- "I called customer service but the warranty expired \\\n",
- "already, so I had to buy another one. FYI: The overall \\\n",
- "quality has gone done in these types of products, so \\\n",
- "they are kind of counting on brand recognition and \\\n",
- "consumer loyalty to maintain sales. Got it in about \\\n",
- "two days.\n",
- "\"\"\""
+ "同一段来信,我们提醒模型使用用户来信中的详细信息,并设置温度:"
]
},
{
@@ -394,11 +377,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "在温度为零时,每次执行相同的提示时,您应该期望获得相同的完成。而使用温度为0.7,则每次都会获得不同的输出。\n",
+ "在温度为零时,每次执行相同的 Prompt ,您获得的回复理应相同。而使用温度为 0.7 时,则每次都会获得不同的输出。\n",
"\n",
- "所以,您可以看到它与我们之前收到的电子邮件不同。让我们再次执行它,以显示我们将再次获得不同的电子邮件。\n",
+ "所以,您可以看到它与我们之前收到的电子邮件不同。再次执行将再次获得不同的电子邮件。\n",
"\n",
- "因此,我建议您自己尝试温度,以查看输出如何变化。总之,在更高的温度下,模型的输出更加随机。您几乎可以将其视为在更高的温度下,助手更易分心,但也许更有创造力。"
+ "因此,我建议您自己尝试温度,以查看输出如何变化。总之,在更高的温度下,模型的输出更加随机。您几乎可以将其视为在更高的温度下,助手**更易分心**,但也许**更有创造力**。"
]
}
],
diff --git a/content/Prompt Engineering/8. 聊天机器人 Chatbot.ipynb b/content/Prompt Engineering/8. 聊天机器人 Chatbot.ipynb
index f66b240..1a363b2 100644
--- a/content/Prompt Engineering/8. 聊天机器人 Chatbot.ipynb
+++ b/content/Prompt Engineering/8. 聊天机器人 Chatbot.ipynb
@@ -7,12 +7,36 @@
"id": "JMXGlIvAwn30"
},
"source": [
- "# 对话聊天\n",
+ "# 第八章 聊天机器人"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4164d820",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f0bdc2c9",
+ "metadata": {},
+ "source": [
+ "## 一、引言\n",
"\n",
- "使用一个大型语言模型的一个令人兴奋的事情是,我们可以用它来构建一个定制的聊天机器人,只需要很少的工作量。在这一节中,我们将探索如何利用聊天格式(接口)与个性化或专门针对特定任务或行为的聊天机器人进行延伸对话。\n",
- "\n",
- "\n",
- "## 启动"
+ "使用一个大型语言模型的一个令人兴奋的事情是,我们可以用它来构建一个定制的聊天机器人 (Chatbot) ,只需要很少的工作量。在这一节中,我们将探索如何利用聊天的方式,与个性化(或专门针对特定任务或行为的)聊天机器人进行扩展对话。"
]
},
{
@@ -31,18 +55,34 @@
"# 设置 API_KEY, 请替换成您自己的 API_KEY"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "e6fae355",
+ "metadata": {},
+ "source": [
+ "像 ChatGPT 这样的聊天模型实际上是组装成以一系列消息作为输入,并返回一个模型生成的消息作为输出的。这种聊天格式原本的设计目标是简便多轮对话,但我们通过之前的学习可以知道,它对于不会涉及任何对话的**单轮任务**也同样有用。\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "78344a7e",
+ "metadata": {},
+ "source": [
+ "## 二、身份与上下文构建"
+ ]
+ },
{
"cell_type": "markdown",
"id": "2c9b885b",
"metadata": {},
"source": [
- "像 ChatGPT 这样的聊天模型实际上是组装成以一系列消息作为输入,并返回一个模型生成的消息作为输出的。虽然聊天格式的设计旨在使这种多轮对话变得容易,但我们通过之前的学习可以知道,它对于没有任何对话的单轮任务也同样有用。\n",
+ "接下来,我们将定义两个辅助函数。\n",
"\n",
- "接下来,我们将定义两个辅助函数。第一个是单轮的,我们将prompt放入看起来像是某种用户消息的东西中。另一个则传入一个消息列表。这些消息可以来自不同的角色,我们会描述一下这些角色。\n",
+ "第一个方法已经陪伴了您一整个教程,即 ```get_completion``` ,其适用于单轮对话。我们将 Prompt 放入某种类似**用户消息**的对话框中。另一个称为 ```get_completion_from_messages``` ,传入一个消息列表。这些消息可以来自大量不同的**角色** (roles) ,我们会描述一下这些角色。\n",
"\n",
- "第一条消息是一个系统消息,它提供了一个总体的指示,然后在这个消息之后,我们有用户和助手之间的交替。如果你曾经使用过 ChatGPT 网页界面,那么你的消息是用户消息,而 ChatGPT 的消息是助手消息。系统消息则有助于设置助手的行为和角色,并作为对话的高级指示。你可以想象它在助手的耳边低语,引导它的回应,而用户不会注意到系统消息。\n",
+ "第一条消息中,我们以系统身份发送系统消息 (system message) ,它提供了一个总体的指示。系统消息则有助于设置助手的行为和角色,并作为对话的高级指示。你可以想象它在助手的耳边低语,引导它的回应,而用户不会注意到系统消息。因此,作为用户,如果你曾经使用过 ChatGPT,您可能从来不知道 ChatGPT 的系统消息是什么,这是有意为之的。系统消息的好处是为开发者提供了一种方法,在不让请求本身成为对话的一部分的情况下,引导助手并指导其回应。\n",
"\n",
- "因此,作为用户,如果你曾经使用过 ChatGPT,你可能不知道 ChatGPT 的系统消息是什么,这是有意为之的。系统消息的好处是为开发者提供了一种方法,在不让请求本身成为对话的一部分的情况下,引导助手并指导其回应。"
+ "在 ChatGPT 网页界面中,您的消息称为用户消息,而 ChatGPT 的消息称为助手消息。但在构建聊天机器人时,在发送了系统消息之后,您的角色可以仅作为用户 (user) ;也可以在用户和助手 (assistant) 之间交替,从而提供对话上下文。"
]
},
{
@@ -78,9 +118,9 @@
"id": "46caaa5b",
"metadata": {},
"source": [
- "现在让我们尝试在对话中使用这些消息。我们将使用上面的函数来获取从这些消息中得到的回答,同时,使用更高的 temperature(越高生成的越多样)。\n",
+ "现在让我们尝试在对话中使用这些消息。我们将使用上面的函数来获取从这些消息中得到的回答,同时,使用更高的温度 (temperature)(越高生成的越多样,更多内容见第七章)。\n",
"\n",
- "系统消息说,你是一个说话像莎士比亚的助手。这是我们向助手描述它应该如何表现的方式。然后,第一个用户消息是,给我讲个笑话。接下来的消息是,为什么鸡会过马路?然后最后一个用户消息是,我不知道。"
+ "系统消息说,你是一个说话像莎士比亚的助手。这是我们向助手描述**它应该如何表现的方式**。然后,第一个用户消息是*给我讲个笑话*。接下来以助手身份给出回复是,*为什么鸡会过马路?* 最后发送用户消息是*我不知道*。"
]
},
{
@@ -154,12 +194,61 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "3b3e5b83",
+ "metadata": {},
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7f51a7e0",
+ "metadata": {},
+ "source": [
+ "(注:上述例子中由于选定 temperature = 1,模型的回答会比较随机且迥异(不乏很有创意)。此处附上另一个回答:\n",
+ "\n",
+ "让我用一首莎士比亚式的诗歌来回答你的问题:\n",
+ "\n",
+ "当鸡之心欲往前,\n",
+ "马路之际是其选择。\n",
+ "驱车徐行而天晴,\n",
+ "鸣笛吹响伴交错。\n",
+ "\n",
+ "问之何去何从也?\n",
+ "因大道之上未有征,\n",
+ "而鸡乃跃步前进,\n",
+ "其决策毋需犹豫。\n",
+ "\n",
+ "鸡之智慧何可言,\n",
+ "道路孤独似乌漆。\n",
+ "然其勇气令人叹,\n",
+ "勇往直前没有退。\n",
+ "\n",
+ "故鸡过马路何解?\n",
+ "忍受车流喧嚣之困厄。\n",
+ "因其鸣鸣悍然一跃,\n",
+ "成就夸夸骄人壁画。\n",
+ "\n",
+ "所以笑话之妙处,\n",
+ "伴随鸡之勇气满溢。\n",
+ "笑谈人生不畏路,\n",
+ "有智有勇尽显妙。\n",
+ "\n",
+ "希望这个莎士比亚风格的回答给你带来一些欢乐!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d70fd298",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "5f76bedb",
"metadata": {},
"source": [
- "让我们做另一个例子。助手的消息是,你是一个友好的聊天机器人,第一个用户消息是,嗨,我叫Isa。我们想要得到第一个用户消息。"
+ "让我们看另一个例子。助手的消息是*你是一个友好的聊天机器人*,第一个用户消息是*嗨,我叫Isa*。我们想要得到第一个用户消息。"
]
},
{
@@ -209,6 +298,12 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "63c2010b",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "1e9f96ba",
@@ -264,6 +359,12 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "da1e4df5",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "05c65d16",
@@ -271,7 +372,7 @@
"source": [
"如上所见,模型实际上并不知道我的名字。\n",
"\n",
- "因此,每次与语言模型的交互都是一个独立的交互,这意味着我们必须提供所有相关的消息,以便模型在当前对话中进行引用。如果想让模型引用或 “记住” 对话的早期部分,则必须在模型的输入中提供早期的交流。我们将其称为上下文。让我们试试。"
+ "因此,每次与语言模型的交互都互相独立,这意味着我们必须提供所有相关的消息,以便模型在当前对话中进行引用。如果想让模型引用或 “记住” 对话的早期部分,则必须在模型的输入中提供早期的交流。我们将其称为上下文 (context) 。尝试以下示例。"
]
},
{
@@ -301,6 +402,16 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "a7b40fb0",
+ "metadata": {},
+ "source": [
+ "附上另一次回答:\n",
+ "\n",
+ "*Your name is Isa! How could I forget?*"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 16,
@@ -343,11 +454,11 @@
"id": "bBg_MpXeYnTq"
},
"source": [
- "# 订餐机器人\n",
+ "## 三、订餐机器人\n",
"\n",
"现在,我们构建一个 “订餐机器人”,我们需要它自动收集用户信息,接受比萨饼店的订单。\n",
"\n",
- "下面这个函数将收集我们的用户消息,以便我们可以避免手动输入,就像我们在刚刚上面做的那样。这个函数将从我们下面构建的用户界面中收集提示,然后将其附加到一个名为上下文的列表中,并在每次调用模型时使用该上下文。模型的响应也会被添加到上下文中,所以模型消息和用户消息都被添加到上下文中,因此上下文逐渐变长。这样,模型就有了需要的信息来确定下一步要做什么。"
+ "下面这个函数将收集我们的用户消息,以便我们可以避免像刚才一样手动输入。这个函数将从我们下面构建的用户界面中收集 Prompt ,然后将其附加到一个名为上下文( ```context``` )的列表中,并在每次调用模型时使用该上下文。模型的响应也会添加到上下文中,所以用户消息和模型消息都被添加到上下文中,上下文逐渐变长。这样,模型就有了需要的信息来确定下一步要做什么。"
]
},
{
@@ -378,7 +489,7 @@
"id": "8a3b003e",
"metadata": {},
"source": [
- "现在,我们将设置并运行这个 UI 来显示订单机器人。初始的上下文包含了包含菜单的系统消息。请注意,上下文会随着时间的推移而不断增长。"
+ "现在,我们将设置并运行这个 UI 来显示订单机器人。初始的上下文包含了包含菜单的系统消息,在每次调用时都会使用。此后随着对话进行,上下文也会不断增长。"
]
},
{
@@ -393,43 +504,12 @@
},
{
"cell_type": "code",
- "execution_count": 43,
+ "execution_count": null,
"id": "c9e746f5",
"metadata": {
"tags": []
},
- "outputs": [
- {
- "data": {
- "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'gridstack': {'exports': 'GridStack'}}});\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 2;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.4/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.4/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.4/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.4/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.4/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.4/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.4/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.4/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.4/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.4/dist/css/loading.css\", \"https://cdn.holoviz.org/panel/0.14.4/dist/css/dataframe.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));",
- "application/vnd.holoviews_load.v0+json": ""
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
- "application/vnd.holoviews_load.v0+json": ""
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
"import panel as pn # GUI\n",
"pn.extension()\n",
@@ -476,19 +556,31 @@
" inp,\n",
" pn.Row(button_conversation),\n",
" pn.panel(interactive_conversation, loading_indicator=True, height=300),\n",
- ")"
+ ")\n",
+ "\n",
+ "dashboard"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "65f0416e",
- "metadata": {
- "tags": []
- },
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "42fff07d",
+ "metadata": {},
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "327b15b7",
+ "metadata": {},
"source": [
- "dashboard"
+ "运行结果可交互,请见下文中文版。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "668ea96d",
+ "metadata": {},
+ "source": [
+ "### 3.1 创建JSON摘要"
]
},
{
@@ -496,11 +588,11 @@
"id": "2a2c9822",
"metadata": {},
"source": [
- "现在我们可以要求模型创建一个 JSON 摘要发送给订单系统。\n",
+ "此处我们另外要求模型创建一个 JSON 摘要,方便我们发送给订单系统。\n",
"\n",
- "所以我们现在追加另一个系统消息,它是另一条prompt,我们说创建一个刚刚订单的 JSON 摘要,列出每个项目的价格,字段应包括1)披萨,包括尺寸,2)配料列表,3)饮料列表,4)辅菜列表,包括尺寸,最后是总价格。这里也可以在这里使用用户消息,不一定是系统消息。\n",
+ "因此我们需要在上下文的基础上追加另一个系统消息,作为另一条指示 (instruction) 。我们说*创建一个刚刚订单的 JSON 摘要,列出每个项目的价格,字段应包括 1)披萨,包括尺寸,2)配料列表,3)饮料列表,4)辅菜列表,包括尺寸,最后是总价格*。此处也可以定义为用户消息,不一定是系统消息。\n",
"\n",
- "请注意,这里我们使用了一个较低的temperature,因为对于这些类型的任务,我们希望输出相对可预测。"
+ "请注意,这里我们使用了一个较低的温度,因为对于这些类型的任务,我们希望输出相对可预测。"
]
},
{
@@ -552,8 +644,6 @@
"{'role':'system', 'content':'create a json summary of the previous food order. Itemize the price for each item\\\n",
" 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 '}, \n",
")\n",
- " #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 '}, \n",
- "\n",
"response = get_completion_from_messages(messages, temperature=0)\n",
"print(response)"
]
@@ -777,44 +867,39 @@
"print(response)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "018de2cd",
+ "metadata": {},
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "ef17c2b2",
"metadata": {},
"source": [
- "现在,我们已经建立了自己的订餐聊天机器人。请随意自定义并修改系统消息,以更改聊天机器人的行为,并使其扮演不同的角色和拥有不同的知识。"
+ "现在,我们已经建立了自己的订餐聊天机器人。请随意自定义并修改系统消息,以更改聊天机器人的行为,并使其扮演不同的角色,拥有不同的知识。"
]
},
{
"cell_type": "markdown",
- "id": "3153c581-1c72-497a-9293-8db3bcb804fc",
+ "id": "7f688397",
+ "metadata": {},
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d9f43e62",
"metadata": {},
"source": [
- "## 尝试你的实验!\n",
- "\n",
- "你可以修改菜单或指令来创建自己的订单机器人!"
+ "附:下图展示了订餐机器人一次完整的对话流程:\n",
+ ""
]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "1b0df540",
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "2cc84122",
- "metadata": {},
- "outputs": [],
- "source": []
}
],
"metadata": {
"kernelspec": {
- "display_name": "Python 3",
+ "display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@@ -828,7 +913,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.13"
+ "version": "3.11.0"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
diff --git a/content/Prompt Engineering/9. 总结.md b/content/Prompt Engineering/9. 总结.md
index a64a26e..11b1b4d 100644
--- a/content/Prompt Engineering/9. 总结.md
+++ b/content/Prompt Engineering/9. 总结.md
@@ -1,18 +1,18 @@
-恭喜你完成了这门短期课程。
+**恭喜您完成了这门短期课程。**
-总的来说,在这门课程中,我们学习了关于prompt的两个关键原则:
+总的来说,在这门课程中,我们学习了关于 Prompt 的两个关键原则:
- 编写清晰具体的指令;
- 如果适当的话,给模型一些思考时间。
-你还学习了迭代式prompt开发的方法,并了解了如何找到适合你应用程序的prompt的过程是非常关键的。
+您还学习了迭代式 Prompt 开发的方法,并了解了如何找到适合您应用程序的 Prompt 的过程是非常关键的。
-我们还介绍了许多大型语言模型的功能,包括摘要、推断、转换和扩展。你还学会了如何构建自定义聊天机器人。在这门短期课程中,你学到了很多,希望你喜欢这些学习材料。
+我们还介绍了许多大型语言模型的功能,包括摘要、推断、转换和扩展。您还学会了如何构建自定义聊天机器人。在这门短期课程中,您学到了很多,希望您喜欢这些学习材料。
-我们希望你能想出一些应用程序的想法,并尝试自己构建它们。请尝试一下并让我们知道你的想法。你可以从一个非常小的项目开始,也许它具有一定的实用价值,也可能完全没有实用价值,只是一些有趣好玩儿的东西。请利用你第一个项目的学习经验来构建更好的第二个项目,甚至更好的第三个项目等。或者,如果你已经有一个更大的项目想法,那就去做吧。
+我们希望您能想出一些应用程序的想法,并尝试自己构建它们。请尝试一下并让我们知道您的想法。您可以从一个非常小的项目开始,也许它具有一定的实用价值,也可能完全没有实用价值,只是一些有趣好玩儿的东西。请利用您第一个项目的学习经验来构建更好的第二个项目,甚至更好的第三个项目等。或者,如果您已经有一个更大的项目想法,那就去做吧。
-大型语言模型非常强大,作为提醒,我们希望大家负责任地使用它们,请仅构建对他人有积极影响的东西。在这个时代,构建人工智能系统的人可以对他人产生巨大的影响。因此必须负责任地使用这些工具。
+大型语言模型非常强大,作为提醒,我们希望大家**负责任地**使用它们,请仅构建对他人有**积极影响**的东西。在这个时代,构建人工智能系统的人可以对他人产生巨大的影响。因此必须负责任地使用这些工具。
-现在,基于大型语言模型构建应用程序是一个非常令人兴奋和不断发展的领域。现在你已经完成了这门课程,我们认为你现在拥有了丰富的知识,可以帮助你构建其他人今天不知道如何构建的东西。因此,我希望你也能帮助我们传播并鼓励其他人也参加这门课程。
+现在,基于大型语言模型构建应用程序是一个非常令人兴奋和不断发展的领域。现在您已经完成了这门课程,我们认为您现在拥有了丰富的知识,可以帮助您构建其他人今天不知道如何构建的东西。因此,我希望您也能帮助我们传播并鼓励其他人也参加这门课程。
-最后,希望你在完成这门课程时感到愉快,感谢你完成了这门课程。我们期待听到你构建的惊人之作。
+最后,希望您在完成这门课程时感到愉快,感谢您完成了这门课程。我们期待得知您构建的惊人之作。
diff --git a/content/Prompt Engineering/附1-使用ChatGLM进行学习.ipynb b/content/Prompt Engineering/附1-使用ChatGLM进行学习.ipynb
index 14faaf4..9db90e4 100644
--- a/content/Prompt Engineering/附1-使用ChatGLM进行学习.ipynb
+++ b/content/Prompt Engineering/附1-使用ChatGLM进行学习.ipynb
@@ -7,11 +7,26 @@
"tags": []
},
"source": [
- "# ChatGPT与ChatGLM对比\n",
+ "# 附1 ChatGPT与ChatGLM对比\n",
"\n",
- "国产大模型有很多,比如文心一言、通义千问、星火、MOSS和ChatGLM等等,但现在明确可以部署在本地并且开放api的只有MOOS和ChatGLM。MOOS由于需要的GPU显存过大(不量化的情况下需要80GB,多轮对话还是会爆显存),但ChatGLM可以在笔记本电脑部署(int4版本只需要6GB显存即可)。所以本文采用ChatGLM与ChatGPT做对比,看看国产模型的优点和缺点。\n",
+ "国产大模型有很多,比如文心一言、通义千问、星火、 MOSS 和 ChatGLM 等等,但现在明确可以部署在本地并且开放 api 的只有 MOSS 和 ChatGLM 。MOSS 由于需要的GPU显存过大(不量化的情况下需要 ```80GB``` ,多轮对话还是会爆显存),但 ChatGLM 可以在笔记本电脑部署( ```int4``` 版本只需要 ```6GB``` 显存即可)。所以本文采用 ChatGLM 与 ChatGPT 做对比,看看国产模型的优点和缺点。\n",
"\n",
- "本文会选取本教程的各个方面进行对比,最后会总结ChatGPT与ChatGLM各自的优缺点。另外本文也适用于没有 OpenAI api key的读者,部署好chatglm-6B之后,使用后续介绍的函数也可以学完整个课程。"
+ "本文会选取本教程的各个方面进行对比,最后会总结 ChatGPT 与ChatGLM各自的优缺点。另外本文也适用于没有 OpenAI api key 的读者,部署好 ``` ChatGLM-6B``` 之后,使用后续介绍的函数也可以学完整个课程。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f5debf6b",
+ "metadata": {},
+ "source": [
+ ""
]
},
{
@@ -19,7 +34,15 @@
"id": "9be808ea-5284-4399-b832-5205c2745d13",
"metadata": {},
"source": [
- "## ChatGLM环境配置"
+ "## 一、环境配置"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1553056f",
+ "metadata": {},
+ "source": [
+ "### 1.1 ChatGLM环境配置"
]
},
{
@@ -29,7 +52,7 @@
"source": [
" ChatGLM环境配置可以参考DataWhale的这篇文章:[ChatGLM-6B 本地部署指南!](https://mp.weixin.qq.com/s/545Z4DTB78q_sLqBq6dC1A)\n",
"\n",
- " 部署好了之后,运行项目中的`api.py`文件即可。下面是使用ChatGLM的api封装的类似chatgpt一样的`get_completion`函数,只需要传进去prompt参数即可。"
+ " 部署好了之后,运行项目中的`api.py`文件即可。下面是使用ChatGLM的api封装的类似 ChatGPT 一样的`get_completion`函数,只需要传进去prompt参数即可。"
]
},
{
@@ -48,7 +71,7 @@
"id": "0fe69c47-ccc4-47db-a0f5-21e273b35fcb",
"metadata": {},
"source": [
- "如果你没有openai的key的话,部署好chatglm-6B之后,使用此函数也可以学完整个课程,加油~"
+ "如果你没有 OpenAI 的 key 的话,部署好 ChatGLM -6B 之后,使用此函数也可以学完整个课程,加油~"
]
},
{
@@ -110,7 +133,7 @@
"id": "e4c608de-2293-48df-bb0e-491686e427af",
"metadata": {},
"source": [
- "## ChatGPT环境配置"
+ "### 1.2 ChatGPT环境配置"
]
},
{
@@ -168,6 +191,14 @@
"get_completion_gpt('你好')"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "61f99c24",
+ "metadata": {},
+ "source": [
+ "## 二、文本理解"
+ ]
+ },
{
"cell_type": "markdown",
"id": "c807a1f5-bdf2-46ab-a77f-59985374e647",
@@ -175,7 +206,7 @@
"tags": []
},
"source": [
- "## 文本理解"
+ "### 2.1 文本总结与条件检测"
]
},
{
@@ -183,7 +214,7 @@
"id": "b1925a9e-54d9-4f75-a625-a1698b95e268",
"metadata": {},
"source": [
- "有步骤的文本"
+ "#### 2.1.1 有步骤的文本(满足输入条件)"
]
},
{
@@ -277,7 +308,7 @@
"id": "4b43edb5-37b5-4d43-9e16-d2a9b558ef73",
"metadata": {},
"source": [
- "**注**:这里可以看出,提供的文本是有步骤的文本。chatglm给出了步骤,但在最后说了`未提供步骤`。但chatgpt给出步骤,而且步骤要比chatglm的完整,而且回答正确。"
+ "**注**:这里可以看出,提供的文本是有步骤的文本。 ChatGLM 给出了步骤,但在最后说了`未提供步骤`。但 ChatGPT 给出步骤,而且步骤要比 ChatGLM 的完整,而且回答正确。"
]
},
{
@@ -285,7 +316,7 @@
"id": "37727f9a",
"metadata": {},
"source": [
- "无步骤文本"
+ "#### 2.1.2 无步骤的文本(不满足输入条件)"
]
},
{
@@ -367,7 +398,7 @@
"id": "ca4a5d02-0284-48fb-a22e-19b9d343ef65",
"metadata": {},
"source": [
- "**注:** 提供的是一个无步骤文本,但chatglm回答了一个步骤,在最后说了无步骤,这跟上面的有步骤文本回答几乎一样。chatgpt则是直接给出`未提供步骤`的回答。"
+ "**注:** 提供的是一个无步骤文本,但 ChatGLM 回答了一个步骤,在最后说了无步骤,这跟上面的有步骤文本回答几乎一样。 ChatCPT 则是直接给出`未提供步骤`的回答。"
]
},
{
@@ -375,7 +406,7 @@
"id": "198f0fb0",
"metadata": {},
"source": [
- "提供少量示例的文本"
+ "### 2.2 提供少量示例的文本续写(Few-shot)"
]
},
{
@@ -451,7 +482,7 @@
"id": "524d968f-41da-4f68-beef-a50800944254",
"metadata": {},
"source": [
- "**注:** 让你模仿,没让你超越啊!可以看出chatglm的回答与提供的少量示例文本几乎毫无关系,而chatgpt则是按照提供的示例模型续写。chatgpt薄纱chatglm。"
+ "**注:** 让你模仿,没让你超越啊!可以看出 ChatGLM 的回答与提供的少量示例文本几乎毫无关系,而 ChatGPT 则是按照提供的示例模型续写。 ChatGPT 薄纱 ChatGLM 。"
]
},
{
@@ -459,7 +490,7 @@
"id": "6bdbe63f",
"metadata": {},
"source": [
- "关注点侧重"
+ "### 2.3 关注点侧重"
]
},
{
@@ -528,7 +559,7 @@
"id": "abe00c2a-f8e6-4531-8077-33b50de7dba7",
"metadata": {},
"source": [
- "**注:** 让它侧重运输,chatglm甚至把运输的内容放在了回答的最后,chatgpt倒是把运输的部分放到了最前,表示侧重。"
+ "**注:** 让它侧重运输, ChatGLM 甚至把运输的内容放在了回答的最后, ChatGPT 倒是把运输的部分放到了最前,表示侧重。"
]
},
{
@@ -536,7 +567,7 @@
"id": "6b64ec6e",
"metadata": {},
"source": [
- "关键信息提取"
+ "### 2.4 关键信息提取"
]
},
{
@@ -598,7 +629,7 @@
"id": "4cc52af4-bf0e-4592-9292-ed238233a195",
"metadata": {},
"source": [
- "**注:** 不错,不错,chatglm和chatgpt都把运输信息提取出来了,chatglm甚至还多说了点。"
+ "**注:** 不错,不错, ChatGLM 和 ChatGPT 都把运输信息提取出来了, ChatGLM 甚至还多说了点。"
]
},
{
@@ -606,13 +637,13 @@
"id": "e07bb807-0a6e-43e6-b8a8-a597c42a6753",
"metadata": {},
"source": [
- "### 总结\n",
+ "### 2.5 总结\n",
"\n",
- "- 文本理解方面,chatglm与chatgpt的差距有点大。首先是步骤文本,无论提供的文本是否有步骤,chatglm都给出了步骤。而chatgpt则是有步骤给步骤,没步骤就不给。\n",
+ "- 文本理解方面, ChatGLM 与 ChatGPT 的差距有点大。首先是步骤文本,无论提供的文本是否有步骤, ChatGLM 都给出了步骤。而 ChatGPT 则是有步骤给步骤,没步骤就不给。\n",
"\n",
- "- 示例文本续写方面,chatglm本着模仿就要超越的原则,直接舍弃提供的少量示例,放飞自我。chatgpt则是按照提供的少量示例给出了答案。\n",
+ "- 示例文本续写方面, ChatGLM 本着模仿就要超越的原则,直接舍弃提供的少量示例,放飞自我。 ChatGPT 则是按照提供的少量示例给出了答案。\n",
"\n",
- "- 关键信息提取,chatglm表现差强人意,不太行。chatgpt倒是符合我的要求。"
+ "- 关键信息提取, ChatGLM 表现差强人意,不太行。 ChatGPT 倒是符合我的要求。"
]
},
{
@@ -620,7 +651,15 @@
"id": "8852532a-d1fb-44eb-87d5-8f95aa3e1606",
"metadata": {},
"source": [
- "## 结构化输出"
+ "## 三、结构化输出"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8a9370dc",
+ "metadata": {},
+ "source": [
+ "### 3.1 示例1"
]
},
{
@@ -711,7 +750,7 @@
"id": "c3b6f8c4-e649-4dd5-9b1c-46d724f92f7b",
"metadata": {},
"source": [
- "**注:** 可以看出,chatglm完全忽略了prompt中的`输出json对象`, 而且这个输出的摘要像是重新说了一遍,翻译也有些中文没有完全翻译。chatgpt的回答是符合要求的。"
+ "**注:** 可以看出, ChatGLM 完全忽略了 Prompt 中的`输出json对象`, 而且这个输出的摘要像是重新说了一遍,翻译也有些中文没有完全翻译。 ChatGPT 的回答是符合要求的。"
]
},
{
@@ -719,7 +758,7 @@
"id": "edd7c59f",
"metadata": {},
"source": [
- "从客户的评论中提取结构化信息"
+ "### 3.2 从客户的评论中提取结构化信息"
]
},
{
@@ -797,7 +836,7 @@
"id": "c9bd113e-2ffb-4828-a03a-a7d1c78b82d8",
"metadata": {},
"source": [
- "**注:** chatglm提取信息成功!口头表扬一次,但是并没有按照json对象输出,口头批评一次。chatgpt做的很好,表扬一次。"
+ "**注:** ChatGLM 提取信息成功!口头表扬一次,但是并没有按照json对象输出,口头批评一次。 ChatGPT 做的很好,表扬一次。"
]
},
{
@@ -805,7 +844,7 @@
"id": "10edd035",
"metadata": {},
"source": [
- "一次提取多条信息"
+ "### 3.3 一次提取多条信息"
]
},
{
@@ -883,7 +922,7 @@
"id": "aff470ae-7110-4e97-8e8b-45835af17df4",
"metadata": {},
"source": [
- "**注:** chatglm提取信息确实是提取的没问题,但是吧,还是没有转化为json对象输出。并且`Anger`没有给出布尔值,扣分项。"
+ "**注:** ChatGLM 提取信息确实是提取的没问题,但是吧,还是没有转化为json对象输出。并且`Anger`没有给出布尔值,扣分项。"
]
},
{
@@ -891,9 +930,9 @@
"id": "163f5442-9b64-4e0a-a370-b34f51067c3a",
"metadata": {},
"source": [
- "### 总结\n",
+ "### 3.4 总结\n",
"\n",
- "提取信息+结构化输出,chatglm基本只能做到提取信息,并没有实现输出json对象。能力有待加强,不知道chatglm-130B的版本如何?希望能更好些,加油~"
+ "提取信息+结构化输出, ChatGLM 基本只能做到提取信息,并没有实现输出json对象。能力有待加强,不知道 ChatGLM -130B的版本如何?希望能更好些,加油~"
]
},
{
@@ -901,7 +940,7 @@
"id": "d0085689-c1f1-4cfa-ae1c-714731c02a3a",
"metadata": {},
"source": [
- "## 翻译"
+ "## 四、翻译与转换"
]
},
{
@@ -909,7 +948,7 @@
"id": "ff6b817b",
"metadata": {},
"source": [
- "多语种翻译"
+ "### 4.1 多语种翻译"
]
},
{
@@ -976,7 +1015,7 @@
"id": "6422cb54-6153-4bf5-bdbe-c87d0780cfb6",
"metadata": {},
"source": [
- "**注:** 本人知识浅薄,法语和西班牙语翻译是用有道翻译检验的。chatglm和chatgpt的翻译都正确。大胜利!"
+ "**注:** 本人知识浅薄,法语和西班牙语翻译是用有道翻译检验的。 ChatGLM 和 ChatGPT 的翻译都正确。大胜利!"
]
},
{
@@ -984,7 +1023,7 @@
"id": "5aeb18fc",
"metadata": {},
"source": [
- "翻译+正式语气"
+ "### 4.2 翻译+正式语气"
]
},
{
@@ -1052,7 +1091,7 @@
"id": "dc886170-3b7d-484a-b79c-e7cad453109d",
"metadata": {},
"source": [
- "**注:** 两种语气,chatglm和chatgpt都回答的不错,都加分。"
+ "**注:** 两种语气, ChatGLM 和 ChatGPT 都回答的不错,都加分。"
]
},
{
@@ -1060,9 +1099,9 @@
"id": "a07fd232-34fa-4c04-80db-ac6698740f20",
"metadata": {},
"source": [
- "### 总结\n",
+ "### 4.3 总结\n",
"\n",
- "在翻译这块,chatglm做的和chatgpt相差无几,甚至可以说有些超越。换个角度想想,本地部署一个chatglm-int4专门用来翻译也不错啊,起码本地部署的api不收费!"
+ "在翻译这块, ChatGLM 做的和 ChatGPT 相差无几,甚至可以说有些超越。换个角度想想,本地部署一个 ChatGLM -int4专门用来翻译也不错啊,起码本地部署的api不收费!"
]
},
{
@@ -1070,7 +1109,7 @@
"id": "5d5a0225",
"metadata": {},
"source": [
- "## 逻辑推理"
+ "## 五、逻辑推理"
]
},
{
@@ -1182,7 +1221,7 @@
"id": "2a313cd9-647e-4639-aa06-e28dd2df7827",
"metadata": {},
"source": [
- "**注:** 实际上学生的解决方案是不正确的,维护费用每平方英尺是10美元,在学生的解答中错误的将其写成了100美元,chatglm发现这个错误,但它没有指出学生解答中的错误。相反chatgpt发现了错误,并给出了正确解法。"
+ "**注:** 实际上学生的解决方案是不正确的,维护费用每平方英尺是10美元,在学生的解答中错误的将其写成了100美元, ChatGLM 发现这个错误,但它没有指出学生解答中的错误。相反 ChatGPT 发现了错误,并给出了正确解法。"
]
}
],
diff --git a/figures/Chatbot-pizza-cn.png b/figures/Chatbot-pizza-cn.png
new file mode 100644
index 0000000..54807eb
Binary files /dev/null and b/figures/Chatbot-pizza-cn.png differ