Merge branch 'datawhalechina:PDF' into PDF
This commit is contained in:
@ -0,0 +1,21 @@
|
||||
# 第一章 简介
|
||||
|
||||
**作者 吴恩达教授**
|
||||
|
||||
欢迎来到本课程,我们将为开发人员介绍 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 能够让开发人员非常快速地构建应用程序。
|
||||
|
||||
在本课程中,我们将与您分享一些技巧,来挖掘 LLM 的潜力,也会提供应用上的最佳实践。过程中会涉及大量材料。首先,你会学习到用于软件开发的 Prompt 最佳实践,随后会涉及到几个常用使用例,包括概括、推断、转换与扩展,最后会利用 LLM 构建 chatbot(聊天机器人)。希望这能激发你的想象力,去开拓新应用。
|
||||
|
||||
随着 LLM 的发展,其大致可以分为两种类型,后续称为基础 LLM 和指令微调(Instruction Tuned)LLM。基础LLM是基于文本训练数据,训练出预测下一个单词能力的模型。其通常通过在互联网和其他来源的大量数据上训练,来确定紧接着出现的最可能的词。例如,如果你以“从前,有一只独角兽”作为 Prompt ,基础 LLM 可能会继续预测“她与独角兽朋友共同生活在一片神奇森林中”。但是,如果你以“法国的首都是什么”为 Prompt ,则基础 LLM 可能会根据互联网上的文章,将回答预测为“法国最大的城市是什么?法国的人口是多少?”,因为互联网上的文章很可能是有关法国国家的问答题目列表。
|
||||
|
||||
而对于指令微调的 LLM ,相关研究和实践正甚嚣尘上,训练它们来遵循指示。因此,如果你问它,“法国的首都是什么?”,它有极大可能输出“法国的首都是巴黎”。指令微调的LLM的训练通常是基于预训练好的LLM的,即模型已经在大量文本数据上进行了训练。然后对其进行进一步训练与微调(finetune),使用的数据包括输入和理想输出(输入是指令、输出是遵循这些指令的良好回答)。然后通常使用一种称为 RLHF(reinforcement learning from human feedback,人类反馈强化学习)的技术进行进一步改进,使系统更能够有帮助地遵循指令。
|
||||
|
||||
因为指令微调的 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 时,您可以类比为向另一个人提供指令(假设他很聪明但不知道您任务的具体细节)。因此,当 LLM 无法正常工作时,有时是因为指令不够清晰。例如,如果您想问“请为我写一些关于阿兰·图灵( Alan Turing )的东西”,在此基础上清楚表明您希望文本专注于他的科学工作、个人生活、历史角色或其他方面可能会更有帮助。另外您还可以指定回答的语调, 来更加满足您的需求,可选项包括*专业记者写作*,或者*向朋友写的随笔*等。
|
||||
|
||||
如果你将 LLM 视为一名新毕业的大学生,要求他完成这个任务,你甚至可以提前指定他们应该阅读哪些文本片段来写关于 Alan Turing 的文本,这样能够帮助这位新毕业的大学生更好地完成这项任务。下一章你会看到提示词创建的两个原则,一是**清晰明确**,二是**给LLM时间去思考**。
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,916 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 第三章 迭代优化\n",
|
||||
"\n",
|
||||
"当使用 LLM 构建应用程序时,实践层面上很难*第一次尝试*就成功获得适合最终应用的 Prompt。但这并不重要,只要您有一个好的迭代过程来不断改进您的 Prompt,那么您就能够得到一个适合任务的 Prompt。虽然相比训练机器学习模型,在 Prompt 方面一次成功的几率可能会高一些,但正如上所说, Prompt 是否一次完善并不重要。最重要的是**层层迭代**为您的应用程序找到有效 Prompt 的过程。\n",
|
||||
"\n",
|
||||
"因此在本章中,我们将以产品说明书中生成营销文案为例,来展示一些流程框架,并提示您思考如何层层迭代地分析和完善您的 Prompt。\n",
|
||||
"\n",
|
||||
"在吴恩达(Andrew Ng,原教程作者)的机器学习课程中展示过一张图表,说明了机器学习开发的流程。通常是先有一个想法,然后再用以下流程实现:编写代码,获取数据,训练模型,获得实验结果。然后您可以查看结果,分析误差与错误,找出适用领域,甚至可以更改您对具体问题的具体思路或解决方法。此后再次更改实现,并运行另一个实验等,反复迭代,最终获得有效的机器学习模型。在编写基于 LLM 的应用程序的 Prompt 时,流程可能非常相似。您产生了关于要完成的任务的想法后,可以尝试编写第一个 Prompt ,注意要满足上一章说过的两个原则:**清晰明确,并且给系统足够的时间思考**。然后您可以运行并查看结果。如果第一次效果不好,那么迭代的过程就是找出为什么指令不够清晰或为什么没有给算法足够的时间思考,以便改进想法、改进 Prompt 等等,循环多次,直到找到适合您的应用程序的 Prompt。\n",
|
||||
"\n",
|
||||
"很难有适用于世间万物的所谓“最佳 Prompt ”,更好的方法是找到有效的迭代过程,以便您可以快速地找到一个适合您的应用程序的 Prompt 。\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 一、从产品说明书生成营销产品描述"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"给定一份椅子的资料页。描述说它属于*中世纪灵感*系列,产自意大利,并介绍了材料、构造、尺寸、可选配件等参数。假设您想要使用这份说明书帮助营销团队为电商平台撰写营销描述稿:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 示例:产品说明书\n",
|
||||
"fact_sheet_chair = \"\"\"\n",
|
||||
"概述\n",
|
||||
"\n",
|
||||
" 美丽的中世纪风格办公家具系列的一部分,包括文件柜、办公桌、书柜、会议桌等。\n",
|
||||
" 多种外壳颜色和底座涂层可选。\n",
|
||||
" 可选塑料前后靠背装饰(SWC-100)或10种面料和6种皮革的全面装饰(SWC-110)。\n",
|
||||
" 底座涂层选项为:不锈钢、哑光黑色、光泽白色或铬。\n",
|
||||
" 椅子可带或不带扶手。\n",
|
||||
" 适用于家庭或商业场所。\n",
|
||||
" 符合合同使用资格。\n",
|
||||
"\n",
|
||||
"结构\n",
|
||||
"\n",
|
||||
" 五个轮子的塑料涂层铝底座。\n",
|
||||
" 气动椅子调节,方便升降。\n",
|
||||
"\n",
|
||||
"尺寸\n",
|
||||
"\n",
|
||||
" 宽度53厘米|20.87英寸\n",
|
||||
" 深度51厘米|20.08英寸\n",
|
||||
" 高度80厘米|31.50英寸\n",
|
||||
" 座椅高度44厘米|17.32英寸\n",
|
||||
" 座椅深度41厘米|16.14英寸\n",
|
||||
"\n",
|
||||
"选项\n",
|
||||
"\n",
|
||||
" 软地板或硬地板滚轮选项。\n",
|
||||
" 两种座椅泡沫密度可选:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺)。\n",
|
||||
" 无扶手或8个位置PU扶手。\n",
|
||||
"\n",
|
||||
"材料\n",
|
||||
"外壳底座滑动件\n",
|
||||
"\n",
|
||||
" 改性尼龙PA6/PA66涂层的铸铝。\n",
|
||||
" 外壳厚度:10毫米。\n",
|
||||
" 座椅\n",
|
||||
" HD36泡沫\n",
|
||||
"\n",
|
||||
"原产国\n",
|
||||
"\n",
|
||||
" 意大利\n",
|
||||
"\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 1.1 初始提示"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"产品描述:\n",
|
||||
"\n",
|
||||
"我们自豪地推出美丽的中世纪风格办公家具系列,其中包括文件柜、办公桌、书柜、会议桌等。我们的产品采用多种外壳颜色和底座涂层,以满足您的个性化需求。您可以选择塑料前后靠背装饰(SWC-100)或10种面料和6种皮革的全面装饰(SWC-110),以使您的办公室更加舒适和时尚。\n",
|
||||
"\n",
|
||||
"我们的底座涂层选项包括不锈钢、哑光黑色、光泽白色或铬,以满足您的不同需求。椅子可带或不带扶手,适用于家庭或商业场所。我们的产品符合合同使用资格,为您提供更加可靠的保障。\n",
|
||||
"\n",
|
||||
"我们的产品采用五个轮子的塑料涂层铝底座,气动椅子调节,方便升降。尺寸为宽度53厘米|20.87英寸,深度51厘米|20.08英寸,高度80厘米|31.50英寸,座椅高度44厘米|17.32英寸,座椅深度41厘米|16.14英寸,为您提供舒适的使用体验。\n",
|
||||
"\n",
|
||||
"我们的产品还提供软地板或硬地板滚轮选项,两种座椅泡沫密度可选:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺),以及无扶手或8个位置PU扶手,以满足您的不同需求。\n",
|
||||
"\n",
|
||||
"我们的产品采用改性尼龙PA6/PA66涂层的铸铝外壳底座滑动件,外壳厚度为10毫米,座椅采用HD36泡沫,为您提供更加舒适的使用体验。我们的产品原产国为意大利,为您提供更加优质的品质保证。\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from tool import get_completion\n",
|
||||
"\n",
|
||||
"# Prompt :基于说明书创建营销描述\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"您的任务是帮助营销团队基于技术说明书创建一个产品的营销描述。\n",
|
||||
"\n",
|
||||
"根据```标记的技术说明书中提供的信息,编写一个产品描述。\n",
|
||||
"\n",
|
||||
"技术说明: ```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 1.2 提示优化1: 解决生成文本太长\n",
|
||||
"\n",
|
||||
"它似乎很好地完成了要求,即从技术说明书开始编写产品描述,介绍了一个精致的中世纪风格办公椅。但是当我看到这个时,我会觉得这个太长了。\n",
|
||||
"\n",
|
||||
"所以在上述过程中,我产生想法后写了一个 Prompt ,并得到了结果,但是我对它不是很满意,因为它太长了。所以我澄清我的 Prompt ,要求它限制生成文本长度,要求最多使用50个字。\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"提取回答并根据空格拆分,中文答案为97个字,较好地完成了设计要求。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"中世纪风格办公家具系列,包括文件柜、办公桌、书柜、会议桌等。多种颜色和涂层可选,可带或不带扶手。底座涂层选项为不锈钢、哑光黑色、光泽白色或铬。适用于家庭或商业场所,符合合同使用资格。意大利制造。\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 优化后的 Prompt,要求生成描述不多于 50 词\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。\n",
|
||||
"\n",
|
||||
"根据```标记的技术说明书中提供的信息,编写一个产品描述。\n",
|
||||
"\n",
|
||||
"使用最多50个词。\n",
|
||||
"\n",
|
||||
"技术规格:```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"97"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 由于中文需要分词,此处直接计算整体长度\n",
|
||||
"len(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"LLM在能堪堪胜任严格的字数限制,但实现得并不精确。此例中,英文输出要求控制在50个词,但有时会输出60或65个单词的内容,但这也还算合理。原因是 LLM 使用分词器(tokenizer)解释文本,但它们往往在计算字符方面表现一般般。有很多不同的方法来尝试控制您得到的输出的长度(如若干句话/词/个汉字/个字母 (characters) 等)。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 1.3 提示优化2: 处理抓错文本细节\n",
|
||||
"\n",
|
||||
"我们继续完善这段推广词,会发现的第二个问题是,这个网站并不是直接向消费者销售,它实际上面向的是家具零售商,他们会更关心椅子的技术细节和材料。在这种情况下,您可以继续修改这个 Prompt ,让它更精确地描述椅子的技术细节。\n",
|
||||
"\n",
|
||||
"解决方法:要求它专注于与目标受众相关的方面。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"这款中世纪风格办公家具系列包括文件柜、办公桌、书柜和会议桌等,适用于家庭或商业场所。可选多种外壳颜色和底座涂层,底座涂层选项为不锈钢、哑光黑色、光泽白色或铬。椅子可带或不带扶手,可选软地板或硬地板滚轮,两种座椅泡沫密度可选。外壳底座滑动件采用改性尼龙PA6/PA66涂层的铸铝,座椅采用HD36泡沫。原产国为意大利。\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 优化后的 Prompt,说明面向对象,应具有什么性质且侧重于什么方面\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。\n",
|
||||
"\n",
|
||||
"根据```标记的技术说明书中提供的信息,编写一个产品描述。\n",
|
||||
"\n",
|
||||
"该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。\n",
|
||||
"\n",
|
||||
"使用最多50个单词。\n",
|
||||
"\n",
|
||||
"技术规格: ```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"可见,通过修改 Prompt ,模型的关注点倾向了具体特征与技术细节。\n",
|
||||
"\n",
|
||||
"我可能进一步想要在描述的结尾展示出产品ID。因此,我可以进一步改进这个 Prompt ,要求在描述的结尾,展示出说明书中的7位产品ID。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"这款中世纪风格的办公家具系列包括文件柜、办公桌、书柜和会议桌等,适用于家庭或商业场所。可选多种外壳颜色和底座涂层,底座涂层选项为不锈钢、哑光黑色、光泽白色或铬。椅子可带或不带扶手,可选塑料前后靠背装饰或10种面料和6种皮革的全面装饰。座椅采用HD36泡沫,可选中等或高密度,座椅高度44厘米,深度41厘米。外壳底座滑动件采用改性尼龙PA6/PA66涂层的铸铝,外壳厚度为10毫米。原产国为意大利。产品ID:SWC-100/SWC-110。\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 更进一步\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。\n",
|
||||
"\n",
|
||||
"根据```标记的技术说明书中提供的信息,编写一个产品描述。\n",
|
||||
"\n",
|
||||
"该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。\n",
|
||||
"\n",
|
||||
"在描述末尾,包括技术规格中每个7个字符的产品ID。\n",
|
||||
"\n",
|
||||
"使用最多50个单词。\n",
|
||||
"\n",
|
||||
"技术规格: ```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"以上是许多开发人员通常会经历的 Prompt 开发的迭代过程简短示例。我的建议是,像上一章中所演示的那样,Prompt 应该保持清晰和明确,并在必要时给模型一些思考时间。在这些要求的基础上,常见流程是首先尝试编写一版 Prompt ,看看会发生什么,然后继续迭代完善 Prompt,以逐渐接近所需的结果。许多成功的 Prompt 都是通过这种迭代过程得出的。我将向您展示一个更复杂的 Prompt 示例,可能会让您对 ChatGPT 的能力有更深入的了解。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 1.4 提示优化3: 添加表格描述\n",
|
||||
"继续添加指引,要求提取产品尺寸信息并组织成表格,并指定表格的列、表名和格式;再将所有内容格式化为可以在网页使用的 HTML。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"<div>\n",
|
||||
"<h2>中世纪风格办公家具系列椅子</h2>\n",
|
||||
"<p>这款椅子是中世纪风格办公家具系列的一部分,适用于家庭或商业场所。它有多种外壳颜色和底座涂层可选,包括不锈钢、哑光黑色、光泽白色或铬。您可以选择带或不带扶手的椅子,以及软地板或硬地板滚轮选项。此外,您可以选择两种座椅泡沫密度:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺)。</p>\n",
|
||||
"<p>椅子的外壳底座滑动件是改性尼龙PA6/PA66涂层的铸铝,外壳厚度为10毫米。座椅采用HD36泡沫,底座是五个轮子的塑料涂层铝底座,可以进行气动椅子调节,方便升降。此外,椅子符合合同使用资格,是您理想的选择。</p>\n",
|
||||
"<p>产品ID:SWC-100</p>\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"<table>\n",
|
||||
" <caption>产品尺寸</caption>\n",
|
||||
" <tr>\n",
|
||||
" <th>宽度</th>\n",
|
||||
" <td>20.87英寸</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>深度</th>\n",
|
||||
" <td>20.08英寸</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>高度</th>\n",
|
||||
" <td>31.50英寸</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>座椅高度</th>\n",
|
||||
" <td>17.32英寸</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>座椅深度</th>\n",
|
||||
" <td>16.14英寸</td>\n",
|
||||
" </tr>\n",
|
||||
"</table>\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 要求它抽取信息并组织成表格,并指定表格的列、表名和格式\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。\n",
|
||||
"\n",
|
||||
"根据```标记的技术说明书中提供的信息,编写一个产品描述。\n",
|
||||
"\n",
|
||||
"该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。\n",
|
||||
"\n",
|
||||
"在描述末尾,包括技术规格中每个7个字符的产品ID。\n",
|
||||
"\n",
|
||||
"在描述之后,包括一个表格,提供产品的尺寸。表格应该有两列。第一列包括尺寸的名称。第二列只包括英寸的测量值。\n",
|
||||
"\n",
|
||||
"给表格命名为“产品尺寸”。\n",
|
||||
"\n",
|
||||
"将所有内容格式化为可用于网站的HTML格式。将描述放在<div>元素中。\n",
|
||||
"\n",
|
||||
"技术规格:```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<h2>中世纪风格办公家具系列椅子</h2>\n",
|
||||
"<p>这款椅子是中世纪风格办公家具系列的一部分,适用于家庭或商业场所。它有多种外壳颜色和底座涂层可选,包括不锈钢、哑光黑色、光泽白色或铬。您可以选择带或不带扶手的椅子,以及软地板或硬地板滚轮选项。此外,您可以选择两种座椅泡沫密度:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺)。</p>\n",
|
||||
"<p>椅子的外壳底座滑动件是改性尼龙PA6/PA66涂层的铸铝,外壳厚度为10毫米。座椅采用HD36泡沫,底座是五个轮子的塑料涂层铝底座,可以进行气动椅子调节,方便升降。此外,椅子符合合同使用资格,是您理想的选择。</p>\n",
|
||||
"<p>产品ID:SWC-100</p>\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"<table>\n",
|
||||
" <caption>产品尺寸</caption>\n",
|
||||
" <tr>\n",
|
||||
" <th>宽度</th>\n",
|
||||
" <td>20.87英寸</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>深度</th>\n",
|
||||
" <td>20.08英寸</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>高度</th>\n",
|
||||
" <td>31.50英寸</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>座椅高度</th>\n",
|
||||
" <td>17.32英寸</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>座椅深度</th>\n",
|
||||
" <td>16.14英寸</td>\n",
|
||||
" </tr>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 表格是以 HTML 格式呈现的,加载出来\n",
|
||||
"from IPython.display import display, HTML\n",
|
||||
"\n",
|
||||
"display(HTML(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 二、总结"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"本章的主要内容是 LLM 在开发应用程序中的迭代式 Prompt 开发过程。开发者需要先尝试编写 Prompt ,然后通过迭代逐步完善它,直至得到需要的结果。作为一名高效的提示词工程师(Prompt Engineer),关键在于掌握有效的开发Prompt的过程,而不是去寻求得到“完美的”Prompt。对于一些更复杂的应用程序,可以对多个样本(如数百张说明书)进行 Prompt 的迭代开发,并在样本集上进行评估。\n",
|
||||
"\n",
|
||||
"最后,在更成熟的应用程序中,可以观察多个Prompt在多个样本集上的表现,测试平均或最差性能。但通常,**仅当**应用较成型之后,才推荐您通过这种评估方式,来精益求精。\n",
|
||||
"\n",
|
||||
"请使用 Jupyter Notebook,动手实践本节给出的示例,并尝试不同的变化,查看结果。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 三、英文版"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**产品说明书**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"fact_sheet_chair = \"\"\"\n",
|
||||
"OVERVIEW\n",
|
||||
"- Part of a beautiful family of mid-century inspired office furniture, \n",
|
||||
"including filing cabinets, desks, bookcases, meeting tables, and more.\n",
|
||||
"- Several options of shell color and base finishes.\n",
|
||||
"- Available with plastic back and front upholstery (SWC-100) \n",
|
||||
"or full upholstery (SWC-110) in 10 fabric and 6 leather options.\n",
|
||||
"- Base finish options are: stainless steel, matte black, \n",
|
||||
"gloss white, or chrome.\n",
|
||||
"- Chair is available with or without armrests.\n",
|
||||
"- Suitable for home or business settings.\n",
|
||||
"- Qualified for contract use.\n",
|
||||
"\n",
|
||||
"CONSTRUCTION\n",
|
||||
"- 5-wheel plastic coated aluminum base.\n",
|
||||
"- Pneumatic chair adjust for easy raise/lower action.\n",
|
||||
"\n",
|
||||
"DIMENSIONS\n",
|
||||
"- WIDTH 53 CM | 20.87”\n",
|
||||
"- DEPTH 51 CM | 20.08”\n",
|
||||
"- HEIGHT 80 CM | 31.50”\n",
|
||||
"- SEAT HEIGHT 44 CM | 17.32”\n",
|
||||
"- SEAT DEPTH 41 CM | 16.14”\n",
|
||||
"\n",
|
||||
"OPTIONS\n",
|
||||
"- Soft or hard-floor caster options.\n",
|
||||
"- Two choices of seat foam densities: \n",
|
||||
"medium (1.8 lb/ft3) or high (2.8 lb/ft3)\n",
|
||||
"- Armless or 8 position PU armrests \n",
|
||||
"\n",
|
||||
"MATERIALS\n",
|
||||
"SHELL BASE GLIDER\n",
|
||||
"- Cast Aluminum with modified nylon PA6/PA66 coating.\n",
|
||||
"- Shell thickness: 10 mm.\n",
|
||||
"SEAT\n",
|
||||
"- HD36 foam\n",
|
||||
"\n",
|
||||
"COUNTRY OF ORIGIN\n",
|
||||
"- Italy\n",
|
||||
"\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**1.1 英文初始提示**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Introducing our stunning mid-century inspired office chair, the perfect addition to any home or business setting. This chair is part of a beautiful family of office furniture, including filing cabinets, desks, bookcases, meeting tables, and more, all designed with a timeless mid-century aesthetic.\n",
|
||||
"\n",
|
||||
"One of the standout features of this chair is the variety of customization options available. You can choose from several shell colors and base finishes to perfectly match your existing decor. The chair is available with either plastic back and front upholstery or full upholstery in a range of 10 fabric and 6 leather options, allowing you to create a look that is uniquely yours.\n",
|
||||
"\n",
|
||||
"The chair is also available with or without armrests, giving you the flexibility to choose the option that best suits your needs. The base finish options include stainless steel, matte black, gloss white, or chrome, ensuring that you can find the perfect match for your space.\n",
|
||||
"\n",
|
||||
"In terms of construction, this chair is built to last. It features a 5-wheel plastic coated aluminum base, providing stability and mobility. The pneumatic chair adjust allows for easy raise and lower action, ensuring optimal comfort throughout the day.\n",
|
||||
"\n",
|
||||
"When it comes to dimensions, this chair is designed with both style and comfort in mind. With a width of 53 cm (20.87\"), depth of 51 cm (20.08\"), and height of 80 cm (31.50\"), it offers ample space without overwhelming your space. The seat height is 44 cm (17.32\") and the seat depth is 41 cm (16.14\"), providing a comfortable seating experience for extended periods.\n",
|
||||
"\n",
|
||||
"We understand that every space is unique, which is why we offer a range of options to further customize your chair. You can choose between soft or hard-floor caster options, ensuring that your chair glides smoothly on any surface. Additionally, you have the choice between two seat foam densities: medium (1.8 lb/ft3) or high (2.8 lb/ft3), allowing you to select the level of support that suits your preferences. The chair is also available with armless design or 8 position PU armrests, providing additional comfort and versatility.\n",
|
||||
"\n",
|
||||
"When it comes to materials, this chair is crafted with the utmost attention to quality. The shell base glider is made of cast aluminum with a modified nylon PA6/PA66 coating, ensuring durability and longevity. The shell thickness is 10 mm, providing a sturdy and reliable structure. The seat is made of HD36 foam, offering a comfortable and supportive seating experience.\n",
|
||||
"\n",
|
||||
"Finally, this chair is proudly made in Italy, known for its exceptional craftsmanship and attention to detail. With its timeless design and superior construction, this chair is not only a stylish addition to any space but also a reliable and functional piece of furniture.\n",
|
||||
"\n",
|
||||
"Upgrade your office or home with our mid-century inspired office chair and experience the perfect blend of style, comfort, and functionality.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Prompt :基于说明书生成营销描述\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"Your task is to help a marketing team create a \n",
|
||||
"description for a retail website of a product based \n",
|
||||
"on a technical fact sheet.\n",
|
||||
"\n",
|
||||
"Write a product description based on the information \n",
|
||||
"provided in the technical specifications delimited by \n",
|
||||
"triple backticks.\n",
|
||||
"\n",
|
||||
"Technical specifications: ```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**1.2限制生成长度**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Introducing our mid-century inspired office chair, part of a beautiful furniture collection. With various color and finish options, it can be customized to suit any space. Choose between plastic or full upholstery in a range of fabrics and leathers. The chair features a durable aluminum base and easy height adjustment. Suitable for both home and business use. Made in Italy.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 优化后的 Prompt,要求生成描述不多于 50 词\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"Your task is to help a marketing team create a \n",
|
||||
"description for a retail website of a product based \n",
|
||||
"on a technical fact sheet.\n",
|
||||
"\n",
|
||||
"Write a product description based on the information \n",
|
||||
"provided in the technical specifications delimited by \n",
|
||||
"triple backticks.\n",
|
||||
"\n",
|
||||
"Use at most 50 words.\n",
|
||||
"\n",
|
||||
"Technical specifications: ```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"60\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"lst = response.split()\n",
|
||||
"print(len(lst))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**1.3处理抓错文本细节**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Introducing our mid-century inspired office chair, part of a beautiful furniture collection. With various shell colors and base finishes, it offers versatility for any setting. Choose between plastic or full upholstery in a range of fabric and leather options. The chair features a durable aluminum base with 5-wheel design and pneumatic chair adjustment. Made in Italy.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 优化后的 Prompt,说明面向对象,应具有什么性质且侧重于什么方面\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"Your task is to help a marketing team create a \n",
|
||||
"description for a retail website of a product based \n",
|
||||
"on a technical fact sheet.\n",
|
||||
"\n",
|
||||
"Write a product description based on the information \n",
|
||||
"provided in the technical specifications delimited by \n",
|
||||
"triple backticks.\n",
|
||||
"\n",
|
||||
"The description is intended for furniture retailers, \n",
|
||||
"so should be technical in nature and focus on the \n",
|
||||
"materials the product is constructed from.\n",
|
||||
"\n",
|
||||
"Use at most 50 words.\n",
|
||||
"\n",
|
||||
"Technical specifications: ```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Introducing our mid-century inspired office chair, part of a beautiful family of furniture. This chair offers a range of options, including different shell colors and base finishes. Choose between plastic or full upholstery in various fabric and leather options. The chair is constructed with a 5-wheel plastic coated aluminum base and features a pneumatic chair adjust for easy raise/lower action. With its sleek design and multiple customization options, this chair is suitable for both home and business settings. Made in Italy.\n",
|
||||
"\n",
|
||||
"Product IDs: SWC-100, SWC-110\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 更进一步,要求在描述末尾包含 7个字符的产品ID\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"Your task is to help a marketing team create a \n",
|
||||
"description for a retail website of a product based \n",
|
||||
"on a technical fact sheet.\n",
|
||||
"\n",
|
||||
"Write a product description based on the information \n",
|
||||
"provided in the technical specifications delimited by \n",
|
||||
"triple backticks.\n",
|
||||
"\n",
|
||||
"The description is intended for furniture retailers, \n",
|
||||
"so should be technical in nature and focus on the \n",
|
||||
"materials the product is constructed from.\n",
|
||||
"\n",
|
||||
"At the end of the description, include every 7-character \n",
|
||||
"Product ID in the technical specification.\n",
|
||||
"\n",
|
||||
"Use at most 50 words.\n",
|
||||
"\n",
|
||||
"Technical specifications: ```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**1.4英文添加表格描述**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"<div>\n",
|
||||
" <h2>Product Description</h2>\n",
|
||||
" <p>\n",
|
||||
" Introducing our latest addition to our mid-century inspired office furniture collection, the SWC-100 Chair. This chair is part of a beautiful family of furniture that includes filing cabinets, desks, bookcases, meeting tables, and more. With its sleek design and customizable options, it is perfect for both home and business settings.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" The SWC-100 Chair is available in several options of shell color and base finishes, allowing you to choose the perfect combination to match your space. You can opt for plastic back and front upholstery or full upholstery in a variety of fabric and leather options. The base finish options include stainless steel, matte black, gloss white, or chrome. Additionally, you have the choice of having armrests or going armless.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" Constructed with durability and comfort in mind, the SWC-100 Chair features a 5-wheel plastic coated aluminum base for stability and mobility. The chair also has a pneumatic adjuster, allowing for easy raise and lower action to find the perfect height for your needs.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" The SWC-100 Chair is designed to provide maximum comfort and support. The seat is made with HD36 foam, ensuring a plush and comfortable seating experience. You also have the option to choose between soft or hard-floor casters, depending on your flooring needs. Additionally, you can select from two choices of seat foam densities: medium (1.8 lb/ft3) or high (2.8 lb/ft3). The chair is also available with 8 position PU armrests for added convenience.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" Made with high-quality materials, the SWC-100 Chair is built to last. The shell base glider is constructed with cast aluminum and modified nylon PA6/PA66 coating, providing durability and stability. The shell has a thickness of 10 mm, ensuring strength and longevity. The chair is proudly made in Italy, known for its craftsmanship and attention to detail.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" Whether you need a chair for your home office or a professional workspace, the SWC-100 Chair is the perfect choice. Its stylish design, customizable options, and high-quality construction make it a standout piece of furniture that will enhance any space.\n",
|
||||
" </p>\n",
|
||||
" <h2>Product Dimensions</h2>\n",
|
||||
" <table>\n",
|
||||
" <tr>\n",
|
||||
" <th>Dimension</th>\n",
|
||||
" <th>Measurement (inches)</th>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Width</td>\n",
|
||||
" <td>20.87\"</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Depth</td>\n",
|
||||
" <td>20.08\"</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Height</td>\n",
|
||||
" <td>31.50\"</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Seat Height</td>\n",
|
||||
" <td>17.32\"</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Seat Depth</td>\n",
|
||||
" <td>16.14\"</td>\n",
|
||||
" </tr>\n",
|
||||
" </table>\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"Product IDs: SWC-100, SWC-110\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
" <h2>Product Description</h2>\n",
|
||||
" <p>\n",
|
||||
" Introducing our latest addition to our mid-century inspired office furniture collection, the SWC-100 Chair. This chair is part of a beautiful family of furniture that includes filing cabinets, desks, bookcases, meeting tables, and more. With its sleek design and customizable options, it is perfect for both home and business settings.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" The SWC-100 Chair is available in several options of shell color and base finishes, allowing you to choose the perfect combination to match your space. You can opt for plastic back and front upholstery or full upholstery in a variety of fabric and leather options. The base finish options include stainless steel, matte black, gloss white, or chrome. Additionally, you have the choice of having armrests or going armless.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" Constructed with durability and comfort in mind, the SWC-100 Chair features a 5-wheel plastic coated aluminum base for stability and mobility. The chair also has a pneumatic adjuster, allowing for easy raise and lower action to find the perfect height for your needs.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" The SWC-100 Chair is designed to provide maximum comfort and support. The seat is made with HD36 foam, ensuring a plush and comfortable seating experience. You also have the option to choose between soft or hard-floor casters, depending on your flooring needs. Additionally, you can select from two choices of seat foam densities: medium (1.8 lb/ft3) or high (2.8 lb/ft3). The chair is also available with 8 position PU armrests for added convenience.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" Made with high-quality materials, the SWC-100 Chair is built to last. The shell base glider is constructed with cast aluminum and modified nylon PA6/PA66 coating, providing durability and stability. The shell has a thickness of 10 mm, ensuring strength and longevity. The chair is proudly made in Italy, known for its craftsmanship and attention to detail.\n",
|
||||
" </p>\n",
|
||||
" <p>\n",
|
||||
" Whether you need a chair for your home office or a professional workspace, the SWC-100 Chair is the perfect choice. Its stylish design, customizable options, and high-quality construction make it a standout piece of furniture that will enhance any space.\n",
|
||||
" </p>\n",
|
||||
" <h2>Product Dimensions</h2>\n",
|
||||
" <table>\n",
|
||||
" <tr>\n",
|
||||
" <th>Dimension</th>\n",
|
||||
" <th>Measurement (inches)</th>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Width</td>\n",
|
||||
" <td>20.87\"</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Depth</td>\n",
|
||||
" <td>20.08\"</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Height</td>\n",
|
||||
" <td>31.50\"</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Seat Height</td>\n",
|
||||
" <td>17.32\"</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <td>Seat Depth</td>\n",
|
||||
" <td>16.14\"</td>\n",
|
||||
" </tr>\n",
|
||||
" </table>\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"Product IDs: SWC-100, SWC-110"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 要求它抽取信息并组织成表格,并指定表格的列、表名和格式\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"Your task is to help a marketing team create a \n",
|
||||
"description for a retail website of a product based \n",
|
||||
"on a technical fact sheet.\n",
|
||||
"\n",
|
||||
"Write a product description based on the information \n",
|
||||
"provided in the technical specifications delimited by \n",
|
||||
"triple backticks.\n",
|
||||
"\n",
|
||||
"The description is intended for furniture retailers, \n",
|
||||
"so should be technical in nature and focus on the \n",
|
||||
"materials the product is constructed from.\n",
|
||||
"\n",
|
||||
"At the end of the description, include every 7-character \n",
|
||||
"Product ID in the technical specification.\n",
|
||||
"\n",
|
||||
"After the description, include a table that gives the \n",
|
||||
"product's dimensions. The table should have two columns.\n",
|
||||
"In the first column include the name of the dimension. \n",
|
||||
"In the second column include the measurements in inches only.\n",
|
||||
"\n",
|
||||
"Give the table the title 'Product Dimensions'.\n",
|
||||
"\n",
|
||||
"Format everything as HTML that can be used in a website. \n",
|
||||
"Place the description in a <div> element.\n",
|
||||
"\n",
|
||||
"Technical specifications: ```{fact_sheet_chair}```\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)\n",
|
||||
"\n",
|
||||
"# 表格是以 HTML 格式呈现的,加载出来\n",
|
||||
"from IPython.display import display, HTML\n",
|
||||
"\n",
|
||||
"display(HTML(response))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.11"
|
||||
},
|
||||
"latex_envs": {
|
||||
"LaTeX_envs_menu_present": true,
|
||||
"autoclose": false,
|
||||
"autocomplete": true,
|
||||
"bibliofile": "biblio.bib",
|
||||
"cite_by": "apalike",
|
||||
"current_citInitial": 1,
|
||||
"eqLabelWithNumbers": true,
|
||||
"eqNumInitial": 1,
|
||||
"hotkeys": {
|
||||
"equation": "Ctrl-E",
|
||||
"itemize": "Ctrl-I"
|
||||
},
|
||||
"labels_anchors": false,
|
||||
"latex_user_defs": false,
|
||||
"report_style_numbering": false,
|
||||
"user_envs_cfg": false
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": true,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,447 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 第七章 文本扩展"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"扩展是将短文本(例如一组说明或主题列表)输入到大型语言模型中,让模型生成更长的文本(例如基于某个主题的电子邮件或论文)。这种应用是一把双刃剑,好处例如将大型语言模型用作头脑风暴的伙伴;但也存在问题,例如某人可能会使用它来生成大量垃圾邮件。因此,当你使用大型语言模型的这些功能时,请仅以**负责任** (responsible) 和**有益于人们** (helps people) 的方式使用它们。\n",
|
||||
"\n",
|
||||
"在本章中,你将学会如何基于 OpenAI API 生成*针对每位客户评价优化*的客服电子邮件。我们还将利用模型的另一个输入参数称为温度,这种参数允许您在模型响应中变化探索的程度和多样性。\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 一、定制客户邮件"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"我们将根据客户评价和情感,针对性写自动回复邮件。因此,我们将给定客户评价和情感,使用 LLM 针对性生成响应,即根据客户评价和评论情感生成定制电子邮件。\n",
|
||||
"\n",
|
||||
"我们首先给出一个示例,包括一个评论及对应的情感。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 我们可以在推理那章学习到如何对一个评论判断其情感倾向\n",
|
||||
"sentiment = \"消极的\"\n",
|
||||
"\n",
|
||||
"# 一个产品的评价\n",
|
||||
"review = f\"\"\"\n",
|
||||
"他们在11月份的季节性销售期间以约49美元的价格出售17件套装,折扣约为一半。\\\n",
|
||||
"但由于某些原因(可能是价格欺诈),到了12月第二周,同样的套装价格全都涨到了70美元到89美元不等。\\\n",
|
||||
"11件套装的价格也上涨了大约10美元左右。\\\n",
|
||||
"虽然外观看起来还可以,但基座上锁定刀片的部分看起来不如几年前的早期版本那么好。\\\n",
|
||||
"不过我打算非常温柔地使用它,例如,\\\n",
|
||||
"我会先在搅拌机中将像豆子、冰、米饭等硬物研磨,然后再制成所需的份量,\\\n",
|
||||
"切换到打蛋器制作更细的面粉,或者在制作冰沙时先使用交叉切割刀片,然后使用平面刀片制作更细/不粘的效果。\\\n",
|
||||
"制作冰沙时,特别提示:\\\n",
|
||||
"将水果和蔬菜切碎并冷冻(如果使用菠菜,则轻轻煮软菠菜,然后冷冻直到使用;\\\n",
|
||||
"如果制作果酱,则使用小到中号的食品处理器),这样可以避免在制作冰沙时添加太多冰块。\\\n",
|
||||
"大约一年后,电机发出奇怪的噪音,我打电话给客服,但保修已经过期了,所以我不得不再买一个。\\\n",
|
||||
"总的来说,这些产品的总体质量已经下降,因此它们依靠品牌认可和消费者忠诚度来维持销售。\\\n",
|
||||
"货物在两天内到达。\n",
|
||||
"\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"我们已经使用推断课程中所学方法提取了情感,这是一个关于搅拌机的客户评价,现在我们将根据情感定制回复。\n",
|
||||
"\n",
|
||||
"以下述 Prompt 为例:假设你是一个客户服务 AI 助手,你的任务是为客户发送电子邮件回复,根据通过三个反引号分隔的客户电子邮件,生成一封回复以感谢客户的评价。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"尊敬的客户,\n",
|
||||
"\n",
|
||||
"非常感谢您对我们产品的评价。我们非常抱歉您在购买过程中遇到了价格上涨的问题。我们一直致力于为客户提供最优惠的价格,但由于市场波动,价格可能会有所变化。我们深表歉意,如果您需要任何帮助,请随时联系我们的客户服务团队。\n",
|
||||
"\n",
|
||||
"我们非常感谢您对我们产品的详细评价和使用技巧。我们将会把您的反馈传达给我们的产品团队,以便改进我们的产品质量和性能。\n",
|
||||
"\n",
|
||||
"再次感谢您对我们的支持和反馈。如果您需要任何帮助或有任何疑问,请随时联系我们的客户服务团队。\n",
|
||||
"\n",
|
||||
"祝您一切顺利!\n",
|
||||
"\n",
|
||||
"AI客户代理\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from tool import get_completion\n",
|
||||
"\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"你是一位客户服务的AI助手。\n",
|
||||
"你的任务是给一位重要客户发送邮件回复。\n",
|
||||
"根据客户通过“```”分隔的评价,生成回复以感谢客户的评价。提醒模型使用评价中的具体细节\n",
|
||||
"用简明而专业的语气写信。\n",
|
||||
"作为“AI客户代理”签署电子邮件。\n",
|
||||
"客户评论:\n",
|
||||
"```{review}```\n",
|
||||
"评论情感:{sentiment}\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 二、引入温度系数\n",
|
||||
"\n",
|
||||
"接下来,我们将使用语言模型的一个称为“温度” (Temperature) 的参数,它将允许我们改变模型响应的多样性。您可以将温度视为模型探索或随机性的程度。\n",
|
||||
"\n",
|
||||
"例如,在一个特定的短语中,“我的最爱食品”最有可能的下一个词是“比萨”,其次最有可能的是“寿司”和“塔可”。因此,在温度为零时,模型将总是选择最有可能的下一个词,而在较高的温度下,它还将选择其中一个不太可能的词,在更高的温度下,它甚至可能选择塔可,而这种可能性仅为五分之一。您可以想象,随着模型继续生成更多单词的最终响应,“我的最爱食品是比萨”将会与第一个响应“我的最爱食品是塔可”产生差异。随着模型的继续,这两个响应也将变得越来越不同。\n",
|
||||
"\n",
|
||||
"一般来说,在构建需要可预测响应的应用程序时,我建议**设置温度为零**。在所有课程中,我们一直设置温度为零,如果您正在尝试构建一个可靠和可预测的系统,我认为您应该选择这个温度。如果您尝试以更具创意的方式使用模型,可能需要更广泛地输出不同的结果,那么您可能需要使用更高的温度。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"同一段来信,我们提醒模型使用用户来信中的详细信息,并设置温度:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"尊敬的客户,\n",
|
||||
"\n",
|
||||
"感谢您对我们产品的评价。我们非常重视您的意见,并对您在使用过程中遇到的问题表示诚挚的道歉。\n",
|
||||
"\n",
|
||||
"我们对价格的变动深感抱歉。根据您的描述,我们了解到在12月第二周,套装的价格出现了不同程度的上涨。我们会进一步调查此事,并确保我们的定价策略更加透明和一致。\n",
|
||||
"\n",
|
||||
"您提到了产品部分的质量下降,特别是锁定刀片的部分。我们对此感到非常遗憾,并将反馈给我们的研发团队,以便改进产品的设计和质量控制。我们始终致力于提供优质的产品,以满足客户的需求和期望。\n",
|
||||
"\n",
|
||||
"此外,我们将非常感谢您分享了您对产品的使用方式和相关提示。您的经验和建议对我们来说非常宝贵,我们将考虑将其纳入我们的产品改进计划中。\n",
|
||||
"\n",
|
||||
"如果您需要进一步帮助或有其他问题,请随时联系我们的客户服务团队。我们将竭诚为您提供支持和解决方案。\n",
|
||||
"\n",
|
||||
"再次感谢您的反馈和对我们的支持。我们将继续努力提供更好的产品和服务。\n",
|
||||
"\n",
|
||||
"祝您一切顺利!\n",
|
||||
"\n",
|
||||
"AI客户代理\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 第一次运行\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"你是一名客户服务的AI助手。\n",
|
||||
"你的任务是给一位重要的客户发送邮件回复。\n",
|
||||
"根据通过“```”分隔的客户电子邮件生成回复,以感谢客户的评价。\n",
|
||||
"如果情感是积极的或中性的,感谢他们的评价。\n",
|
||||
"如果情感是消极的,道歉并建议他们联系客户服务。\n",
|
||||
"请确保使用评论中的具体细节。\n",
|
||||
"以简明和专业的语气写信。\n",
|
||||
"以“AI客户代理”的名义签署电子邮件。\n",
|
||||
"客户评价:```{review}```\n",
|
||||
"评论情感:{sentiment}\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt, temperature=0.7)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"亲爱的客户,\n",
|
||||
"\n",
|
||||
"非常感谢您对我们产品的评价和反馈。我们非常重视您的意见,并感谢您对我们产品的支持。\n",
|
||||
"\n",
|
||||
"首先,我们对价格的变动感到非常抱歉给您带来了困扰。我们会认真考虑您提到的情况,并采取适当的措施来改进我们的价格策略,以避免类似情况再次发生。\n",
|
||||
"\n",
|
||||
"关于产品质量的问题,我们深感抱歉。我们一直致力于提供高质量的产品,并且我们会将您提到的问题反馈给我们的研发团队,以便改进产品的设计和制造过程。\n",
|
||||
"\n",
|
||||
"如果您需要更多关于产品保修的信息,或者对我们的其他产品有任何疑问或需求,请随时联系我们的客户服务团队。我们将竭诚为您提供帮助和支持。\n",
|
||||
"\n",
|
||||
"再次感谢您对我们产品的评价和支持。我们将继续努力提供优质的产品和出色的客户服务,以满足您的需求。\n",
|
||||
"\n",
|
||||
"祝您度过愉快的一天!\n",
|
||||
"\n",
|
||||
"AI客户代理\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 第二次运行\n",
|
||||
"prompt = f\"\"\"\n",
|
||||
"你是一名客户服务的AI助手。\n",
|
||||
"你的任务是给一位重要的客户发送邮件回复。\n",
|
||||
"根据通过“```”分隔的客户电子邮件生成回复,以感谢客户的评价。\n",
|
||||
"如果情感是积极的或中性的,感谢他们的评价。\n",
|
||||
"如果情感是消极的,道歉并建议他们联系客户服务。\n",
|
||||
"请确保使用评论中的具体细节。\n",
|
||||
"以简明和专业的语气写信。\n",
|
||||
"以“AI客户代理”的名义签署电子邮件。\n",
|
||||
"客户评价:```{review}```\n",
|
||||
"评论情感:{sentiment}\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt, temperature=0.7)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"在温度为零时,每次执行相同的 Prompt ,您获得的回复理应相同。而使用温度为 0.7 时,则每次都会获得不同的输出。\n",
|
||||
"\n",
|
||||
"所以,您可以看到它与我们之前收到的电子邮件不同。再次执行将再次获得不同的电子邮件。\n",
|
||||
"\n",
|
||||
"因此,我建议您自己尝试温度,以查看输出如何变化。总之,在更高的温度下,模型的输出更加随机。您几乎可以将其视为在更高的温度下,助手**更易分心**,但也许**更有创造力**。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 三、英文版"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**1.1 定制客户邮件**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"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",
|
||||
"\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Dear Valued Customer,\n",
|
||||
"\n",
|
||||
"Thank you for taking the time to share your review with us. We appreciate your feedback and apologize for any inconvenience you may have experienced.\n",
|
||||
"\n",
|
||||
"We are sorry to hear about the price increase you noticed in December. We strive to provide competitive pricing for our products, and we understand your frustration. If you have any further concerns regarding pricing or any other issues, we encourage you to reach out to our customer service team. They will be more than happy to assist you.\n",
|
||||
"\n",
|
||||
"We also appreciate your feedback regarding the base of the system. We continuously work to improve the quality of our products, and your comments will be taken into consideration for future enhancements.\n",
|
||||
"\n",
|
||||
"We apologize for any inconvenience caused by the motor issue you encountered. Our customer service team is always available to assist with any warranty-related concerns. We understand that the warranty had expired, but we would still like to address this matter further. Please feel free to contact our customer service team, and they will do their best to assist you.\n",
|
||||
"\n",
|
||||
"Thank you once again for your review. We value your feedback and appreciate your loyalty to our brand. If you have any further questions or concerns, please do not hesitate to contact us.\n",
|
||||
"\n",
|
||||
"Best regards,\n",
|
||||
"\n",
|
||||
"AI customer agent\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"prompt = f\"\"\"\n",
|
||||
"You are a customer service AI assistant.\n",
|
||||
"Your task is to send an email reply to a valued customer.\n",
|
||||
"Given the customer email delimited by ```, \\\n",
|
||||
"Generate a reply to thank the customer for their review.\n",
|
||||
"If the sentiment is positive or neutral, thank them for \\\n",
|
||||
"their review.\n",
|
||||
"If the sentiment is negative, apologize and suggest that \\\n",
|
||||
"they can reach out to customer service. \n",
|
||||
"Make sure to use specific details from the review.\n",
|
||||
"Write in a concise and professional tone.\n",
|
||||
"Sign the email as `AI customer agent`.\n",
|
||||
"Customer review: ```{review}```\n",
|
||||
"Review sentiment: {sentiment}\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**2.1 引入温度系数**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Dear Valued Customer,\n",
|
||||
"\n",
|
||||
"Thank you for taking the time to share your feedback with us. We sincerely apologize for any inconvenience you experienced with our pricing and the quality of our product.\n",
|
||||
"\n",
|
||||
"We understand your frustration regarding the price increase of our 17 piece system in December. We assure you that price gouging is not our intention, and we apologize for any confusion caused. We appreciate your loyalty and we value your feedback, as it helps us to improve our products and services.\n",
|
||||
"\n",
|
||||
"Regarding the issue with the blade lock and the decrease in overall quality, we apologize for any disappointment caused. We strive to provide our customers with the best possible products, and we regret that we did not meet your expectations. We will make sure to take your feedback into consideration for future improvements.\n",
|
||||
"\n",
|
||||
"If you require further assistance or if you have any other concerns, please do not hesitate to reach out to our customer service team. They will be more than happy to assist you in resolving any issues you may have.\n",
|
||||
"\n",
|
||||
"Once again, we apologize for any inconvenience caused and we appreciate your understanding. We value your business and we hope to have the opportunity to serve you better in the future.\n",
|
||||
"\n",
|
||||
"Best regards,\n",
|
||||
"\n",
|
||||
"AI customer agent\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"prompt = f\"\"\"\n",
|
||||
"You are a customer service AI assistant.\n",
|
||||
"Your task is to send an email reply to a valued customer.\n",
|
||||
"Given the customer email delimited by ```, \\\n",
|
||||
"Generate a reply to thank the customer for their review.\n",
|
||||
"If the sentiment is positive or neutral, thank them for \\\n",
|
||||
"their review.\n",
|
||||
"If the sentiment is negative, apologize and suggest that \\\n",
|
||||
"they can reach out to customer service. \n",
|
||||
"Make sure to use specific details from the review.\n",
|
||||
"Write in a concise and professional tone.\n",
|
||||
"Sign the email as `AI customer agent`.\n",
|
||||
"Customer review: ```{review}```\n",
|
||||
"Review sentiment: {sentiment}\n",
|
||||
"\"\"\"\n",
|
||||
"response = get_completion(prompt, temperature=0.7)\n",
|
||||
"print(response)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.11"
|
||||
},
|
||||
"latex_envs": {
|
||||
"LaTeX_envs_menu_present": true,
|
||||
"autoclose": false,
|
||||
"autocomplete": true,
|
||||
"bibliofile": "biblio.bib",
|
||||
"cite_by": "apalike",
|
||||
"current_citInitial": 1,
|
||||
"eqLabelWithNumbers": true,
|
||||
"eqNumInitial": 1,
|
||||
"hotkeys": {
|
||||
"equation": "Ctrl-E",
|
||||
"itemize": "Ctrl-I"
|
||||
},
|
||||
"labels_anchors": false,
|
||||
"latex_user_defs": false,
|
||||
"report_style_numbering": false,
|
||||
"user_envs_cfg": false
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": true,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": false
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@ -0,0 +1,856 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a9183228-0ba6-4af9-8430-649e28868253",
|
||||
"metadata": {
|
||||
"id": "JMXGlIvAwn30"
|
||||
},
|
||||
"source": [
|
||||
"# 第八章 聊天机器人"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f0bdc2c9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"使用一个大型语言模型的一个令人兴奋的事情是,我们可以用它来构建一个定制的聊天机器人 (Chatbot) ,只需要很少的工作量。在这一节中,我们将探索如何利用聊天的方式,与个性化(或专门针对特定任务或行为的)聊天机器人进行扩展对话。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e6fae355",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"像 ChatGPT 这样的聊天模型实际上是组装成以一系列消息作为输入,并返回一个模型生成的消息作为输出的。这种聊天格式原本的设计目标是简便多轮对话,但我们通过之前的学习可以知道,它对于不会涉及任何对话的**单轮任务**也同样有用。\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "78344a7e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 一、给定身份"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2c9b885b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"接下来,我们将定义两个辅助函数。\n",
|
||||
"\n",
|
||||
"第一个方法已经陪伴了您一整个教程,即 ```get_completion``` ,其适用于单轮对话。我们将 Prompt 放入某种类似**用户消息**的对话框中。另一个称为 ```get_completion_from_messages``` ,传入一个消息列表。这些消息可以来自大量不同的**角色** (roles) ,我们会描述一下这些角色。\n",
|
||||
"\n",
|
||||
"第一条消息中,我们以系统身份发送系统消息 (system message) ,它提供了一个总体的指示。系统消息则有助于设置助手的行为和角色,并作为对话的高级指示。你可以想象它在助手的耳边低语,引导它的回应,而用户不会注意到系统消息。因此,作为用户,如果你曾经使用过 ChatGPT,您可能从来不知道 ChatGPT 的系统消息是什么,这是有意为之的。系统消息的好处是为开发者提供了一种方法,在不让请求本身成为对话的一部分的情况下,引导助手并指导其回应。\n",
|
||||
"\n",
|
||||
"在 ChatGPT 网页界面中,您的消息称为用户消息,而 ChatGPT 的消息称为助手消息。但在构建聊天机器人时,在发送了系统消息之后,您的角色可以仅作为用户 (user) ;也可以在用户和助手 (assistant) 之间交替,从而提供对话上下文。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "f5308d65",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import openai\n",
|
||||
"\n",
|
||||
"# 下文第一个函数即tool工具包中的同名函数,此处展示出来以便于读者对比\n",
|
||||
"def get_completion(prompt, model=\"gpt-3.5-turbo\"):\n",
|
||||
" messages = [{\"role\": \"user\", \"content\": prompt}]\n",
|
||||
" response = openai.ChatCompletion.create(\n",
|
||||
" model=model,\n",
|
||||
" messages=messages,\n",
|
||||
" temperature=0, # 控制模型输出的随机程度\n",
|
||||
" )\n",
|
||||
" return response.choices[0].message[\"content\"]\n",
|
||||
"\n",
|
||||
"def get_completion_from_messages(messages, model=\"gpt-3.5-turbo\", temperature=0):\n",
|
||||
" response = openai.ChatCompletion.create(\n",
|
||||
" model=model,\n",
|
||||
" messages=messages,\n",
|
||||
" temperature=temperature, # 控制模型输出的随机程度\n",
|
||||
" )\n",
|
||||
"# print(str(response.choices[0].message))\n",
|
||||
" return response.choices[0].message[\"content\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "46caaa5b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"现在让我们尝试在对话中使用这些消息。我们将使用上面的函数来获取从这些消息中得到的回答,同时,使用更高的温度 (temperature)(越高生成的越多样,更多内容见第七章)。\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e105c1b4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 1.1 讲笑话\n",
|
||||
"\n",
|
||||
"系统消息说,你是一个说话像莎士比亚的助手。这是我们向助手描述**它应该如何表现的方式**。然后,第一个用户消息是*给我讲个笑话*。接下来以助手身份给出回复是,*为什么鸡会过马路?* 最后发送用户消息是*我不知道*。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "02b0e4d3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 中文\n",
|
||||
"messages = [ \n",
|
||||
"{'role':'system', 'content':'你是一个像莎士比亚一样说话的助手。'}, \n",
|
||||
"{'role':'user', 'content':'给我讲个笑话'}, \n",
|
||||
"{'role':'assistant', 'content':'鸡为什么过马路'}, \n",
|
||||
"{'role':'user', 'content':'我不知道'} ]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"id": "65f80283",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"为了到达彼岸,去追求自己的夢想! 有点儿像一个戏剧里面的人物吧,不是吗?\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = get_completion_from_messages(messages, temperature=1)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": "852b8989",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 1.2 友好的聊天机器人"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5f76bedb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"让我们看另一个例子。助手的消息是*你是一个友好的聊天机器人*,第一个用户消息是*嗨,我叫Isa*。我们想要得到第一个用户消息。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "ca517ab0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"嗨,Isa,很高兴见到你!有什么我可以帮助你的吗?\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 中文\n",
|
||||
"messages = [ \n",
|
||||
"{'role':'system', 'content':'你是个友好的聊天机器人。'}, \n",
|
||||
"{'role':'user', 'content':'Hi, 我是Isa。'} ]\n",
|
||||
"response = get_completion_from_messages(messages, temperature=1)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1dd6c5f8",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 二、构建上下文"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1e9f96ba",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"让我们再试一个例子。系统消息是,你是一个友好的聊天机器人,第一个用户消息是,是的,你能提醒我我的名字是什么吗?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "a606d422",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"抱歉,我不知道您的名字,因为我们是虚拟的聊天机器人和现实生活中的人类在不同的世界中。\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 中文\n",
|
||||
"messages = [ \n",
|
||||
"{'role':'system', 'content':'你是个友好的聊天机器人。'}, \n",
|
||||
"{'role':'user', 'content':'好,你能提醒我,我的名字是什么吗?'} ]\n",
|
||||
"response = get_completion_from_messages(messages, temperature=1)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "05c65d16",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"如上所见,模型实际上并不知道我的名字。\n",
|
||||
"\n",
|
||||
"因此,每次与语言模型的交互都互相独立,这意味着我们必须提供所有相关的消息,以便模型在当前对话中进行引用。如果想让模型引用或 “记住” 对话的早期部分,则必须在模型的输入中提供早期的交流。我们将其称为上下文 (context) 。尝试以下示例。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "6019b1d5",
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"当然可以!您的名字是Isa。\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 中文\n",
|
||||
"messages = [ \n",
|
||||
"{'role':'system', 'content':'你是个友好的聊天机器人。'},\n",
|
||||
"{'role':'user', 'content':'Hi, 我是Isa'},\n",
|
||||
"{'role':'assistant', 'content': \"Hi Isa! 很高兴认识你。今天有什么可以帮到你的吗?\"},\n",
|
||||
"{'role':'user', 'content':'是的,你可以提醒我, 我的名字是什么?'} ]\n",
|
||||
"response = get_completion_from_messages(messages, temperature=1)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c1ed90a6",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"现在我们已经给模型提供了上下文,也就是之前的对话中提到的我的名字,然后我们会问同样的问题,也就是我的名字是什么。因为模型有了需要的全部上下文,所以它能够做出回应,就像我们在输入的消息列表中看到的一样。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dedba66a-58b0-40d4-b9ae-47e79ae22328",
|
||||
"metadata": {
|
||||
"id": "bBg_MpXeYnTq"
|
||||
},
|
||||
"source": [
|
||||
"## 三、订餐机器人\n",
|
||||
"\n",
|
||||
"现在,我们构建一个 “订餐机器人”,我们需要它自动收集用户信息,接受比萨饼店的订单。\n",
|
||||
"\n",
|
||||
"### 3.1 构建机器人\n",
|
||||
"\n",
|
||||
"下面这个函数将收集我们的用户消息,以便我们可以避免像刚才一样手动输入。这个函数将从我们下面构建的用户界面中收集 Prompt ,然后将其附加到一个名为上下文( ```context``` )的列表中,并在每次调用模型时使用该上下文。模型的响应也会添加到上下文中,所以用户消息和模型消息都被添加到上下文中,上下文逐渐变长。这样,模型就有了需要的信息来确定下一步要做什么。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"id": "e76749ac",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def collect_messages(_):\n",
|
||||
" prompt = inp.value_input\n",
|
||||
" inp.value = ''\n",
|
||||
" context.append({'role':'user', 'content':f\"{prompt}\"})\n",
|
||||
" response = get_completion_from_messages(context) \n",
|
||||
" context.append({'role':'assistant', 'content':f\"{response}\"})\n",
|
||||
" panels.append(\n",
|
||||
" pn.Row('User:', pn.pane.Markdown(prompt, width=600)))\n",
|
||||
" panels.append(\n",
|
||||
" pn.Row('Assistant:', pn.pane.Markdown(response, width=600, style={'background-color': '#F6F6F6'})))\n",
|
||||
" \n",
|
||||
" return pn.Column(*panels)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8a3b003e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"现在,我们将设置并运行这个 UI 来显示订单机器人。初始的上下文包含了包含菜单的系统消息,在每次调用时都会使用。此后随着对话进行,上下文也会不断增长。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d9f97fa0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install panel"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fdf1731b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 中文\n",
|
||||
"import panel as pn # GUI\n",
|
||||
"pn.extension()\n",
|
||||
"\n",
|
||||
"panels = [] # collect display \n",
|
||||
"\n",
|
||||
"context = [{'role':'system', 'content':\"\"\"\n",
|
||||
"你是订餐机器人,为披萨餐厅自动收集订单信息。\n",
|
||||
"你要首先问候顾客。然后等待用户回复收集订单信息。收集完信息需确认顾客是否还需要添加其他内容。\n",
|
||||
"最后需要询问是否自取或外送,如果是外送,你要询问地址。\n",
|
||||
"最后告诉顾客订单总金额,并送上祝福。\n",
|
||||
"\n",
|
||||
"请确保明确所有选项、附加项和尺寸,以便从菜单中识别出该项唯一的内容。\n",
|
||||
"你的回应应该以简短、非常随意和友好的风格呈现。\n",
|
||||
"\n",
|
||||
"菜单包括:\n",
|
||||
"\n",
|
||||
"菜品:\n",
|
||||
"意式辣香肠披萨(大、中、小) 12.95、10.00、7.00\n",
|
||||
"芝士披萨(大、中、小) 10.95、9.25、6.50\n",
|
||||
"茄子披萨(大、中、小) 11.95、9.75、6.75\n",
|
||||
"薯条(大、小) 4.50、3.50\n",
|
||||
"希腊沙拉 7.25\n",
|
||||
"\n",
|
||||
"配料:\n",
|
||||
"奶酪 2.00\n",
|
||||
"蘑菇 1.50\n",
|
||||
"香肠 3.00\n",
|
||||
"加拿大熏肉 3.50\n",
|
||||
"AI酱 1.50\n",
|
||||
"辣椒 1.00\n",
|
||||
"\n",
|
||||
"饮料:\n",
|
||||
"可乐(大、中、小) 3.00、2.00、1.00\n",
|
||||
"雪碧(大、中、小) 3.00、2.00、1.00\n",
|
||||
"瓶装水 5.00\n",
|
||||
"\"\"\"} ] # accumulate messages\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"inp = pn.widgets.TextInput(value=\"Hi\", placeholder='Enter text here…')\n",
|
||||
"button_conversation = pn.widgets.Button(name=\"Chat!\")\n",
|
||||
"\n",
|
||||
"interactive_conversation = pn.bind(collect_messages, button_conversation)\n",
|
||||
"\n",
|
||||
"dashboard = pn.Column(\n",
|
||||
" inp,\n",
|
||||
" pn.Row(button_conversation),\n",
|
||||
" pn.panel(interactive_conversation, loading_indicator=True, height=300),\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"dashboard"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "07d29d10",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"运行如上代码可以得到一个点餐机器人,下图展示了一个点餐的完整流程:\n",
|
||||
"\n",
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "668ea96d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 3.2 创建JSON摘要"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2a2c9822",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"此处我们另外要求模型创建一个 JSON 摘要,方便我们发送给订单系统。\n",
|
||||
"\n",
|
||||
"因此我们需要在上下文的基础上追加另一个系统消息,作为另一条指示 (instruction) 。我们说*创建一个刚刚订单的 JSON 摘要,列出每个项目的价格,字段应包括 1)披萨,包括尺寸,2)配料列表,3)饮料列表,4)辅菜列表,包括尺寸,最后是总价格*。此处也可以定义为用户消息,不一定是系统消息。\n",
|
||||
"\n",
|
||||
"请注意,这里我们使用了一个较低的温度,因为对于这些类型的任务,我们希望输出相对可预测。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 35,
|
||||
"id": "c840ff56",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{\n",
|
||||
" \"披萨\": {\n",
|
||||
" \"意式辣香肠披萨\": {\n",
|
||||
" \"大\": 12.95,\n",
|
||||
" \"中\": 10.00,\n",
|
||||
" \"小\": 7.00\n",
|
||||
" },\n",
|
||||
" \"芝士披萨\": {\n",
|
||||
" \"大\": 10.95,\n",
|
||||
" \"中\": 9.25,\n",
|
||||
" \"小\": 6.50\n",
|
||||
" },\n",
|
||||
" \"茄子披萨\": {\n",
|
||||
" \"大\": 11.95,\n",
|
||||
" \"中\": 9.75,\n",
|
||||
" \"小\": 6.75\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" \"配料\": {\n",
|
||||
" \"奶酪\": 2.00,\n",
|
||||
" \"蘑菇\": 1.50,\n",
|
||||
" \"香肠\": 3.00,\n",
|
||||
" \"加拿大熏肉\": 3.50,\n",
|
||||
" \"AI酱\": 1.50,\n",
|
||||
" \"辣椒\": 1.00\n",
|
||||
" },\n",
|
||||
" \"饮料\": {\n",
|
||||
" \"可乐\": {\n",
|
||||
" \"大\": 3.00,\n",
|
||||
" \"中\": 2.00,\n",
|
||||
" \"小\": 1.00\n",
|
||||
" },\n",
|
||||
" \"雪碧\": {\n",
|
||||
" \"大\": 3.00,\n",
|
||||
" \"中\": 2.00,\n",
|
||||
" \"小\": 1.00\n",
|
||||
" },\n",
|
||||
" \"瓶装水\": 5.00\n",
|
||||
" }\n",
|
||||
"}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"messages = context.copy()\n",
|
||||
"messages.append(\n",
|
||||
"{'role':'system', 'content':\n",
|
||||
"'''创建上一个食品订单的 json 摘要。\\\n",
|
||||
"逐项列出每件商品的价格,字段应该是 1) 披萨,包括大小 2) 配料列表 3) 饮料列表,包括大小 4) 配菜列表包括大小 5) 总价\n",
|
||||
"你应该给我返回一个可解析的Json对象,包括上述字段'''}, \n",
|
||||
")\n",
|
||||
"\n",
|
||||
"response = get_completion_from_messages(messages, temperature=0)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ef17c2b2",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"现在,我们已经建立了自己的订餐聊天机器人。请随意自定义并修改系统消息,以更改聊天机器人的行为,并使其扮演不同的角色,拥有不同的知识。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2764c8a0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 三、英文版"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "123f2066",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**1.1 讲笑话**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"id": "c9dff513",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"messages = [ \n",
|
||||
"{'role':'system', 'content':'You are an assistant that speaks like Shakespeare.'}, \n",
|
||||
"{'role':'user', 'content':'tell me a joke'}, \n",
|
||||
"{'role':'assistant', 'content':'Why did the chicken cross the road'}, \n",
|
||||
"{'role':'user', 'content':'I don\\'t know'} ]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"id": "381e14c1",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"To get to the other side, methinks!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = get_completion_from_messages(messages, temperature=1)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "028656a1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**1.2 友好的聊天机器人**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"id": "8205c007",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Hello Isa! How can I assist you today?\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"messages = [ \n",
|
||||
"{'role':'system', 'content':'You are friendly chatbot.'}, \n",
|
||||
"{'role':'user', 'content':'Hi, my name is Isa'} ]\n",
|
||||
"response = get_completion_from_messages(messages, temperature=1)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "81f0d22d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**2.1 构建上下文**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 28,
|
||||
"id": "97296cdd",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"I'm sorry, but as a chatbot, I do not have access to personal information or memory. I cannot remind you of your name.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"messages = [ \n",
|
||||
"{'role':'system', 'content':'You are friendly chatbot.'}, \n",
|
||||
"{'role':'user', 'content':'Yes, can you remind me, What is my name?'} ]\n",
|
||||
"response = get_completion_from_messages(messages, temperature=1)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"id": "5ab959d0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Your name is Isa! How can I assist you further, Isa?\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"messages = [ \n",
|
||||
"{'role':'system', 'content':'You are friendly chatbot.'},\n",
|
||||
"{'role':'user', 'content':'Hi, my name is Isa'},\n",
|
||||
"{'role':'assistant', 'content': \"Hi Isa! It's nice to meet you. \\\n",
|
||||
"Is there anything I can help you with today?\"},\n",
|
||||
"{'role':'user', 'content':'Yes, you can remind me, What is my name?'} ]\n",
|
||||
"response = get_completion_from_messages(messages, temperature=1)\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a93897fc",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**3.1 构建机器人**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"id": "9d93bc09",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def collect_messages(_):\n",
|
||||
" prompt = inp.value_input\n",
|
||||
" inp.value = ''\n",
|
||||
" context.append({'role':'user', 'content':f\"{prompt}\"})\n",
|
||||
" response = get_completion_from_messages(context) \n",
|
||||
" context.append({'role':'assistant', 'content':f\"{response}\"})\n",
|
||||
" panels.append(\n",
|
||||
" pn.Row('User:', pn.pane.Markdown(prompt, width=600)))\n",
|
||||
" panels.append(\n",
|
||||
" pn.Row('Assistant:', pn.pane.Markdown(response, width=600, style={'background-color': '#F6F6F6'})))\n",
|
||||
" \n",
|
||||
" return pn.Column(*panels)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8138c4ac",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import panel as pn # GUI\n",
|
||||
"pn.extension()\n",
|
||||
"\n",
|
||||
"panels = [] # collect display \n",
|
||||
"\n",
|
||||
"context = [ {'role':'system', 'content':\"\"\"\n",
|
||||
"You are OrderBot, an automated service to collect orders for a pizza restaurant. \\\n",
|
||||
"You first greet the customer, then collects the order, \\\n",
|
||||
"and then asks if it's a pickup or delivery. \\\n",
|
||||
"You wait to collect the entire order, then summarize it and check for a final \\\n",
|
||||
"time if the customer wants to add anything else. \\\n",
|
||||
"If it's a delivery, you ask for an address. \\\n",
|
||||
"Finally you collect the payment.\\\n",
|
||||
"Make sure to clarify all options, extras and sizes to uniquely \\\n",
|
||||
"identify the item from the menu.\\\n",
|
||||
"You respond in a short, very conversational friendly style. \\\n",
|
||||
"The menu includes \\\n",
|
||||
"pepperoni pizza 12.95, 10.00, 7.00 \\\n",
|
||||
"cheese pizza 10.95, 9.25, 6.50 \\\n",
|
||||
"eggplant pizza 11.95, 9.75, 6.75 \\\n",
|
||||
"fries 4.50, 3.50 \\\n",
|
||||
"greek salad 7.25 \\\n",
|
||||
"Toppings: \\\n",
|
||||
"extra cheese 2.00, \\\n",
|
||||
"mushrooms 1.50 \\\n",
|
||||
"sausage 3.00 \\\n",
|
||||
"canadian bacon 3.50 \\\n",
|
||||
"AI sauce 1.50 \\\n",
|
||||
"peppers 1.00 \\\n",
|
||||
"Drinks: \\\n",
|
||||
"coke 3.00, 2.00, 1.00 \\\n",
|
||||
"sprite 3.00, 2.00, 1.00 \\\n",
|
||||
"bottled water 5.00 \\\n",
|
||||
"\"\"\"} ] # accumulate messages\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"inp = pn.widgets.TextInput(value=\"Hi\", placeholder='Enter text here…')\n",
|
||||
"button_conversation = pn.widgets.Button(name=\"Chat!\")\n",
|
||||
"\n",
|
||||
"interactive_conversation = pn.bind(collect_messages, button_conversation)\n",
|
||||
"\n",
|
||||
"dashboard = pn.Column(\n",
|
||||
" inp,\n",
|
||||
" pn.Row(button_conversation),\n",
|
||||
" pn.panel(interactive_conversation, loading_indicator=True, height=300),\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"dashboard"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "93944944",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**3.2 创建Json摘要**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"id": "b779dd04",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Sure! Here's a JSON summary of your food order:\n",
|
||||
"\n",
|
||||
"{\n",
|
||||
" \"pizza\": {\n",
|
||||
" \"type\": \"pepperoni\",\n",
|
||||
" \"size\": \"large\"\n",
|
||||
" },\n",
|
||||
" \"toppings\": [\n",
|
||||
" \"extra cheese\",\n",
|
||||
" \"mushrooms\"\n",
|
||||
" ],\n",
|
||||
" \"drinks\": [\n",
|
||||
" {\n",
|
||||
" \"type\": \"coke\",\n",
|
||||
" \"size\": \"medium\"\n",
|
||||
" },\n",
|
||||
" {\n",
|
||||
" \"type\": \"sprite\",\n",
|
||||
" \"size\": \"small\"\n",
|
||||
" }\n",
|
||||
" ],\n",
|
||||
" \"sides\": [\n",
|
||||
" {\n",
|
||||
" \"type\": \"fries\",\n",
|
||||
" \"size\": \"regular\"\n",
|
||||
" }\n",
|
||||
" ],\n",
|
||||
" \"total_price\": 29.45\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"Please let me know if there's anything else you'd like to add or modify.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"messages = context.copy()\n",
|
||||
"messages.append(\n",
|
||||
"{'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",
|
||||
"response = get_completion_from_messages(messages, temperature=0)\n",
|
||||
"print(response)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.11"
|
||||
},
|
||||
"latex_envs": {
|
||||
"LaTeX_envs_menu_present": true,
|
||||
"autoclose": false,
|
||||
"autocomplete": true,
|
||||
"bibliofile": "biblio.bib",
|
||||
"cite_by": "apalike",
|
||||
"current_citInitial": 1,
|
||||
"eqLabelWithNumbers": true,
|
||||
"eqNumInitial": 1,
|
||||
"hotkeys": {
|
||||
"equation": "Ctrl-E",
|
||||
"itemize": "Ctrl-I"
|
||||
},
|
||||
"labels_anchors": false,
|
||||
"latex_user_defs": false,
|
||||
"report_style_numbering": false,
|
||||
"user_envs_cfg": false
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": true,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {
|
||||
"height": "calc(100% - 180px)",
|
||||
"left": "10px",
|
||||
"top": "150px",
|
||||
"width": "277px"
|
||||
},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": true
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
244
docs/content/环境配置.ipynb
Normal file
244
docs/content/环境配置.ipynb
Normal file
@ -0,0 +1,244 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 环境配置"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"我们需要配置⼀个环境来运⾏ Python、Jupyter Notebook、OpenAI API key、相关库以及运⾏本书所需的代码,快速⼊⻔。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 安装Anaconda"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"通过清华源镜像来安装[Anaconda](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive)\n",
|
||||
"\n",
|
||||
"<p align=\"center\">\n",
|
||||
" <img src=\"../../figures/docs/C0/Anaconda-file-list.png\" width=\"1000\" alt=\"Anaconda下载\">\n",
|
||||
"</p>\n",
|
||||
"\n",
|
||||
"选择对应的版本下载安装即可。\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"如果已安装Anaconda,则可以跳过以下步骤。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- 如果我们使用Window系统,可以下载`Anaconda3-2023.07-1-Windows-x86_64.exe`安装包直接安装即可。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- 如果我们使用MacOS系统\n",
|
||||
" 1. Intel芯片:可以下载`Anaconda3-2023.07-1-MacOSX-x86_64.sh`\n",
|
||||
" 2. Apple芯片:可以下载`Anaconda3-2023.07-1-MacOSX-arm64.sh`\n",
|
||||
" 并执行以下操作:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "shellscript"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 以Intel处理器为例,⽂件名可能会更改\n",
|
||||
"sh Anaconda3-2023.07-1-MacOSX-x86_64.sh -b"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"接下来,初始化终端Shell,以便我们可以直接运⾏conda。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "shellscript"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"~/anaconda3/bin/conda init"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"现在关闭并重新打开当前的shell,我们会发现在命令行的前面多了一个`(base)`,这是anaconda的一个基础`python`环境。下⾯我们使⽤以下命令来创建⼀个新的环境:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "shellscript"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 创建一个名为chatgpt且python版本为3.9的环境\n",
|
||||
"conda create --name chatgpt python=3.9 -y"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"创建完成后,现在我们来激活 chatgpt 环境:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "shellscript"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"conda activate chatgpt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 安装本书需要用到的python库"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q python-dotenv\n",
|
||||
"!pip install -q openai\n",
|
||||
"## 等更多的python包"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## OpenAI API key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"在获取OpenAI API key之前我们需要[openai官网](https://openai.com/)中注册一个账号。这里假设我们已经有了openai账号,先在[openai官网](https://openai.com/)登录,登录后如下图所示:\n",
|
||||
"\n",
|
||||
"<p align=\"center\">\n",
|
||||
" <img src=\"../../figures/docs/C0/openai-choose.png\" width=\"1000\" alt=\"openai官网登录后选择API\">\n",
|
||||
"</p>\n",
|
||||
"\n",
|
||||
"我们选择`API`,然后点击右上角的头像,选择`View API keys`,如下图所示:\n",
|
||||
"\n",
|
||||
"<p align=\"center\">\n",
|
||||
" <img src=\"../../figures/docs/C0/openai-get-key.png\" width=\"1000\" alt=\"openai获取key\">\n",
|
||||
"</p>\n",
|
||||
"\n",
|
||||
"点击`Create new secret key`按钮创建OpenAI API key,我们将创建好的OpenAI API key复制以此形式`OPENAI_API_KEY=\"sk-...\"`保存到`.env`文件中,并将`.env`文件保存在项目根目录下。# TODO:放到哪个固定位置待确认\n",
|
||||
"\n",
|
||||
"下面是读取`.env`文件的代码"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import openai\n",
|
||||
"from dotenv import load_dotenv, find_dotenv\n",
|
||||
"\n",
|
||||
"# 读取本地/项目的环境变量。\n",
|
||||
"\n",
|
||||
"# find_dotenv()寻找并定位.env文件的路径\n",
|
||||
"# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 \n",
|
||||
"# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n",
|
||||
"_ = load_dotenv(find_dotenv())\n",
|
||||
"\n",
|
||||
"# 获取环境变量 OPENAI_API_KEY\n",
|
||||
"openai.api_key = os.environ['OPENAI_API_KEY']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"将读取`.env`文件的代码封装成函数供每一章节直接调用获取在OpenAI API key。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from dotenv import load_dotenv, find_dotenv\n",
|
||||
"def get_openai_key():\n",
|
||||
" _ = load_dotenv(find_dotenv())\n",
|
||||
" return os.environ['OPENAI_API_KEY']\n",
|
||||
"\n",
|
||||
"openai.api_key = get_openai_key()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "gpt_flask",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.16"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
BIN
figures/docs/C0/Anaconda-file-list.png
Normal file
BIN
figures/docs/C0/Anaconda-file-list.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
figures/docs/C0/openai-choose.png
Normal file
BIN
figures/docs/C0/openai-choose.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
figures/docs/C0/openai-get-key.png
Normal file
BIN
figures/docs/C0/openai-get-key.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 236 KiB |
BIN
figures/docs/C1/Chatbot-pizza-cn.png
Normal file
BIN
figures/docs/C1/Chatbot-pizza-cn.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 279 KiB |
Reference in New Issue
Block a user