{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第七章 扩展\n",
    "\n",
    "扩展是将短文本，例如一组说明或主题列表，输入到大型语言模型中，让模型生成更长的文本，例如基于某个主题的电子邮件或论文。这样做有一些很好的用途，例如将大型语言模型用作头脑风暴的伙伴。但这种做法也存在一些问题，例如某人可能会使用它来生成大量垃圾邮件。因此，当你使用大型语言模型的这些功能时，请仅以负责任的方式和有益于人们的方式使用它们。\n",
    "\n",
    "在本章中，你将学会如何基于 OpenAI API 生成适用于每个客户评价的客户服务电子邮件。我们还将使用模型的另一个输入参数称为温度，这种参数允许您在模型响应中变化探索的程度和多样性。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 一、环境配置\n",
    "\n",
    "同以上几章，你需要类似的代码来配置一个可以使用 OpenAI API 的环境"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将自己的 API-KEY 导入系统环境变量\n",
    "!export OPENAI_API_KEY='api-key'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "import os\n",
    "from dotenv import load_dotenv, find_dotenv\n",
    "# 导入第三方库\n",
    "\n",
    "_ = load_dotenv(find_dotenv())\n",
    "# 读取系统中的环境变量\n",
    "\n",
    "openai.api_key  = os.getenv('OPENAI_API_KEY')\n",
    "# 设置 API_KEY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 一个封装 OpenAI 接口的函数，参数为 Prompt，返回对应结果\n",
    "def get_completion(prompt, model=\"gpt-3.5-turbo\", temperature=0):\n",
    "    '''\n",
    "    prompt: 对应的提示\n",
    "    model: 调用的模型，默认为 gpt-3.5-turbo(ChatGPT)，有内测资格的用户可以选择 gpt-4\n",
    "    temperature: 温度系数\n",
    "    '''\n",
    "    messages = [{\"role\": \"user\", \"content\": prompt}]\n",
    "    response = openai.ChatCompletion.create(\n",
    "        model=model,\n",
    "        messages=messages,\n",
    "        temperature=temperature, # 模型输出的温度系数，控制输出的随机程度\n",
    "    )\n",
    "    # 调用 OpenAI 的 ChatCompletion 接口\n",
    "    return response.choices[0].message[\"content\"]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 二、定制客户邮件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们将根据客户评价和情感撰写自定义电子邮件响应。因此，我们将给定客户评价和情感，并生成自定义响应即使用 LLM 根据客户评价和评论情感生成定制电子邮件。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们首先给出一个示例，包括一个评论及对应的情感"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "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": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 我们可以在推理那章学习到如何对一个评论判断其情感倾向\n",
    "sentiment = \"negative\"\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",
    "这里的指令是：假设你是一个客户服务AI助手，你的任务是为客户发送电子邮件回复，根据通过三个反引号分隔的客户电子邮件，生成一封回复以感谢客户的评价。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dear Valued Customer,\n",
      "\n",
      "Thank you for taking the time to leave a review about our product. We are sorry to hear that you experienced an increase in price and that the quality of the product did not meet your expectations. We apologize for any inconvenience this may have caused you.\n",
      "\n",
      "We would like to assure you that we take all feedback seriously and we will be sure to pass your comments along to our team. If you have any further concerns, please do not hesitate to reach out to our customer service team for assistance.\n",
      "\n",
      "Thank you again for your review and for choosing our product. 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)\n",
    "print(response)"
   ]
  },
  {
   "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": [
    "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",
    "接下来，我们将使用语言模型的一个称为“温度”的参数，它将允许我们改变模型响应的多样性。您可以将温度视为模型探索或随机性的程度。\n",
    "\n",
    "例如，在一个特定的短语中，“我的最爱食品”最有可能的下一个词是“比萨”，其次最有可能的是“寿司”和“塔可”。因此，在温度为零时，模型将总是选择最有可能的下一个词，而在较高的温度下，它还将选择其中一个不太可能的词，在更高的温度下，它甚至可能选择塔可，而这种可能性仅为五分之一。您可以想象，随着模型继续生成更多单词的最终响应，“我的最爱食品是比萨”将会与第一个响应“我的最爱食品是塔可”产生差异。因此，随着模型的继续，这两个响应将变得越来越不同。\n",
    "\n",
    "一般来说，在构建需要可预测响应的应用程序时，我建议使用温度为零。在所有课程中，我们一直设置温度为零，如果您正在尝试构建一个可靠和可预测的系统，我认为您应该选择这个温度。如果您尝试以更具创意的方式使用模型，可能需要更广泛地输出不同的结果，那么您可能需要使用更高的温度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "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": 10,
   "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 are sorry to hear that you were disappointed with the prices of our products and the quality of our blender. We apologize for any inconvenience this may have caused you.\n",
      "\n",
      "We value your feedback and would like to make things right for you. Please feel free to contact our customer service team so we can assist you with any concerns or issues you may have. We are committed to providing you with the best possible service and products.\n",
      "\n",
      "Thank you again for your review and for being a loyal customer. We hope to have the opportunity to serve you better in the future.\n",
      "\n",
      "Sincerely,\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)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "尊敬的客户，\n",
      "\n",
      "非常感谢您对我们产品的评价。我们由衷地为您在购买过程中遇到的问题表示抱歉。我们确实在12月份的第二周调整了价格，但这是由于市场因素所致，并非价格欺诈。我们深刻意识到您对产品质量的担忧，我们将尽一切努力改进产品，以提供更好的体验。\n",
      "\n",
      "我们非常感激您对我们产品的使用经验和制作技巧的分享。您的建议和反馈对我们非常重要，我们将以此为基础，进一步改进我们的产品。\n",
      "\n",
      "如果您有任何疑问或需要进一步帮助，请随时联系我们的客户服务部门。我们将尽快回复您并提供帮助。\n",
      "\n",
      "最后，请再次感谢您对我们产品的评价和选择。我们期待着未来与您的合作。\n",
      "\n",
      "此致\n",
      "\n",
      "敬礼\n",
      "\n",
      "AI客户代理\n"
     ]
    }
   ],
   "source": [
    "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": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在温度为零时，每次执行相同的提示时，您应该期望获得相同的完成。而使用温度为0.7，则每次都会获得不同的输出。\n",
    "\n",
    "所以，您可以看到它与我们之前收到的电子邮件不同。让我们再次执行它，以显示我们将再次获得不同的电子邮件。\n",
    "\n",
    "因此，我建议您自己尝试温度，以查看输出如何变化。总之，在更高的温度下，模型的输出更加随机。您几乎可以将其视为在更高的温度下，助手更易分心，但也许更有创造力。"
   ]
  }
 ],
 "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.8.13"
  },
  "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
}
