From bc7fa5a0f5b0c53d679248a0c1fed4c1d6271287 Mon Sep 17 00:00:00 2001 From: martin-martin Date: Wed, 21 Jun 2023 17:31:14 +0200 Subject: [PATCH 01/16] Add example CLI --- prompt-engineering/LICENSE | 19 + prompt-engineering/README.md | 377 ++++++++++++++++++++ prompt-engineering/pyproject.toml | 32 ++ prompt-engineering/requirements.txt | 15 + prompt-engineering/src/bleach/__init__.py | 0 prompt-engineering/src/bleach/__main__.py | 3 + prompt-engineering/src/bleach/app.py | 53 +++ prompt-engineering/src/bleach/cli.py | 24 ++ prompt-engineering/src/bleach/settings.toml | 101 ++++++ prompt-engineering/support-chat.txt | 42 +++ 10 files changed, 666 insertions(+) create mode 100644 prompt-engineering/LICENSE create mode 100644 prompt-engineering/README.md create mode 100644 prompt-engineering/pyproject.toml create mode 100644 prompt-engineering/requirements.txt create mode 100644 prompt-engineering/src/bleach/__init__.py create mode 100644 prompt-engineering/src/bleach/__main__.py create mode 100644 prompt-engineering/src/bleach/app.py create mode 100644 prompt-engineering/src/bleach/cli.py create mode 100644 prompt-engineering/src/bleach/settings.toml create mode 100644 prompt-engineering/support-chat.txt diff --git a/prompt-engineering/LICENSE b/prompt-engineering/LICENSE new file mode 100644 index 0000000000..51ddec8a00 --- /dev/null +++ b/prompt-engineering/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Real Python + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/prompt-engineering/README.md b/prompt-engineering/README.md new file mode 100644 index 0000000000..a6e5e52b02 --- /dev/null +++ b/prompt-engineering/README.md @@ -0,0 +1,377 @@ +# Bleach + +Practical example to showcase some prompt engineering techniques. Preprocess customer service chats using GPT-4 through the OpenAI API. + +## Setup + +Create a `.env` file with your OpenAI API key: + +``` +OPENAI_API_KEY=your-api-key +``` + +You can generate your [API key](https://platform.openai.com/account/api-keys) in your OpenAI account settings. + +Move the `.env` file into the `src/bleach/` package folder. + +## Install + +Create and activate a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/). Then install the dependencies and the `bleach` package locally: + +```bash +(venv) $ python -m pip install openai python-dotenv +(venv) $ python -m pip install . +``` + +## Usage + +```bash +(venv) $ python -m bleach --help +usage: bleach [-h] [--file FILE] + +Clean chat text with OpenAI's API + +options: + -h, --help show this help message and exit + --file FILE Path to file with text +``` + +Read support chat content from a file, sanitize the text, classify by sentiment, and format as JSON: + +```bash +(venv) $ python -m bleach --file support-chat.txt +``` + +## Prompts And Output + +I want to show how developing the prompt can give you better results based on a couple of prompting techniques. +Change any of the prompts from `instructions_x` to `instructions` to run the script including the prompt. + +### Step 1: Plain Prompt + +```toml +instructions_1 = """ +Remove personally identifyable information, only show the date, and replace all swear words with "😤" +""" +``` + +**Output** is already pretty good! + +``` +2022-08-24 : What can I help you with? +I CAN'T CONNECT TO MY 😤 ACCOUNT +Are you sure it's not your caps lock? +😤! You're right! + +... + +2022-09-15 : Good evening! How may I assist you? +Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. +I'm sorry to hear that. Let me help you. Can you please confirm your email address? +Sure. + +2022-09-24 : Welcome! What can I do for you today? +Hi, I need to change my delivery address for my recent order. +Alright. Please provide your order number. +It's 3344556. Thanks for your help! +``` + +### Step 2: Delimiters And Step Instructions + +```toml +instructions_2 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Remove personally identifyable information by replacing names in [] with "Agent" and "Client", respectively +2. Replace the date-time information to only show the date in the format YYYY-mm-dd +3. Replace all swear words with the following emoji: "😤" +""" +``` + +**Output** is more specific, but doesn't replace an email address: + +``` +[Agent] 2022-08-24 : What can I help you with? +[Client] 2022-08-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2022-08-24 : Are you sure it's not your caps lock? +[Client] 2022-08-24 : 😤! You're right! + +... + +[Agent] 2022-09-15 : Good evening! How may I assist you? +[Client] 2022-09-15 : Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. +[Agent] 2022-09-15 : I'm sorry to hear that, Client. Let me help you. Can you please confirm your email address? +[Client] 2022-09-15 : Sure, it's sara.winters@email.com. + +[Agent] 2022-09-24 : Welcome! What can I do for you today? +[Client] 2022-09-24 : Hi, I need to change my delivery address for my recent order. +[Agent] 2022-09-24 : Alright, Client. Please provide your order number. +[Client] 2022-09-24 : It's 3344556. Thanks for your help! +``` + +### Step 3: Increase the Steps for More Specificity + +```toml +instructions_3 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace names in [] with "A", for Agent, and "C", for Client, respectively +2. Replace any other personally identifyable information, such as names or email addresses +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Replace all swear words with the following emoji: "😤" +``` + +**Output** tackles the email address: + +``` +[A] 2022-08-24 : What can I help you with? +[C] 2022-08-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[A] 2022-08-24 : Are you sure it's not your caps lock? +[C] 2022-08-24 : 😤! You're right! + +... + +[A] 2022-09-15: Good evening! How may I assist you? +[C] 2022-09-15: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. +[A] 2022-09-15: I'm sorry to hear that. Let me help you. Can you please confirm your email address? +[C] 2022-09-15: Sure, it's [REDACTED]. + +[A] 2022-09-24: Welcome! What can I do for you today? +[C] 2022-09-24: Hi, I need to change my delivery address for my recent order. +[A] 2022-09-24: Alright. Please provide your order number. +[C] 2022-09-24: It's 3344556. Thanks for your help! +``` + +### Step 4: Few-Shot Prompting to Improve Output + +```toml +instructions_4 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace names in [] with "A", for Agent, and "C", for Client, respectively +2. Replace any other personally identifyable information, such as names or email addresses +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Replace all swear words with the following emoji: "😤" + +Here is some example output in the expected format: + +2021-09-29: +---------------------------------------------- +A: How can I assist you today? +C: I CAN'T GET THIS 😤 THING TO TURN ON!! + + +2022-02-24: +---------------------------------------------- +A: Good morning! How can I help you today? +C: Could you help me with applying my coupon code? +""" +``` + +**Output** sticks to the provided format: + +``` +2022-08-24: +---------------------------------------------- +A: What can I help you with? +C: I CAN'T CONNECT TO MY 😤 ACCOUNT +A: Are you sure it's not your caps lock? +C: 😤! You're right! + +... + +2022-09-15: +---------------------------------------------- +A: Good evening! How may I assist you? +C: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. +A: I'm sorry to hear that. Let me help you. Can you please confirm your email address? +C: Sure, it's [REDACTED]. + +2022-09-24: +---------------------------------------------- +A: Welcome! What can I do for you today? +C: Hi, I need to change my delivery address for my recent order. +A: Alright. Please provide your order number. +C: It's 3344556. Thanks for your help! +``` + +### Step 5: Classify Sentiment of Chat Conversation + +```toml +instructions_5 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace names in [] with "A", for Agent, and "C", for Client, respectively +2. Replace any other personally identifyable information, such as names or email addresses +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Classify the sentiment of the client's responses in the conversation with "🔥" for negative and "✅" for positive +5. Replace all swear words with the following emoji: "😤" + +Here is some example output in the expected format: + +🔥 2021-09-29: +---------------------------------------------- +A: How can I assist you today? +C: I CAN'T GET THIS 😤 THING TO TURN ON!! + + +✅ 2022-02-24: +---------------------------------------------- +A: Good morning! How can I help you today? +C: Could you help me with applying my coupon code? +""" +``` + +**Output** works pretty well and could be good for visual inspection of a customer service agent: + +``` +🔥 2022-08-24: +---------------------------------------------- +A: What can I help you with? +C: I CAN'T CONNECT TO MY 😤 ACCOUNT +A: Are you sure it's not your caps lock? +C: 😤! You're right! + +... + +✅ 2022-09-15: +---------------------------------------------- +A: Good evening! How may I assist you? +C: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. +A: I'm sorry to hear that, C. Let me help you. Can you please confirm your email address? +C: Sure, it's [REDACTED]. + +✅ 2022-09-24: +---------------------------------------------- +A: Welcome! What can I do for you today? +C: Hi, I need to change my delivery address for my recent order. +A: Alright, C. Please provide your order number. +C: It's 3344556. Thanks for your help! +``` + +### Step 6: Format as Machine-Readable Output (JSON) + +```toml +instructions_6 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace names in [] with "A", for Agent, and "C", for Client, respectively +2. Replace any other personally identifyable information, such as names or email addresses +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Classify the sentiment of the client's responses in the conversation as "negative" and "positive" +5. Replace all swear words with the following emoji: "😤" +6. Format the resulting text as JSON + +Here is some example output in the expected JSON format: + +``json +{ + "negative": [ + { + "date": "2021-09-29", + "conversation": [ + "A: How can I assist you today?", + "C: I CAN'T GET THIS 😤 THING TO TURN ON!!" + ] + }, + ] + "positive": [ + { + "date": "2022-02-24", + "conversation": [ + "A: Good morning! How can I help you today?", + "C: Could you help me with applying my coupon code?" + ] + }, + ] +} +`` +""" +``` + +**Output** is classified according to sentiment, and well-formatted JSON: + +```json +{ + "negative": [ + { + "date": "2022-08-24", + "conversation": [ + "Agent: What can I help you with?", + "Client: I CAN'T CONNECT TO MY 😤 ACCOUNT", + "Agent: Are you sure it's not your caps lock?", + "Client: 😤! You're right!" + ] + }, + { + "date": "2022-10-05", + "conversation": [ + "Agent: Hi, how can I help you today?", + "Client: MY 😤 ORDER STILL HASN'T ARRIVED AND IT'S BEEN A WEEK!!!", + "Agent: I'm sorry to hear that, Client. Let's look into this issue.", + "Agent: Can you please provide your order number so I can check the status for you?", + "Client: Fine, it's ******.", + "Agent: Thank you, Client. I see there was a delay in shipping. Your order will arrive within the next 2 days." + ] + } + ], + "positive": [ + { + "date": "2022-09-15", + "conversation": [ + "Agent: Hello! How can I assist you today?", + "Client: I can't seem to find the download link for my purchased software.", + "Agent: No problem, Client. Let me find that for you. Can you please provide your order number?", + "Client: It's ******. Thanks for helping me out!" + ] + }, + { + "date": "2022-09-18", + "conversation": [ + "Agent: Hello! How can I help you today?", + "Client: I accidentally placed an order twice, can you help me cancel one?", + "Agent: Sure, Client. Can you give me the order number you'd like to cancel?", + "Client: Yes, it's ******. Thank you!", + "Agent: I've successfully canceled order number ******. You will receive a confirmation email shortly." + ] + }, + { + "date": "2022-09-29", + "conversation": [ + "Agent: Good morning, what can I assist you with today?", + "Client: Hi there, I received a damaged item in my order. Can you help me return it?", + "Agent: I'm sorry to hear that, Client. Can you provide your order number and specify the damaged item?", + "Client: Sure, order number is ****** and the damaged item is a coffee mug." + ] + }, + { + "date": "2022-10-04", + "conversation": [ + "Agent: How can I help you today?", + "Client: My coupon code isn't working at checkout. Can you help?", + "Agent: Of course, Client. Please provide the coupon code you're trying to use.", + "Client: It's \"HELLO10\".", + "Agent: I've checked the code, and it seems to have expired. I apologize for the inconvenience. Here's a new code for you to use: \"WELCOME15\"." + ] + }, + { + "date": "2022-09-15", + "conversation": [ + "Agent: Good evening! How may I assist you?", + "Client: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working.", + "Agent: I'm sorry to hear that, Client. Let me help you. Can you please confirm your email address?", + "Client: Sure, it's **********." + ] + }, + { + "date": "2022-09-24", + "conversation": [ + "Agent: Welcome! What can I do for you today?", + "Client: Hi, I need to change my delivery address for my recent order.", + "Agent: Alright, Client. Please provide your order number.", + "Client: It's ******. Thanks for your help!" + ] + } + ] +} +``` \ No newline at end of file diff --git a/prompt-engineering/pyproject.toml b/prompt-engineering/pyproject.toml new file mode 100644 index 0000000000..4616fc0ee3 --- /dev/null +++ b/prompt-engineering/pyproject.toml @@ -0,0 +1,32 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "bleach" +version = "0.0.1" +authors = [ + { name = "Martin Breuss", email = "martin@realpython.com" } +] +description = "A CLI tool that interacts with GPT-4 to sanitize chat content" +readme = "README.md" +license = { file = "LICENSE" } +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] +dependencies = [ + "openai", + "python-dotenv", +] +requires-python = ">=3.11" + +[project.urls] +Home = "https://realpython.com" + +[project.scripts] +bleach = "bleach.__main__:main" + +[tool.setuptools.package-data] +bleach = ["settings.toml"] diff --git a/prompt-engineering/requirements.txt b/prompt-engineering/requirements.txt new file mode 100644 index 0000000000..116fc72241 --- /dev/null +++ b/prompt-engineering/requirements.txt @@ -0,0 +1,15 @@ +aiohttp==3.8.4 +aiosignal==1.3.1 +async-timeout==4.0.2 +attrs==23.1.0 +certifi==2023.5.7 +charset-normalizer==3.1.0 +frozenlist==1.3.3 +idna==3.4 +multidict==6.0.4 +openai==0.27.8 +python-dotenv==1.0.0 +requests==2.31.0 +tqdm==4.65.0 +urllib3==2.0.3 +yarl==1.9.2 diff --git a/prompt-engineering/src/bleach/__init__.py b/prompt-engineering/src/bleach/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prompt-engineering/src/bleach/__main__.py b/prompt-engineering/src/bleach/__main__.py new file mode 100644 index 0000000000..09679adc5d --- /dev/null +++ b/prompt-engineering/src/bleach/__main__.py @@ -0,0 +1,3 @@ +from bleach.cli import main + +main() diff --git a/prompt-engineering/src/bleach/app.py b/prompt-engineering/src/bleach/app.py new file mode 100644 index 0000000000..9856e6379f --- /dev/null +++ b/prompt-engineering/src/bleach/app.py @@ -0,0 +1,53 @@ +import os +from importlib import resources +from pathlib import Path +from typing import List + +import openai +import tomllib +from dotenv import load_dotenv + +# Authorization: +# Add your API key to the .env file as OPENAI_API_KEY +load_dotenv() +openai.api_key = os.getenv("OPENAI_API_KEY") + +# Load the settings file +settings_path = resources.files(__package__) / "settings.toml" +with settings_path.open("rb") as settings_file: + settings = tomllib.load(settings_file) + +MODEL = settings["general"]["model"] +ROLE_PROMPT = settings["prompts"]["role_prompt"] +INSTRUCTIONS = settings["prompts"]["instructions"] + + +def sanitize(file: str, model: str = MODEL) -> str: + """Assemble all prompts and send the API request.""" + content = _read_input_text(file) + messages = _assemble_messages(content) + + response = openai.ChatCompletion.create( + model=model, + messages=messages, + temperature=0.0, + ) + return response["choices"][0]["message"]["content"] + + +def _read_input_text(input_file: str) -> str: + """Read the text content from a file.""" + input_file_path = Path(input_file) + with input_file_path.open("r") as file: + content = file.read() + return content + + +def _assemble_messages(content: str) -> List[dict]: + """Combine all messages into a well-formatted dictionary.""" + messages = [ + {"role": "system", "content": ROLE_PROMPT}, + {"role": "user", "content": f">>>\n{content}\n<<<\n\n"}, + {"role": "user", "content": INSTRUCTIONS}, + ] + return messages diff --git a/prompt-engineering/src/bleach/cli.py b/prompt-engineering/src/bleach/cli.py new file mode 100644 index 0000000000..435166bb8b --- /dev/null +++ b/prompt-engineering/src/bleach/cli.py @@ -0,0 +1,24 @@ +import argparse + +from bleach.app import sanitize + + +def main() -> None: + args = cli_prompt() + print("Sanitizing...") + print(sanitize(args.file)) + + +def cli_prompt() -> argparse.Namespace: + """Parse the arguments provided through the CLI.""" + parser = argparse.ArgumentParser( + description="Sanitize chat support text with OpenAI's API" + ) + parser.add_argument("--file", help="Path to file with text") + + args = parser.parse_args() + return args + + +if __name__ == "__main__": + main() diff --git a/prompt-engineering/src/bleach/settings.toml b/prompt-engineering/src/bleach/settings.toml new file mode 100644 index 0000000000..ae5648787f --- /dev/null +++ b/prompt-engineering/src/bleach/settings.toml @@ -0,0 +1,101 @@ +[general] +model = "gpt-4" + +[prompts] +role_prompt = "You are a friendly assistant who has a vast knowledge of customer support chats." +instructions = """ +Remove personally identifyable information, only show the date, and replace all swear words with "😤" +""" +instructions_2 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Remove personally identifyable information by replacing names in [] with "Agent" and "Client", respectively +2. Replace the date-time information to only show the date in the format YYYY-mm-dd +3. Replace all swear words with the following emoji: "😤" +""" +instructions_3 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace names in [] with "A", for Agent, and "C", for Client, respectively +2. Replace any other personally identifyable information, such as names or email addresses +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Replace all swear words with the following emoji: "😤" +""" +instructions_4 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace names in [] with "A", for Agent, and "C", for Client, respectively +2. Replace any other personally identifyable information, such as names or email addresses +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Replace all swear words with the following emoji: "😤" + +Here is some example output in the expected format: + +2021-09-29: +---------------------------------------------- +Agent: How can I assist you today? +Client: I CAN'T GET THIS 😤 THING TO TURN ON!! + + +2022-02-24: +---------------------------------------------- +Agent: Good morning! How can I help you today? +Client: Could you help me with applying my coupon code? +""" +instructions_5 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace names in [] with "A", for Agent, and "C", for Client, respectively +2. Replace any other personally identifyable information, such as names or email addresses +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Classify the sentiment of the client's responses in the conversation with "🔥" for negative and "✅" for positive +5. Replace all swear words with the following emoji: "😤" + +Here is some example output in the expected format: + +🔥 2021-09-29: +---------------------------------------------- +A: How can I assist you today? +C: I CAN'T GET THIS 😤 THING TO TURN ON!! + + +✅ 2022-02-24: +---------------------------------------------- +A: Good morning! How can I help you today? +C: Could you help me with applying my coupon code? +""" +instructions_6 = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace names in [] with "A", for Agent, and "C", for Client, respectively +2. Replace any other personally identifyable information, such as names or email addresses +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Classify the sentiment of the client's responses in the conversation as "negative" and "positive" +5. Replace all swear words with the following emoji: "😤" +6. Format the resulting text as JSON + +Here is some example output in the expected JSON format: + +```json +{ + "negative": [ + { + "date": "2021-09-29", + "conversation": [ + "A: How can I assist you today?", + "C: I CAN'T GET THIS 😤 THING TO TURN ON!!" + ] + }, + ] + "positive": [ + { + "date": "2022-02-24", + "conversation": [ + "A: Good morning! How can I help you today?", + "C: Could you help me with applying my coupon code?" + ] + }, + ] +} +``` +""" \ No newline at end of file diff --git a/prompt-engineering/support-chat.txt b/prompt-engineering/support-chat.txt new file mode 100644 index 0000000000..5627ce3556 --- /dev/null +++ b/prompt-engineering/support-chat.txt @@ -0,0 +1,42 @@ +[support_tom] 2022-08-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2022-08-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2022-08-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2022-08-24T10:04:03+00:00 : Blast! You're right! + +[support_amy] 2022-09-15T14:45:35+00:00 : Hello! How can I assist you today? +[greg_stone] 2022-09-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. +[support_amy] 2022-09-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? +[greg_stone] 2022-09-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! + +[support_louis] 2022-10-05T09:22:12+00:00 : Hi, how can I help you today? +[karen_w] 2022-10-05T09:23:47+00:00 : MY BLASTED ORDER STILL HASN'T ARRIVED AND IT'S BEEN A WEEK!!! +[support_louis] 2022-10-05T09:24:15+00:00 : I'm sorry to hear that, Karen. Let's look into this issue.[support_louis] 2022-10-05T09:25:35+00:00: Can you please provide your order number so I can check the status for you? +[karen_w] 2022-10-05T09:26:12+00:00: Fine, it's 9876543. +[support_louis] 2022-10-05T09:26:45+00:00: Thank you, Karen. I see there was a delay in shipping. Your order will arrive within the next 2 days. + +[support_jenny] 2022-09-18T17:35:28+00:00: Hello! How can I help you today? +[alex_harper] 2022-09-18T17:36:05+00:00: I accidentally placed an order twice, can you help me cancel one? +[support_jenny] 2022-09-18T17:36:25+00:00: Sure, Alex. Can you give me the order number you'd like to cancel? +[alex_harper] 2022-09-18T17:36:55+00:00: Yes, it's1122334. Thank you! +[support_jenny] 2022-09-18T17:37:32+00:00: I've successfully canceled order number 1122334. You will receive a confirmation email shortly. + +[support_ben] 2022-09-29T11:51:45+00:00: Good morning, what can I assist you with today? +[lisa_beck] 2022-09-29T11:52:20+00:00: Hi there, I received a damaged item in my order. Can you help me return it? +[support_ben] 2022-09-29T11:52:45+00:00: I'm sorry to hear that, Lisa. Can you provide your order number and specify the damaged item? +[lisa_beck] 2022-09-29T11:53:22+00:00: Sure, order number is 5566778 and the damaged item is a coffee mug. + +[support_rachel] 2022-10-04T08:16:37+00:00: How can I help you today? +[mike_t] 2022-10-04T08:17:15+00:00: My coupon code isn't working at checkout. Can you help? +[support_rachel] 2022-10-04T08:17:38+00:00: Of course, Mike. Please provide the coupon code you're trying to use. +[mike_t] 2022-10-04T08:18:02+00:00: It's "HELLO10". +[support_rachel] 2022-10-04T08:18:37+00:00: I've checked the code, and it seems to have expired. I apologize for the inconvenience. Here's a new code for you to use: "WELCOME15". + +[support_vincent] 2022-09-15T20:43:55+00:00: Good evening! How may I assist you? +[sara_winters] 2022-09-15T20:44:30+00:00: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. +[support_vincent] 2022-09-15T20:44:52+00:00: I'm sorry to hear that, Sara. Let me help you. Can you please confirm your email address? +[sara_winters] 2022-09-15T20:45:25+00:00: Sure, it's sara.winters@email.com. + +[support_david] 2022-09-24T16:28:43+00:00: Welcome! What can I do for you today? +[jane_d] 2022-09-24T16:29:16+00:00: Hi, I need to change my delivery address for my recent order. +[support_david] 2022-09-24T16:29:43+00:00: Alright, Jane. Please provide your order number. +[jane_d] 2022-09-24T16:30:11+00:00: It's 3344556. Thanks for your help! \ No newline at end of file From 650c7eeb7988fded29d33a0f4dc6965b63878f7d Mon Sep 17 00:00:00 2001 From: martin-martin Date: Wed, 21 Jun 2023 17:37:31 +0200 Subject: [PATCH 02/16] Fix a bracket --- prompt-engineering/src/bleach/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prompt-engineering/src/bleach/cli.py b/prompt-engineering/src/bleach/cli.py index 435166bb8b..6f814f6969 100644 --- a/prompt-engineering/src/bleach/cli.py +++ b/prompt-engineering/src/bleach/cli.py @@ -13,7 +13,7 @@ def cli_prompt() -> argparse.Namespace: """Parse the arguments provided through the CLI.""" parser = argparse.ArgumentParser( description="Sanitize chat support text with OpenAI's API" - ) + ) parser.add_argument("--file", help="Path to file with text") args = parser.parse_args() From 1a2de47bd84d5af9f353d51ceca10491cd8a5f68 Mon Sep 17 00:00:00 2001 From: martin-martin Date: Thu, 6 Jul 2023 15:59:34 +0200 Subject: [PATCH 03/16] Fix line break --- prompt-engineering/support-chat.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/prompt-engineering/support-chat.txt b/prompt-engineering/support-chat.txt index 5627ce3556..5a3b3e9dd6 100644 --- a/prompt-engineering/support-chat.txt +++ b/prompt-engineering/support-chat.txt @@ -10,14 +10,15 @@ [support_louis] 2022-10-05T09:22:12+00:00 : Hi, how can I help you today? [karen_w] 2022-10-05T09:23:47+00:00 : MY BLASTED ORDER STILL HASN'T ARRIVED AND IT'S BEEN A WEEK!!! -[support_louis] 2022-10-05T09:24:15+00:00 : I'm sorry to hear that, Karen. Let's look into this issue.[support_louis] 2022-10-05T09:25:35+00:00: Can you please provide your order number so I can check the status for you? +[support_louis] 2022-10-05T09:24:15+00:00 : I'm sorry to hear that, Karen. Let's look into this issue. +[support_louis] 2022-10-05T09:25:35+00:00: Can you please provide your order number so I can check the status for you? [karen_w] 2022-10-05T09:26:12+00:00: Fine, it's 9876543. [support_louis] 2022-10-05T09:26:45+00:00: Thank you, Karen. I see there was a delay in shipping. Your order will arrive within the next 2 days. [support_jenny] 2022-09-18T17:35:28+00:00: Hello! How can I help you today? [alex_harper] 2022-09-18T17:36:05+00:00: I accidentally placed an order twice, can you help me cancel one? [support_jenny] 2022-09-18T17:36:25+00:00: Sure, Alex. Can you give me the order number you'd like to cancel? -[alex_harper] 2022-09-18T17:36:55+00:00: Yes, it's1122334. Thank you! +[alex_harper] 2022-09-18T17:36:55+00:00: Yes, it's 1122334. Thank you! [support_jenny] 2022-09-18T17:37:32+00:00: I've successfully canceled order number 1122334. You will receive a confirmation email shortly. [support_ben] 2022-09-29T11:51:45+00:00: Good morning, what can I assist you with today? From 992fbabee10b7f10894e75b7d6497fab2dc58a32 Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 7 Jul 2023 11:25:22 +0200 Subject: [PATCH 04/16] Write to file by default --- prompt-engineering/src/bleach/cli.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/prompt-engineering/src/bleach/cli.py b/prompt-engineering/src/bleach/cli.py index 6f814f6969..b9b92b2871 100644 --- a/prompt-engineering/src/bleach/cli.py +++ b/prompt-engineering/src/bleach/cli.py @@ -5,9 +5,13 @@ def main() -> None: args = cli_prompt() - print("Sanitizing...") - print(sanitize(args.file)) - + if args.test: + print("Sanitizing...") + print(sanitize(args.file)) + else: + cleaned_filename = f"{args.file.split('.')[-2]}_sanitized.txt" + with open(cleaned_filename, "w") as sanitized_file: + sanitized_file.write(sanitize(args.file)) def cli_prompt() -> argparse.Namespace: """Parse the arguments provided through the CLI.""" @@ -15,6 +19,7 @@ def cli_prompt() -> argparse.Namespace: description="Sanitize chat support text with OpenAI's API" ) parser.add_argument("--file", help="Path to file with text") + parser.add_argument("--test", action='store_true', help="Show output in console") args = parser.parse_args() return args From 970af65e7aa9cb0df68c8d09cd8cf5beeb2762ee Mon Sep 17 00:00:00 2001 From: martin-martin Date: Wed, 19 Jul 2023 13:24:28 +0200 Subject: [PATCH 05/16] Update to slimmer code --- prompt-engineering/README.md | 364 +------------------- prompt-engineering/app.py | 101 ++++++ prompt-engineering/final-settings.toml | 57 +++ prompt-engineering/pyproject.toml | 32 -- prompt-engineering/sanitized-testing.txt | 44 +++ prompt-engineering/sanitized-validation.txt | 43 +++ prompt-engineering/settings.toml | 10 + prompt-engineering/src/bleach/__init__.py | 0 prompt-engineering/src/bleach/__main__.py | 3 - prompt-engineering/src/bleach/app.py | 53 --- prompt-engineering/src/bleach/cli.py | 29 -- prompt-engineering/src/bleach/settings.toml | 101 ------ prompt-engineering/support-chat.txt | 43 --- prompt-engineering/testing.txt | 44 +++ prompt-engineering/validation.txt | 43 +++ 15 files changed, 354 insertions(+), 613 deletions(-) create mode 100644 prompt-engineering/app.py create mode 100644 prompt-engineering/final-settings.toml delete mode 100644 prompt-engineering/pyproject.toml create mode 100644 prompt-engineering/sanitized-testing.txt create mode 100644 prompt-engineering/sanitized-validation.txt create mode 100644 prompt-engineering/settings.toml delete mode 100644 prompt-engineering/src/bleach/__init__.py delete mode 100644 prompt-engineering/src/bleach/__main__.py delete mode 100644 prompt-engineering/src/bleach/app.py delete mode 100644 prompt-engineering/src/bleach/cli.py delete mode 100644 prompt-engineering/src/bleach/settings.toml delete mode 100644 prompt-engineering/support-chat.txt create mode 100644 prompt-engineering/testing.txt create mode 100644 prompt-engineering/validation.txt diff --git a/prompt-engineering/README.md b/prompt-engineering/README.md index a6e5e52b02..144868f805 100644 --- a/prompt-engineering/README.md +++ b/prompt-engineering/README.md @@ -1,377 +1,37 @@ -# Bleach +# Practical Prompt Engineering -Practical example to showcase some prompt engineering techniques. Preprocess customer service chats using GPT-4 through the OpenAI API. +This repository contains a practical example to showcase a few common prompt engineering techniques. It's the code base used in the [associated Real Python tutorial on prompt engineering](https://realpython.com/practical-prompt-engineering/). The project allows you to preprocess customer service chats using GPT-3 and GPT-4 using the OpenAI API. ## Setup -Create a `.env` file with your OpenAI API key: +Export your OpenAI API key as an environment variable: ``` -OPENAI_API_KEY=your-api-key +export OPENAI_API_KEY="your-api-key" ``` You can generate your [API key](https://platform.openai.com/account/api-keys) in your OpenAI account settings. -Move the `.env` file into the `src/bleach/` package folder. - ## Install -Create and activate a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/). Then install the dependencies and the `bleach` package locally: +Create and activate a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/). Then install the `openai` dependency: ```bash -(venv) $ python -m pip install openai python-dotenv -(venv) $ python -m pip install . +(venv) $ python -m pip install openai ``` ## Usage -```bash -(venv) $ python -m bleach --help -usage: bleach [-h] [--file FILE] - -Clean chat text with OpenAI's API - -options: - -h, --help show this help message and exit - --file FILE Path to file with text -``` - -Read support chat content from a file, sanitize the text, classify by sentiment, and format as JSON: +Read support chat conversations from a file, sanitize the text, classify by sentiment, and format the output as JSON: ```bash -(venv) $ python -m bleach --file support-chat.txt -``` - -## Prompts And Output - -I want to show how developing the prompt can give you better results based on a couple of prompting techniques. -Change any of the prompts from `instructions_x` to `instructions` to run the script including the prompt. - -### Step 1: Plain Prompt - -```toml -instructions_1 = """ -Remove personally identifyable information, only show the date, and replace all swear words with "😤" -""" -``` - -**Output** is already pretty good! - -``` -2022-08-24 : What can I help you with? -I CAN'T CONNECT TO MY 😤 ACCOUNT -Are you sure it's not your caps lock? -😤! You're right! - -... - -2022-09-15 : Good evening! How may I assist you? -Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. -I'm sorry to hear that. Let me help you. Can you please confirm your email address? -Sure. - -2022-09-24 : Welcome! What can I do for you today? -Hi, I need to change my delivery address for my recent order. -Alright. Please provide your order number. -It's 3344556. Thanks for your help! -``` - -### Step 2: Delimiters And Step Instructions - -```toml -instructions_2 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Remove personally identifyable information by replacing names in [] with "Agent" and "Client", respectively -2. Replace the date-time information to only show the date in the format YYYY-mm-dd -3. Replace all swear words with the following emoji: "😤" -""" -``` - -**Output** is more specific, but doesn't replace an email address: - -``` -[Agent] 2022-08-24 : What can I help you with? -[Client] 2022-08-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT -[Agent] 2022-08-24 : Are you sure it's not your caps lock? -[Client] 2022-08-24 : 😤! You're right! - -... - -[Agent] 2022-09-15 : Good evening! How may I assist you? -[Client] 2022-09-15 : Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. -[Agent] 2022-09-15 : I'm sorry to hear that, Client. Let me help you. Can you please confirm your email address? -[Client] 2022-09-15 : Sure, it's sara.winters@email.com. - -[Agent] 2022-09-24 : Welcome! What can I do for you today? -[Client] 2022-09-24 : Hi, I need to change my delivery address for my recent order. -[Agent] 2022-09-24 : Alright, Client. Please provide your order number. -[Client] 2022-09-24 : It's 3344556. Thanks for your help! -``` - -### Step 3: Increase the Steps for More Specificity - -```toml -instructions_3 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Replace names in [] with "A", for Agent, and "C", for Client, respectively -2. Replace any other personally identifyable information, such as names or email addresses -3. Replace the date-time information to only show the date in the format YYYY-mm-dd -4. Replace all swear words with the following emoji: "😤" -``` - -**Output** tackles the email address: - -``` -[A] 2022-08-24 : What can I help you with? -[C] 2022-08-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT -[A] 2022-08-24 : Are you sure it's not your caps lock? -[C] 2022-08-24 : 😤! You're right! - -... - -[A] 2022-09-15: Good evening! How may I assist you? -[C] 2022-09-15: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. -[A] 2022-09-15: I'm sorry to hear that. Let me help you. Can you please confirm your email address? -[C] 2022-09-15: Sure, it's [REDACTED]. - -[A] 2022-09-24: Welcome! What can I do for you today? -[C] 2022-09-24: Hi, I need to change my delivery address for my recent order. -[A] 2022-09-24: Alright. Please provide your order number. -[C] 2022-09-24: It's 3344556. Thanks for your help! -``` - -### Step 4: Few-Shot Prompting to Improve Output - -```toml -instructions_4 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Replace names in [] with "A", for Agent, and "C", for Client, respectively -2. Replace any other personally identifyable information, such as names or email addresses -3. Replace the date-time information to only show the date in the format YYYY-mm-dd -4. Replace all swear words with the following emoji: "😤" - -Here is some example output in the expected format: - -2021-09-29: ----------------------------------------------- -A: How can I assist you today? -C: I CAN'T GET THIS 😤 THING TO TURN ON!! - - -2022-02-24: ----------------------------------------------- -A: Good morning! How can I help you today? -C: Could you help me with applying my coupon code? -""" -``` - -**Output** sticks to the provided format: - -``` -2022-08-24: ----------------------------------------------- -A: What can I help you with? -C: I CAN'T CONNECT TO MY 😤 ACCOUNT -A: Are you sure it's not your caps lock? -C: 😤! You're right! - -... - -2022-09-15: ----------------------------------------------- -A: Good evening! How may I assist you? -C: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. -A: I'm sorry to hear that. Let me help you. Can you please confirm your email address? -C: Sure, it's [REDACTED]. - -2022-09-24: ----------------------------------------------- -A: Welcome! What can I do for you today? -C: Hi, I need to change my delivery address for my recent order. -A: Alright. Please provide your order number. -C: It's 3344556. Thanks for your help! -``` - -### Step 5: Classify Sentiment of Chat Conversation - -```toml -instructions_5 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Replace names in [] with "A", for Agent, and "C", for Client, respectively -2. Replace any other personally identifyable information, such as names or email addresses -3. Replace the date-time information to only show the date in the format YYYY-mm-dd -4. Classify the sentiment of the client's responses in the conversation with "🔥" for negative and "✅" for positive -5. Replace all swear words with the following emoji: "😤" - -Here is some example output in the expected format: - -🔥 2021-09-29: ----------------------------------------------- -A: How can I assist you today? -C: I CAN'T GET THIS 😤 THING TO TURN ON!! - - -✅ 2022-02-24: ----------------------------------------------- -A: Good morning! How can I help you today? -C: Could you help me with applying my coupon code? -""" -``` - -**Output** works pretty well and could be good for visual inspection of a customer service agent: - +(venv) $ python app.py testing.txt ``` -🔥 2022-08-24: ----------------------------------------------- -A: What can I help you with? -C: I CAN'T CONNECT TO MY 😤 ACCOUNT -A: Are you sure it's not your caps lock? -C: 😤! You're right! -... +You can provide a different file as input file. -✅ 2022-09-15: ----------------------------------------------- -A: Good evening! How may I assist you? -C: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. -A: I'm sorry to hear that, C. Let me help you. Can you please confirm your email address? -C: Sure, it's [REDACTED]. - -✅ 2022-09-24: ----------------------------------------------- -A: Welcome! What can I do for you today? -C: Hi, I need to change my delivery address for my recent order. -A: Alright, C. Please provide your order number. -C: It's 3344556. Thanks for your help! -``` - -### Step 6: Format as Machine-Readable Output (JSON) - -```toml -instructions_6 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Replace names in [] with "A", for Agent, and "C", for Client, respectively -2. Replace any other personally identifyable information, such as names or email addresses -3. Replace the date-time information to only show the date in the format YYYY-mm-dd -4. Classify the sentiment of the client's responses in the conversation as "negative" and "positive" -5. Replace all swear words with the following emoji: "😤" -6. Format the resulting text as JSON - -Here is some example output in the expected JSON format: - -``json -{ - "negative": [ - { - "date": "2021-09-29", - "conversation": [ - "A: How can I assist you today?", - "C: I CAN'T GET THIS 😤 THING TO TURN ON!!" - ] - }, - ] - "positive": [ - { - "date": "2022-02-24", - "conversation": [ - "A: Good morning! How can I help you today?", - "C: Could you help me with applying my coupon code?" - ] - }, - ] -} -`` -""" -``` +## Prompts And Output -**Output** is classified according to sentiment, and well-formatted JSON: +Change the prompts used in the script by editing the entries in `settings.toml`. -```json -{ - "negative": [ - { - "date": "2022-08-24", - "conversation": [ - "Agent: What can I help you with?", - "Client: I CAN'T CONNECT TO MY 😤 ACCOUNT", - "Agent: Are you sure it's not your caps lock?", - "Client: 😤! You're right!" - ] - }, - { - "date": "2022-10-05", - "conversation": [ - "Agent: Hi, how can I help you today?", - "Client: MY 😤 ORDER STILL HASN'T ARRIVED AND IT'S BEEN A WEEK!!!", - "Agent: I'm sorry to hear that, Client. Let's look into this issue.", - "Agent: Can you please provide your order number so I can check the status for you?", - "Client: Fine, it's ******.", - "Agent: Thank you, Client. I see there was a delay in shipping. Your order will arrive within the next 2 days." - ] - } - ], - "positive": [ - { - "date": "2022-09-15", - "conversation": [ - "Agent: Hello! How can I assist you today?", - "Client: I can't seem to find the download link for my purchased software.", - "Agent: No problem, Client. Let me find that for you. Can you please provide your order number?", - "Client: It's ******. Thanks for helping me out!" - ] - }, - { - "date": "2022-09-18", - "conversation": [ - "Agent: Hello! How can I help you today?", - "Client: I accidentally placed an order twice, can you help me cancel one?", - "Agent: Sure, Client. Can you give me the order number you'd like to cancel?", - "Client: Yes, it's ******. Thank you!", - "Agent: I've successfully canceled order number ******. You will receive a confirmation email shortly." - ] - }, - { - "date": "2022-09-29", - "conversation": [ - "Agent: Good morning, what can I assist you with today?", - "Client: Hi there, I received a damaged item in my order. Can you help me return it?", - "Agent: I'm sorry to hear that, Client. Can you provide your order number and specify the damaged item?", - "Client: Sure, order number is ****** and the damaged item is a coffee mug." - ] - }, - { - "date": "2022-10-04", - "conversation": [ - "Agent: How can I help you today?", - "Client: My coupon code isn't working at checkout. Can you help?", - "Agent: Of course, Client. Please provide the coupon code you're trying to use.", - "Client: It's \"HELLO10\".", - "Agent: I've checked the code, and it seems to have expired. I apologize for the inconvenience. Here's a new code for you to use: \"WELCOME15\"." - ] - }, - { - "date": "2022-09-15", - "conversation": [ - "Agent: Good evening! How may I assist you?", - "Client: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working.", - "Agent: I'm sorry to hear that, Client. Let me help you. Can you please confirm your email address?", - "Client: Sure, it's **********." - ] - }, - { - "date": "2022-09-24", - "conversation": [ - "Agent: Welcome! What can I do for you today?", - "Client: Hi, I need to change my delivery address for my recent order.", - "Agent: Alright, Client. Please provide your order number.", - "Client: It's ******. Thanks for your help!" - ] - } - ] -} -``` \ No newline at end of file +In the tutorial, you learn how developing the prompt can give you better results based on a couple of prompting techniques. diff --git a/prompt-engineering/app.py b/prompt-engineering/app.py new file mode 100644 index 0000000000..5b51266851 --- /dev/null +++ b/prompt-engineering/app.py @@ -0,0 +1,101 @@ +import os +import sys +import tomllib +from pathlib import Path +from typing import List + +import openai + +# Authenticate +openai.api_key = os.getenv("OPENAI_API_KEY") + + +def main() -> str: + try: + file_path = sys.argv[1] + except IndexError: + file_path = "training.txt" + settings = _load_settings() + if settings["general"]["model"] in settings["general"]["chat_models"]: + return request_response(file_path) + return request_completion(file_path) + + +def request_completion(file: str) -> str: + """Assemble all text into a prompt and send a /completion API request.""" + settings = _load_settings() + content = _read_input_text(file) + prompt = _assemble_prompt(content, settings) + + response = openai.Completion.create( + model=settings["general"]["model"], + prompt=prompt, + max_tokens=settings["general"]["max_tokens"], + temperature=settings["general"]["temperature"], + ) + return response["choices"][0]["text"] + + +def request_response(file: str) -> str: + """Assemble all text into a prompt and send a /chat API request.""" + settings = _load_settings() + content = _read_input_text(file) + messages = _assemble_messages(content, settings) + + response = openai.ChatCompletion.create( + model=settings["general"]["model"], + messages=messages, + # max_tokens defaults to inf + temperature=settings["general"]["temperature"], + ) + return response["choices"][0]["message"]["content"] + + +def _load_settings() -> dict: + """Load the settings file.""" + settings_path = Path.cwd() / "settings.toml" + with settings_path.open("rb") as settings_file: + settings = tomllib.load(settings_file) + return settings + + +def _read_input_text(input_file: str) -> str: + """Read the text content from a file.""" + input_file_path = Path(input_file) + with input_file_path.open("r") as file: + content = file.read() + return content + + +def _assemble_prompt(content: str, settings: dict) -> str: + """Combine all messages into a single prompt.""" + prompt = f">>>>>\n{content}\n<<<<<\n\n" + settings["prompts"]["instructions"] + return prompt + + +# def _assemble_messages(content: str, settings: dict) -> List[dict]: +# """Combine all messages into a well-formatted dictionary.""" +# messages = [ +# {"role": "system", "content": settings["prompts"]["role_prompt"]}, +# {"role": "user", "content": f">>>>>\n{content}\n<<<<<\n\n"}, +# {"role": "user", "content": settings["prompts"]["instructions"]}, +# ] +# return messages + +def _assemble_messages(content: str, settings: dict) -> List[dict]: + """Combine all messages into a well-formatted dictionary.""" + messages = [ + {"role": "system", "content": settings["prompts"]["role_prompt"]}, + {"role": "user", "content": settings["prompts"]["negative_example"]}, + {"role": "system", "content": settings["prompts"]["negative_reasoning"]}, + {"role": "assistant", "content": settings["prompts"]["negative_output"]}, + {"role": "user", "content": settings["prompts"]["positive_example"]}, + {"role": "system", "content": settings["prompts"]["positive_reasoning"]}, + {"role": "assistant", "content": settings["prompts"]["positive_output"]}, + {"role": "user", "content": f">>>>>\n{content}\n<<<<<\n\n"}, + {"role": "user", "content": settings["prompts"]["instructions"]}, + ] + return messages + +if __name__ == "__main__": + print(main()) diff --git a/prompt-engineering/final-settings.toml b/prompt-engineering/final-settings.toml new file mode 100644 index 0000000000..22f5e35add --- /dev/null +++ b/prompt-engineering/final-settings.toml @@ -0,0 +1,57 @@ +[general] +chat_models = ["gpt-3.5", "gpt-3.5-turbo", "gpt-4"] +model = "gpt-4" +max_tokens = 100 +temperature = 0 + +[prompts] +role_prompt = """You are an thoroughly trained machine learning model that is an expert at sentiment classification. +You diligently complete tasks as instructed. You never make up any information that isn't there.""" +positive_example = """ +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! +""" +positive_reasoning = "The customer does not use any swear words or 😤 emoji and does not seem aggravated or angry, so the sentiment is positive." +positive_output = """ +{ + "positive": [ + { + "date": "2023-06-15", + "conversation": [ + "A: Hello! How can I assist you today?", + "C: I can't seem to find the download link for my purchased software.", + "A: No problem, ********. Let me find that for you. Can you please provide your order number?", + "C: It's ********. Thanks for helping me out!" + ] + } + ] +} +""" +negative_example = """ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! +""" +negative_reasoning = "The customer uses the 😤 emoji and seems aggravated, so the sentiment is negative." +negative_output = """ +{ + "negative": [ + { + "date": "2023-07-24", + "conversation": [ + "A: What can I help you with?", + "C: I CAN'T CONNECT TO MY 😤 ACCOUNT", + "A: Are you sure it's not your caps lock?", + "C: 😤! You're right!" + ] + } + ] +} +""" +instructions = """ +Classify the sentiment of each conversation in >>>>>CONTENT<<<<< as "negative" and "positive". +Return the output as valid JSON. +""" diff --git a/prompt-engineering/pyproject.toml b/prompt-engineering/pyproject.toml deleted file mode 100644 index 4616fc0ee3..0000000000 --- a/prompt-engineering/pyproject.toml +++ /dev/null @@ -1,32 +0,0 @@ -[build-system] -requires = ["setuptools", "wheel"] -build-backend = "setuptools.build_meta" - -[project] -name = "bleach" -version = "0.0.1" -authors = [ - { name = "Martin Breuss", email = "martin@realpython.com" } -] -description = "A CLI tool that interacts with GPT-4 to sanitize chat content" -readme = "README.md" -license = { file = "LICENSE" } -classifiers = [ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", -] -dependencies = [ - "openai", - "python-dotenv", -] -requires-python = ">=3.11" - -[project.urls] -Home = "https://realpython.com" - -[project.scripts] -bleach = "bleach.__main__:main" - -[tool.setuptools.package-data] -bleach = ["settings.toml"] diff --git a/prompt-engineering/sanitized-testing.txt b/prompt-engineering/sanitized-testing.txt new file mode 100644 index 0000000000..6da3659736 --- /dev/null +++ b/prompt-engineering/sanitized-testing.txt @@ -0,0 +1,44 @@ +[Agent] 2023-07-15: Hello! What can I help you with today? +[Client] 2023-07-15: Hey, my promo code isn't applying the discount in my cart. +[Agent] 2023-07-15: My apologies for the trouble, ********. Could you tell me the promo code you're trying to use? +[Client] 2023-07-15: It's "SAVE20". + +[Agent] 2023-07-24: Good day! How can I help you? +[Client] 2023-07-24: Hi "********", I can't update my 😤 credit card information. Do you want my 😤 money or not? +[Agent] 2023-07-24: I'm sorry for the inconvenience, ********. Can you please confirm your account's email? +[Client] 2023-07-24: Sure, you have all my 😤 data already anyways. It's ********. + +[Agent] 2023-08-13: Good morning! How may I assist you? +[Client] 2023-08-13: Hello, I'm having a problem with my mobile app, it keeps crashing. +[Agent] 2023-08-13: I'm sorry to hear that, ********. Could you tell me what device you're using? +[Client] 2023-08-13: I have an iPhone 11. + +[Agent] 2023-08-30: Good evening! How may I assist you today? +[Client] 2023-08-30: Hi ********, I've forgotten my 😤 password and I can't login into my account. +[Agent] 2023-08-30: I'm sorry for the trouble, ********. Could you confirm your email address so we can reset your password? +[Client] 2023-08-30: Definitely, it's ********. + +[Agent] 2023-09-01: Hello! How can I assist you this morning? +[Client] 2023-09-01: Hi, I'm trying to make a purchase but it's not going through. +[Agent] 2023-09-01: I'm sorry to hear that, ********. Can you tell me what error message you're receiving? +[Client] 2023-09-01: It's saying "Payment method not valid". + +[Agent] 2023-10-11: Good morning! How may I assist you? +[Client] 2023-10-11: Hello, I'd like to know the status of my order. +[Agent] 2023-10-11: Of course, ********. Could you please provide me with the order number? +[Client] 2023-10-11: It's ********. + +[Agent] 2023-10-19: Welcome! How can I assist you right now? +[Client] 2023-10-19: 😤! There's no option to change my profile picture. What kind of 😤 joint are you running? +[Agent] 2023-10-19: Let me help you with this, ********. Are you trying to update it from the mobile app or the website? +[Client] 2023-10-19: I'm using the 😤 website + +[Agent] 2023-10-29: Hello! What can I help you with today? +[Client] 2023-10-29: Hi ********, I was charged twice for my last order. +[Agent] 2023-10-29: I'm sorry to hear that, ********. Could you share your order number so I can look into this for you? +[Client] 2023-10-29: Sure, it's ********. + +[Agent] 2023-11-08: How can I help you today? +[Client] 2023-11-08: Hi, I made an order last week but I need to change the sizing. +[Agent] 2023-11-08: Certainly, ********. Could you provide me the order number? +[Client] 2023-11-08: Yes, it's ********. Thanks! \ No newline at end of file diff --git a/prompt-engineering/sanitized-validation.txt b/prompt-engineering/sanitized-validation.txt new file mode 100644 index 0000000000..3f70b515b2 --- /dev/null +++ b/prompt-engineering/sanitized-validation.txt @@ -0,0 +1,43 @@ +[support_tom] 2023-07-24 : What can I help you with? +[Client] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Client] 2023-07-24 : 😤! You're right! + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Client] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Client] 2023-06-15 : It's ********. Thanks for helping me out! + +[Agent] 2023-05-05 : Hi, how can I help you today? +[Client] 2023-05-05 : MY 😤 ORDER STILL HASN'T ARRIVED AND IT'S BEEN A WEEK!!! +[Agent] 2023-05-05 : I'm sorry to hear that, ********. Let's look into this issue. +[Agent] 2023-05-05: Can you please provide your order number so I can check the status for you? +[Client] 2023-05-05: Fine, it's ********. +[Agent] 2023-05-05: Thank you, ********. I see there was a delay in shipping. Your order will arrive within the next 2 days. + +[Agent] 2023-06-18: Hello! How can I help you today? +[Client] 2023-06-18: I accidentally placed an order twice, can you help me cancel one? +[Agent] 2023-06-18: Sure, ********. Can you give me the order number you'd like to cancel? +[Client] 2023-06-18: Yes, it's ********. Thank you! +[Agent] 2023-06-18: I've successfully canceled order number ********. You will receive a confirmation email shortly. + +[Agent] 2023-06-29: Good morning, what can I assist you with today? +[Client] 2023-06-29: Hi there, I received a damaged item in my order. Can you help me return it? +[Agent] 2023-06-29: I'm sorry to hear that, ********. Can you provide your order number and specify the damaged item? +[Client] 2023-06-29: Sure, order number is ******** and the damaged item is a coffee mug. + +[Agent] 2023-05-04: How can I help you today? +[Client] 2023-05-04: My coupon code isn't working at checkout. Can you help? +[Agent] 2023-05-04: Of course, ********. Please provide the coupon code you're trying to use. +[Client] 2023-05-04: It's "********". +[Agent] 2023-05-04: I've checked the code, and it seems to have expired. I apologize for the inconvenience. Here's a new code for you to use: "********". + +[Agent] 2023-06-15: Good evening! How may I assist you? +[Client] 2023-06-15: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. +[Agent] 2023-06-15: I'm sorry to hear that, ********. Let me help you. Can you please confirm your email address? +[Client] 2023-06-15: Sure, it's ********. + +[Agent] 2023-06-24: Welcome! What can I do for you today? +[Client] 2023-06-24: Hi, I need to change my delivery address for my recent order. +[Agent] 2023-06-24: Alright, ********. Please provide your order number. +[Client] 2023-06-24: It's ********. Thanks for your help! diff --git a/prompt-engineering/settings.toml b/prompt-engineering/settings.toml new file mode 100644 index 0000000000..e932ce6bc7 --- /dev/null +++ b/prompt-engineering/settings.toml @@ -0,0 +1,10 @@ +[general] +chat_models = ["gpt-3.5", "gpt-3.5-turbo", "gpt-4"] +model = "text-davinci-003" +max_tokens = 2200 +temperature = 0 + +[prompts] +instructions = """ +Remove personally identifiable information, only show the date, and replace all swear words with "😤" +""" diff --git a/prompt-engineering/src/bleach/__init__.py b/prompt-engineering/src/bleach/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/prompt-engineering/src/bleach/__main__.py b/prompt-engineering/src/bleach/__main__.py deleted file mode 100644 index 09679adc5d..0000000000 --- a/prompt-engineering/src/bleach/__main__.py +++ /dev/null @@ -1,3 +0,0 @@ -from bleach.cli import main - -main() diff --git a/prompt-engineering/src/bleach/app.py b/prompt-engineering/src/bleach/app.py deleted file mode 100644 index 9856e6379f..0000000000 --- a/prompt-engineering/src/bleach/app.py +++ /dev/null @@ -1,53 +0,0 @@ -import os -from importlib import resources -from pathlib import Path -from typing import List - -import openai -import tomllib -from dotenv import load_dotenv - -# Authorization: -# Add your API key to the .env file as OPENAI_API_KEY -load_dotenv() -openai.api_key = os.getenv("OPENAI_API_KEY") - -# Load the settings file -settings_path = resources.files(__package__) / "settings.toml" -with settings_path.open("rb") as settings_file: - settings = tomllib.load(settings_file) - -MODEL = settings["general"]["model"] -ROLE_PROMPT = settings["prompts"]["role_prompt"] -INSTRUCTIONS = settings["prompts"]["instructions"] - - -def sanitize(file: str, model: str = MODEL) -> str: - """Assemble all prompts and send the API request.""" - content = _read_input_text(file) - messages = _assemble_messages(content) - - response = openai.ChatCompletion.create( - model=model, - messages=messages, - temperature=0.0, - ) - return response["choices"][0]["message"]["content"] - - -def _read_input_text(input_file: str) -> str: - """Read the text content from a file.""" - input_file_path = Path(input_file) - with input_file_path.open("r") as file: - content = file.read() - return content - - -def _assemble_messages(content: str) -> List[dict]: - """Combine all messages into a well-formatted dictionary.""" - messages = [ - {"role": "system", "content": ROLE_PROMPT}, - {"role": "user", "content": f">>>\n{content}\n<<<\n\n"}, - {"role": "user", "content": INSTRUCTIONS}, - ] - return messages diff --git a/prompt-engineering/src/bleach/cli.py b/prompt-engineering/src/bleach/cli.py deleted file mode 100644 index b9b92b2871..0000000000 --- a/prompt-engineering/src/bleach/cli.py +++ /dev/null @@ -1,29 +0,0 @@ -import argparse - -from bleach.app import sanitize - - -def main() -> None: - args = cli_prompt() - if args.test: - print("Sanitizing...") - print(sanitize(args.file)) - else: - cleaned_filename = f"{args.file.split('.')[-2]}_sanitized.txt" - with open(cleaned_filename, "w") as sanitized_file: - sanitized_file.write(sanitize(args.file)) - -def cli_prompt() -> argparse.Namespace: - """Parse the arguments provided through the CLI.""" - parser = argparse.ArgumentParser( - description="Sanitize chat support text with OpenAI's API" - ) - parser.add_argument("--file", help="Path to file with text") - parser.add_argument("--test", action='store_true', help="Show output in console") - - args = parser.parse_args() - return args - - -if __name__ == "__main__": - main() diff --git a/prompt-engineering/src/bleach/settings.toml b/prompt-engineering/src/bleach/settings.toml deleted file mode 100644 index ae5648787f..0000000000 --- a/prompt-engineering/src/bleach/settings.toml +++ /dev/null @@ -1,101 +0,0 @@ -[general] -model = "gpt-4" - -[prompts] -role_prompt = "You are a friendly assistant who has a vast knowledge of customer support chats." -instructions = """ -Remove personally identifyable information, only show the date, and replace all swear words with "😤" -""" -instructions_2 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Remove personally identifyable information by replacing names in [] with "Agent" and "Client", respectively -2. Replace the date-time information to only show the date in the format YYYY-mm-dd -3. Replace all swear words with the following emoji: "😤" -""" -instructions_3 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Replace names in [] with "A", for Agent, and "C", for Client, respectively -2. Replace any other personally identifyable information, such as names or email addresses -3. Replace the date-time information to only show the date in the format YYYY-mm-dd -4. Replace all swear words with the following emoji: "😤" -""" -instructions_4 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Replace names in [] with "A", for Agent, and "C", for Client, respectively -2. Replace any other personally identifyable information, such as names or email addresses -3. Replace the date-time information to only show the date in the format YYYY-mm-dd -4. Replace all swear words with the following emoji: "😤" - -Here is some example output in the expected format: - -2021-09-29: ----------------------------------------------- -Agent: How can I assist you today? -Client: I CAN'T GET THIS 😤 THING TO TURN ON!! - - -2022-02-24: ----------------------------------------------- -Agent: Good morning! How can I help you today? -Client: Could you help me with applying my coupon code? -""" -instructions_5 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Replace names in [] with "A", for Agent, and "C", for Client, respectively -2. Replace any other personally identifyable information, such as names or email addresses -3. Replace the date-time information to only show the date in the format YYYY-mm-dd -4. Classify the sentiment of the client's responses in the conversation with "🔥" for negative and "✅" for positive -5. Replace all swear words with the following emoji: "😤" - -Here is some example output in the expected format: - -🔥 2021-09-29: ----------------------------------------------- -A: How can I assist you today? -C: I CAN'T GET THIS 😤 THING TO TURN ON!! - - -✅ 2022-02-24: ----------------------------------------------- -A: Good morning! How can I help you today? -C: Could you help me with applying my coupon code? -""" -instructions_6 = """ -Sanitize the text provided in >>>CONTENT<<< in multiple steps: - -1. Replace names in [] with "A", for Agent, and "C", for Client, respectively -2. Replace any other personally identifyable information, such as names or email addresses -3. Replace the date-time information to only show the date in the format YYYY-mm-dd -4. Classify the sentiment of the client's responses in the conversation as "negative" and "positive" -5. Replace all swear words with the following emoji: "😤" -6. Format the resulting text as JSON - -Here is some example output in the expected JSON format: - -```json -{ - "negative": [ - { - "date": "2021-09-29", - "conversation": [ - "A: How can I assist you today?", - "C: I CAN'T GET THIS 😤 THING TO TURN ON!!" - ] - }, - ] - "positive": [ - { - "date": "2022-02-24", - "conversation": [ - "A: Good morning! How can I help you today?", - "C: Could you help me with applying my coupon code?" - ] - }, - ] -} -``` -""" \ No newline at end of file diff --git a/prompt-engineering/support-chat.txt b/prompt-engineering/support-chat.txt deleted file mode 100644 index 5a3b3e9dd6..0000000000 --- a/prompt-engineering/support-chat.txt +++ /dev/null @@ -1,43 +0,0 @@ -[support_tom] 2022-08-24T10:02:23+00:00 : What can I help you with? -[johndoe] 2022-08-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT -[support_tom] 2022-08-24T10:03:30+00:00 : Are you sure it's not your caps lock? -[johndoe] 2022-08-24T10:04:03+00:00 : Blast! You're right! - -[support_amy] 2022-09-15T14:45:35+00:00 : Hello! How can I assist you today? -[greg_stone] 2022-09-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. -[support_amy] 2022-09-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? -[greg_stone] 2022-09-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! - -[support_louis] 2022-10-05T09:22:12+00:00 : Hi, how can I help you today? -[karen_w] 2022-10-05T09:23:47+00:00 : MY BLASTED ORDER STILL HASN'T ARRIVED AND IT'S BEEN A WEEK!!! -[support_louis] 2022-10-05T09:24:15+00:00 : I'm sorry to hear that, Karen. Let's look into this issue. -[support_louis] 2022-10-05T09:25:35+00:00: Can you please provide your order number so I can check the status for you? -[karen_w] 2022-10-05T09:26:12+00:00: Fine, it's 9876543. -[support_louis] 2022-10-05T09:26:45+00:00: Thank you, Karen. I see there was a delay in shipping. Your order will arrive within the next 2 days. - -[support_jenny] 2022-09-18T17:35:28+00:00: Hello! How can I help you today? -[alex_harper] 2022-09-18T17:36:05+00:00: I accidentally placed an order twice, can you help me cancel one? -[support_jenny] 2022-09-18T17:36:25+00:00: Sure, Alex. Can you give me the order number you'd like to cancel? -[alex_harper] 2022-09-18T17:36:55+00:00: Yes, it's 1122334. Thank you! -[support_jenny] 2022-09-18T17:37:32+00:00: I've successfully canceled order number 1122334. You will receive a confirmation email shortly. - -[support_ben] 2022-09-29T11:51:45+00:00: Good morning, what can I assist you with today? -[lisa_beck] 2022-09-29T11:52:20+00:00: Hi there, I received a damaged item in my order. Can you help me return it? -[support_ben] 2022-09-29T11:52:45+00:00: I'm sorry to hear that, Lisa. Can you provide your order number and specify the damaged item? -[lisa_beck] 2022-09-29T11:53:22+00:00: Sure, order number is 5566778 and the damaged item is a coffee mug. - -[support_rachel] 2022-10-04T08:16:37+00:00: How can I help you today? -[mike_t] 2022-10-04T08:17:15+00:00: My coupon code isn't working at checkout. Can you help? -[support_rachel] 2022-10-04T08:17:38+00:00: Of course, Mike. Please provide the coupon code you're trying to use. -[mike_t] 2022-10-04T08:18:02+00:00: It's "HELLO10". -[support_rachel] 2022-10-04T08:18:37+00:00: I've checked the code, and it seems to have expired. I apologize for the inconvenience. Here's a new code for you to use: "WELCOME15". - -[support_vincent] 2022-09-15T20:43:55+00:00: Good evening! How may I assist you? -[sara_winters] 2022-09-15T20:44:30+00:00: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. -[support_vincent] 2022-09-15T20:44:52+00:00: I'm sorry to hear that, Sara. Let me help you. Can you please confirm your email address? -[sara_winters] 2022-09-15T20:45:25+00:00: Sure, it's sara.winters@email.com. - -[support_david] 2022-09-24T16:28:43+00:00: Welcome! What can I do for you today? -[jane_d] 2022-09-24T16:29:16+00:00: Hi, I need to change my delivery address for my recent order. -[support_david] 2022-09-24T16:29:43+00:00: Alright, Jane. Please provide your order number. -[jane_d] 2022-09-24T16:30:11+00:00: It's 3344556. Thanks for your help! \ No newline at end of file diff --git a/prompt-engineering/testing.txt b/prompt-engineering/testing.txt new file mode 100644 index 0000000000..04233b0d8e --- /dev/null +++ b/prompt-engineering/testing.txt @@ -0,0 +1,44 @@ +[support_johnny] 2023-07-15T14:40:37+00:00: Hello! What can I help you with today? +[becky_h] 2023-07-15T14:41:05+00:00: Hey, my promo code isn't applying the discount in my cart. +[support_johnny] 2023-07-15T14:41:30+00:00: My apologies for the trouble, Becky. Could you tell me the promo code you're trying to use? +[becky_h] 2023-07-15T14:41:55+00:00: It's "SAVE20". + +[support_peter] 2023-07-24T10:56:43+00:00: Good day! How can I help you? +[lucy_g] 2023-07-24T10:57:12+00:00: Hi "Peter", I can't update my darn credit card information. Do you want my darn money or not? +[support_peter] 2023-07-24T10:57:38+00:00: I'm sorry for the inconvenience, Lucy. Can you please confirm your account's email? +[lucy_g] 2023-07-24T10:58:06+00:00: Sure, you have all my darn data already anyways. It's lucy.g@email.com. + +[support_luke] 2023-08-13T11:34:02+00:00: Good morning! How may I assist you? +[anna_s] 2023-08-13T11:34:30+00:00: Hello, I'm having a problem with my mobile app, it keeps crashing. +[support_luke] 2023-08-13T11:34:58+00:00: I'm sorry to hear that, Anna. Could you tell me what device you're using? +[anna_s] 2023-08-13T11:35:22+00:00: I have an iPhone 11. + +[support_lisa] 2023-08-30T20:38:00+00:00: Good evening! How may I assist you today? +[steve_b] 2023-08-30T20:38:30+00:00: Hi Lisa, I've forgotten my friggin password and I can't login into my account. +[support_lisa] 2023-08-30T20:38:55+00:00: I'm sorry for the trouble, Steve. Could you confirm your email address so we can reset your password? +[steve_b] 2023-08-30T20:39:22+00:00: Definitely, it's steve.b@email.com. + +[support_william] 2023-09-01T08:22:40+00:00: Hello! How can I assist you this morning? +[emma_t] 2023-09-01T08:23:05+00:00: Hi, I'm trying to make a purchase but it's not going through. +[support_william] 2023-09-01T08:23:33+00:00: I'm sorry to hear that, Emma. Can you tell me what error message you're receiving? +[emma_t] 2023-09-01T08:24:00+00:00: It's saying "Payment method not valid". + +[support_ben] 2023-10-11T09:44:22+00:00: Good morning! How may I assist you? +[susan_p] 2023-10-11T09:44:55+00:00: Hello, I'd like to know the status of my order. +[support_ben] 2023-10-11T09:45:15+00:00: Of course, Susan. Could you please provide me with the order number? +[susan_p] 2023-10-11T09:45:40+00:00: It's 717171. + +[support_ricky] 2023-10-19T17:38:45+00:00: Welcome! How can I assist you right now? +[linda_a] 2023-10-19T17:39:10+00:00: Fudge! There's no option to change my profile picture. What kind of crikey joint are you running? +[support_ricky] 2023-10-19T17:39:32+00:00: Let me help you with this, Linda. Are you trying to update it from the mobile app or the website? +[linda_a] 2023-10-19T17:39:57+00:00: I'm using the darn website + +[support_tony] 2023-10-29T16:00:32+00:00: Hello! What can I help you with today? +[mark_s] 2023-10-29T16:01:00+00:00: Hi Tony, I was charged twice for my last order. +[support_tony] 2023-10-29T16:01:22+00:00: I'm sorry to hear that, Mark. Could you share your order number so I can look into this for you? +[mark_s] 2023-10-29T16:01:46+00:00: Sure, it's 333666. + +[support_emily] 2023-11-08T14:34:12+00:00: How can I help you today? +[nina_z] 2023-11-08T14:34:36+00:00: Hi, I made an order last week but I need to change the sizing. +[support_emily] 2023-11-08T14:34:58+00:00: Certainly, Nina. Could you provide me the order number? +[nina_z] 2023-11-08T14:35:26+00:00: Yes, it's 444888. Thanks! \ No newline at end of file diff --git a/prompt-engineering/validation.txt b/prompt-engineering/validation.txt new file mode 100644 index 0000000000..5c2326c968 --- /dev/null +++ b/prompt-engineering/validation.txt @@ -0,0 +1,43 @@ +[support_tom] 2023-07-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2023-07-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2023-07-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2023-07-24T10:04:03+00:00 : Blast! You're right! + +[support_amy] 2023-06-15T14:45:35+00:00 : Hello! How can I assist you today? +[greg_stone] 2023-06-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. +[support_amy] 2023-06-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? +[greg_stone] 2023-06-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! + +[support_louis] 2023-05-05T09:22:12+00:00 : Hi, how can I help you today? +[karen_w] 2023-05-05T09:23:47+00:00 : MY BLASTED ORDER STILL HASN'T ARRIVED AND IT'S BEEN A WEEK!!! +[support_louis] 2023-05-05T09:24:15+00:00 : I'm sorry to hear that, Karen. Let's look into this issue. +[support_louis] 2023-05-05T09:25:35+00:00: Can you please provide your order number so I can check the status for you? +[karen_w] 2023-05-05T09:26:12+00:00: Fine, it's 9876543. +[support_louis] 2023-05-05T09:26:45+00:00: Thank you, Karen. I see there was a delay in shipping. Your order will arrive within the next 2 days. + +[support_jenny] 2023-06-18T17:35:28+00:00: Hello! How can I help you today? +[alex_harper] 2023-06-18T17:36:05+00:00: I accidentally placed an order twice, can you help me cancel one? +[support_jenny] 2023-06-18T17:36:25+00:00: Sure, Alex. Can you give me the order number you'd like to cancel? +[alex_harper] 2023-06-18T17:36:55+00:00: Yes, it's 1122334. Thank you! +[support_jenny] 2023-06-18T17:37:32+00:00: I've successfully canceled order number 1122334. You will receive a confirmation email shortly. + +[support_ben] 2023-06-29T11:51:45+00:00: Good morning, what can I assist you with today? +[lisa_beck] 2023-06-29T11:52:20+00:00: Hi there, I received a damaged item in my order. Can you help me return it? +[support_ben] 2023-06-29T11:52:45+00:00: I'm sorry to hear that, Lisa. Can you provide your order number and specify the damaged item? +[lisa_beck] 2023-06-29T11:53:22+00:00: Sure, order number is 5566778 and the damaged item is a coffee mug. + +[support_rachel] 2023-05-04T08:16:37+00:00: How can I help you today? +[mike_t] 2023-05-04T08:17:15+00:00: My coupon code isn't working at checkout. Can you help? +[support_rachel] 2023-05-04T08:17:38+00:00: Of course, Mike. Please provide the coupon code you're trying to use. +[mike_t] 2023-05-04T08:18:02+00:00: It's "HELLO10". +[support_rachel] 2023-05-04T08:18:37+00:00: I've checked the code, and it seems to have expired. I apologize for the inconvenience. Here's a new code for you to use: "WELCOME15". + +[support_vincent] 2023-06-15T20:43:55+00:00: Good evening! How may I assist you? +[sara_winters] 2023-06-15T20:44:30+00:00: Hi there, I'm having trouble logging into my account. I've tried resetting my password, but it's not working. +[support_vincent] 2023-06-15T20:44:52+00:00: I'm sorry to hear that, Sara. Let me help you. Can you please confirm your email address? +[sara_winters] 2023-06-15T20:45:25+00:00: Sure, it's sara.winters@email.com. + +[support_david] 2023-06-24T16:28:43+00:00: Welcome! What can I do for you today? +[jane_d] 2023-06-24T16:29:16+00:00: Hi, I need to change my delivery address for my recent order. +[support_david] 2023-06-24T16:29:43+00:00: Alright, Jane. Please provide your order number. +[jane_d] 2023-06-24T16:30:11+00:00: It's 3344556. Thanks for your help! \ No newline at end of file From 38717432aaa6d559322fb40670d67774a745b8d6 Mon Sep 17 00:00:00 2001 From: martin-martin Date: Wed, 19 Jul 2023 13:27:12 +0200 Subject: [PATCH 06/16] Fix formatting --- prompt-engineering/app.py | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/prompt-engineering/app.py b/prompt-engineering/app.py index 5b51266851..03b0488d1f 100644 --- a/prompt-engineering/app.py +++ b/prompt-engineering/app.py @@ -69,33 +69,21 @@ def _read_input_text(input_file: str) -> str: def _assemble_prompt(content: str, settings: dict) -> str: """Combine all messages into a single prompt.""" - prompt = f">>>>>\n{content}\n<<<<<\n\n" + settings["prompts"]["instructions"] + prompt = ( + f">>>>>\n{content}\n<<<<<\n\n" + settings["prompts"]["instructions"] + ) return prompt -# def _assemble_messages(content: str, settings: dict) -> List[dict]: -# """Combine all messages into a well-formatted dictionary.""" -# messages = [ -# {"role": "system", "content": settings["prompts"]["role_prompt"]}, -# {"role": "user", "content": f">>>>>\n{content}\n<<<<<\n\n"}, -# {"role": "user", "content": settings["prompts"]["instructions"]}, -# ] -# return messages - def _assemble_messages(content: str, settings: dict) -> List[dict]: """Combine all messages into a well-formatted dictionary.""" messages = [ {"role": "system", "content": settings["prompts"]["role_prompt"]}, - {"role": "user", "content": settings["prompts"]["negative_example"]}, - {"role": "system", "content": settings["prompts"]["negative_reasoning"]}, - {"role": "assistant", "content": settings["prompts"]["negative_output"]}, - {"role": "user", "content": settings["prompts"]["positive_example"]}, - {"role": "system", "content": settings["prompts"]["positive_reasoning"]}, - {"role": "assistant", "content": settings["prompts"]["positive_output"]}, {"role": "user", "content": f">>>>>\n{content}\n<<<<<\n\n"}, {"role": "user", "content": settings["prompts"]["instructions"]}, ] return messages + if __name__ == "__main__": print(main()) From c1036d469a7c19063211c879a294531c1bca519d Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 21 Jul 2023 16:03:50 +0200 Subject: [PATCH 07/16] Refactor code, update settings file Co-authored-by: Bartosz --- prompt-engineering/app.py | 145 ++++++++++-------- .../{validation.txt => chats.txt} | 0 prompt-engineering/final-settings.toml | 16 +- ...zed-validation.txt => sanitized-chats.txt} | 0 ...esting.txt => sanitized-testing-chats.txt} | 0 prompt-engineering/settings.toml | 23 ++- .../{testing.txt => testing-chats.txt} | 0 7 files changed, 112 insertions(+), 72 deletions(-) rename prompt-engineering/{validation.txt => chats.txt} (100%) rename prompt-engineering/{sanitized-validation.txt => sanitized-chats.txt} (100%) rename prompt-engineering/{sanitized-testing.txt => sanitized-testing-chats.txt} (100%) rename prompt-engineering/{testing.txt => testing-chats.txt} (100%) diff --git a/prompt-engineering/app.py b/prompt-engineering/app.py index 03b0488d1f..f42a2a77ca 100644 --- a/prompt-engineering/app.py +++ b/prompt-engineering/app.py @@ -1,8 +1,7 @@ +import argparse import os -import sys import tomllib from pathlib import Path -from typing import List import openai @@ -10,80 +9,104 @@ openai.api_key = os.getenv("OPENAI_API_KEY") -def main() -> str: - try: - file_path = sys.argv[1] - except IndexError: - file_path = "training.txt" - settings = _load_settings() - if settings["general"]["model"] in settings["general"]["chat_models"]: - return request_response(file_path) - return request_completion(file_path) - - -def request_completion(file: str) -> str: - """Assemble all text into a prompt and send a /completion API request.""" - settings = _load_settings() - content = _read_input_text(file) - prompt = _assemble_prompt(content, settings) - +class Settings(dict): + """Handle loading and accessing application settings from file.""" + + @classmethod + def load(cls, path) -> "Settings": + """Load TOML settings file and pass it to class constuctor.""" + with path.open("rb") as file: + return cls(tomllib.load(file)) + + def __init__(self, *args, **kwargs) -> None: + """Add general settings and prompts as instance attributes.""" + super().__init__(*args, **kwargs) + # Settings + self.chat_models = self["general"]["chat_models"] + self.model = self["general"]["model"] + self.max_tokens = self["general"]["max_tokens"] + self.temperature = self["general"]["temperature"] + self.model_supports_chat_completions = self.model in self.chat_models + # Prompts + self.instruction_prompt = self["prompts"]["instruction_prompt"] + self.role_prompt = self["prompts"]["role_prompt"] + self.positive_example = self["prompts"]["positive_example"] + self.positive_reasoning = self["prompts"]["positive_reasoning"] + self.positive_output = self["prompts"]["positive_output"] + self.negative_example = self["prompts"]["negative_example"] + self.negative_reasoning = self["prompts"]["negative_reasoning"] + self.negative_output = self["prompts"]["negative_output"] + + +def parse_args() -> argparse.Namespace: + """Parse command-line input.""" + parser = argparse.ArgumentParser() + parser.add_argument("file_path", type=Path, help="Path to the input file") + return parser.parse_args() + + +def main(args: argparse.Namespace) -> None: + file_content = args.file_path.read_text("utf-8") + settings = Settings.load(Path("settings.toml")) + if settings.model_supports_chat_completions: + print(get_chat_completion(file_content, settings)) + else: + print(get_completion(file_content, settings)) + + +def get_completion(content: str, settings: Settings) -> str: + """Send a request to the /completions endpoint.""" response = openai.Completion.create( - model=settings["general"]["model"], - prompt=prompt, - max_tokens=settings["general"]["max_tokens"], - temperature=settings["general"]["temperature"], + model=settings.model, + prompt=assemble_prompt(content, settings), + max_tokens=settings.max_tokens, + temperature=settings.temperature, ) return response["choices"][0]["text"] -def request_response(file: str) -> str: - """Assemble all text into a prompt and send a /chat API request.""" - settings = _load_settings() - content = _read_input_text(file) - messages = _assemble_messages(content, settings) - +def get_chat_completion(content: str, settings: Settings) -> str: + """Send a request to the /chat/completions endpoint.""" response = openai.ChatCompletion.create( - model=settings["general"]["model"], - messages=messages, - # max_tokens defaults to inf - temperature=settings["general"]["temperature"], + model=settings.model, + messages=assemble_chat_messages(content, settings), + temperature=settings.temperature, ) return response["choices"][0]["message"]["content"] -def _load_settings() -> dict: - """Load the settings file.""" - settings_path = Path.cwd() / "settings.toml" - with settings_path.open("rb") as settings_file: - settings = tomllib.load(settings_file) - return settings - - -def _read_input_text(input_file: str) -> str: - """Read the text content from a file.""" - input_file_path = Path(input_file) - with input_file_path.open("r") as file: - content = file.read() - return content - - -def _assemble_prompt(content: str, settings: dict) -> str: - """Combine all messages into a single prompt.""" - prompt = ( - f">>>>>\n{content}\n<<<<<\n\n" + settings["prompts"]["instructions"] - ) - return prompt +def assemble_prompt(content: str, settings: Settings) -> str: + """Combine all text input into a single prompt.""" + instruction_prompt = settings["prompts"]["instruction_prompt"] + return f">>>>>\n{content}\n<<<<<\n\n" + instruction_prompt -def _assemble_messages(content: str, settings: dict) -> List[dict]: +def assemble_chat_messages(content: str, settings: Settings) -> list[dict]: """Combine all messages into a well-formatted dictionary.""" - messages = [ + return [ {"role": "system", "content": settings["prompts"]["role_prompt"]}, - {"role": "user", "content": f">>>>>\n{content}\n<<<<<\n\n"}, - {"role": "user", "content": settings["prompts"]["instructions"]}, + {"role": "user", "content": settings["prompts"]["negative_example"]}, + { + "role": "system", + "content": settings["prompts"]["negative_reasoning"], + }, + { + "role": "assistant", + "content": settings["prompts"]["negative_output"], + }, + {"role": "user", "content": settings["prompts"]["positive_example"]}, + { + "role": "system", + "content": settings["prompts"]["positive_reasoning"], + }, + { + "role": "assistant", + "content": settings["prompts"]["positive_output"], + }, + {"role": "user", "content": f">>>>>\n{content}\n<<<<<"}, + {"role": "user", "content": settings["prompts"]["instruction_prompt"]}, ] - return messages if __name__ == "__main__": - print(main()) + main(parse_args()) diff --git a/prompt-engineering/validation.txt b/prompt-engineering/chats.txt similarity index 100% rename from prompt-engineering/validation.txt rename to prompt-engineering/chats.txt diff --git a/prompt-engineering/final-settings.toml b/prompt-engineering/final-settings.toml index 22f5e35add..8c8368898d 100644 --- a/prompt-engineering/final-settings.toml +++ b/prompt-engineering/final-settings.toml @@ -5,7 +5,11 @@ max_tokens = 100 temperature = 0 [prompts] -role_prompt = """You are an thoroughly trained machine learning model that is an expert at sentiment classification. +instruction_prompt = """ +Classify the sentiment of each conversation in >>>>>CONTENT<<<<< as "negative" and "positive". +Return the output as valid JSON. +""" +role_prompt = """You are a thoroughly trained machine learning model that is an expert at sentiment classification. You diligently complete tasks as instructed. You never make up any information that isn't there.""" positive_example = """ [Agent] 2023-06-15 : Hello! How can I assist you today? @@ -13,7 +17,8 @@ positive_example = """ [Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? [Customer] 2023-06-15 : It's ********. Thanks for helping me out! """ -positive_reasoning = "The customer does not use any swear words or 😤 emoji and does not seem aggravated or angry, so the sentiment is positive." +positive_reasoning = """The customer does not use any swear words or 😤 emoji +and does not seem aggravated or angry, so the sentiment is positive.""" positive_output = """ { "positive": [ @@ -35,7 +40,8 @@ negative_example = """ [Agent] 2023-07-24 : Are you sure it's not your caps lock? [Customer] 2023-07-24 : 😤! You're right! """ -negative_reasoning = "The customer uses the 😤 emoji and seems aggravated, so the sentiment is negative." +negative_reasoning = """The customer uses the 😤 emoji and seems aggravated, +so the sentiment is negative.""" negative_output = """ { "negative": [ @@ -51,7 +57,3 @@ negative_output = """ ] } """ -instructions = """ -Classify the sentiment of each conversation in >>>>>CONTENT<<<<< as "negative" and "positive". -Return the output as valid JSON. -""" diff --git a/prompt-engineering/sanitized-validation.txt b/prompt-engineering/sanitized-chats.txt similarity index 100% rename from prompt-engineering/sanitized-validation.txt rename to prompt-engineering/sanitized-chats.txt diff --git a/prompt-engineering/sanitized-testing.txt b/prompt-engineering/sanitized-testing-chats.txt similarity index 100% rename from prompt-engineering/sanitized-testing.txt rename to prompt-engineering/sanitized-testing-chats.txt diff --git a/prompt-engineering/settings.toml b/prompt-engineering/settings.toml index e932ce6bc7..aedae77ffe 100644 --- a/prompt-engineering/settings.toml +++ b/prompt-engineering/settings.toml @@ -1,10 +1,25 @@ [general] -chat_models = ["gpt-3.5", "gpt-3.5-turbo", "gpt-4"] +chat_models = ["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4"] model = "text-davinci-003" -max_tokens = 2200 +max_tokens = 2100 temperature = 0 [prompts] -instructions = """ -Remove personally identifiable information, only show the date, and replace all swear words with "😤" +instruction_prompt = """ +Remove personally identifiable information, only show the date, +and replace all swear words with "😤" +""" +role_prompt = """ +""" +positive_example = """ +""" +positive_reasoning = """ +""" +positive_output = """ +""" +negative_example = """ +""" +negative_reasoning = """ +""" +negative_output = """ """ diff --git a/prompt-engineering/testing.txt b/prompt-engineering/testing-chats.txt similarity index 100% rename from prompt-engineering/testing.txt rename to prompt-engineering/testing-chats.txt From b3cd32e49a48b642bf577d7b4b958059696c33ee Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 21 Jul 2023 23:31:39 +0200 Subject: [PATCH 08/16] Add prompts to README --- prompt-engineering/README.md | 499 ++++++++++++++++++++++++++++++++++- 1 file changed, 495 insertions(+), 4 deletions(-) diff --git a/prompt-engineering/README.md b/prompt-engineering/README.md index 144868f805..16376bce0b 100644 --- a/prompt-engineering/README.md +++ b/prompt-engineering/README.md @@ -25,13 +25,504 @@ Create and activate a [virtual environment](https://realpython.com/python-virtua Read support chat conversations from a file, sanitize the text, classify by sentiment, and format the output as JSON: ```bash -(venv) $ python app.py testing.txt +(venv) $ python app.py chats.txt ``` You can provide a different file as input file. -## Prompts And Output +## Prompts -Change the prompts used in the script by editing the entries in `settings.toml`. +Change the prompts used in the script by editing the entries in `settings.toml`. The repository also contains a second settings file, `final-settings.toml`, which contains the prompts that you use in the final section. -In the tutorial, you learn how developing the prompt can give you better results based on a couple of prompting techniques. +While working through the tutorial, you'll learn how iteratively developing the prompt can give you better results based on a couple of prompting techniques. Here you'll find a collection of all the prompts you use throughout the tutorial: + +### Zero-shot Prompting + +```toml +instruction_prompt = """ +Remove personally identifiable information, only show the date, +and replace all swear words with "😤" +""" +``` + +### One-shot Prompting + +```toml +instruction_prompt = """ +Remove personally identifiable information, only show the date, +and replace all swear words with "😤" + +Example Input: +[support_tom] 2023-07-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2023-07-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2023-07-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2023-07-24T10:04:03+00:00 : Blast! You're right! + +Example Output: +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! +""" +``` + +# Few-shot Prompting + +```toml +instruction_prompt = """ +Remove personally identifiable information, only show the date, +and replace all swear words with "😤" + +Example Inputs: +[support_tom] 2023-07-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2023-07-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2023-07-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2023-07-24T10:04:03+00:00 : Blast! You're right! + +[support_amy] 2023-06-15T14:45:35+00:00 : Hello! How can I assist you today? +[greg_stone] 2023-06-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. +[support_amy] 2023-06-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? +[greg_stone] 2023-06-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! + +Example Outputs: +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! +""" +``` + +### Delimiters + +```toml +instruction_prompt = """Remove personally identifiable information +from >>>>>CONTENT<<<<<, only show the date, +and replace all swear words with "😤" + +#### START EXAMPLES + +------ Example Inputs ------ +[support_tom] 2023-07-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2023-07-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2023-07-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2023-07-24T10:04:03+00:00 : Blast! You're right! + +[support_amy] 2023-06-15T14:45:35+00:00 : Hello! How can I assist you today? +[greg_stone] 2023-06-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. +[support_amy] 2023-06-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? +[greg_stone] 2023-06-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! + +------ Example Outputs ------ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! + +#### END EXAMPLES +""" +``` + +### Numbered Steps + +```toml +instruction_prompt = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace personally identifiable information (customer names, agent names, email addresses, order numbers) with `********` +2. Replace names in [] with "Agent" and "Client", respectively +3. Replace the date-time information to only show the date in the format YYYY-mm-dd +4. Replace all swear words with the following emoji: "😤" + +#### START EXAMPLES + +------ Example Inputs ------ +[support_tom] 2023-07-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2023-07-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2023-07-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2023-07-24T10:04:03+00:00 : Blast! You're right! + +[support_amy] 2023-06-15T14:45:35+00:00 : Hello! How can I assist you today? +[greg_stone] 2023-06-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. +[support_amy] 2023-06-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? +[greg_stone] 2023-06-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! + +------ Example Outputs ------ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! + +#### END EXAMPLES +""" +``` + +### Increased Specificity + +```toml +instruction_prompt = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace personally identifiable information with `********` +2. Delete all names +3. Replace email addresses and order numbers with `********` +4. Replace names in [] with "Agent" and "Client", respectively +5. Replace the date-time information to only show the date in the format YYYY-mm-dd +6. Replace all swear words with the following emoji: "😤" + +#### START EXAMPLES + +------ Example Inputs ------ +[support_tom] 2023-07-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2023-07-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2023-07-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2023-07-24T10:04:03+00:00 : Blast! You're right! + +[support_amy] 2023-06-15T14:45:35+00:00 : Hello! How can I assist you today? +[greg_stone] 2023-06-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. +[support_amy] 2023-06-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? +[greg_stone] 2023-06-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! + +------ Example Outputs ------ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! + +#### END EXAMPLES +""" +``` + +### Role Prompts + +```toml +instruction_prompt = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace personally identifiable information with `********` +2. Delete all names +3. Replace email addresses and order numbers with `********` +4. Replace names in [] with "Agent" and "Client", respectively +5. Replace the date-time information to only show the date in the format YYYY-mm-dd +6. Replace all swear words with the following emoji: "😤" + +#### START EXAMPLES + +------ Example Inputs ------ +[support_tom] 2023-07-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2023-07-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2023-07-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2023-07-24T10:04:03+00:00 : Blast! You're right! + +[support_amy] 2023-06-15T14:45:35+00:00 : Hello! How can I assist you today? +[greg_stone] 2023-06-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. +[support_amy] 2023-06-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? +[greg_stone] 2023-06-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! + +------ Example Outputs ------ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! + +#### END EXAMPLES +""" +role_prompt = """You are a 16th century villain poet who treats +customers with nothing but contempt. +Rephrase every line spoken by an Agent with your unique voice.""" +``` + + +```toml +instruction_prompt = """ +Sanitize the text provided in >>>CONTENT<<< in multiple steps: + +1. Replace personally identifiable information with `********` +2. Delete all names +3. Replace email addresses and order numbers with `********` +4. Replace names in [] with "Agent" and "Client", respectively +5. Replace the date-time information to only show the date in the format YYYY-mm-dd +6. Replace all swear words with the following emoji: "😤" + +#### START EXAMPLES + +------ Example Inputs ------ +[support_tom] 2023-07-24T10:02:23+00:00 : What can I help you with? +[johndoe] 2023-07-24T10:03:15+00:00 : I CAN'T CONNECT TO MY BLASTED ACCOUNT +[support_tom] 2023-07-24T10:03:30+00:00 : Are you sure it's not your caps lock? +[johndoe] 2023-07-24T10:04:03+00:00 : Blast! You're right! + +[support_amy] 2023-06-15T14:45:35+00:00 : Hello! How can I assist you today? +[greg_stone] 2023-06-15T14:46:20+00:00 : I can't seem to find the download link for my purchased software. +[support_amy] 2023-06-15T14:47:01+00:00 : No problem, Greg. Let me find that for you. Can you please provide your order number? +[greg_stone] 2023-06-15T14:47:38+00:00 : It's 1245789. Thanks for helping me out! + +------ Example Outputs ------ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! + +#### END EXAMPLES +""" +role_prompt = """You are a helpful assistant with a vast knowledge +of customer chat conversations. +You diligently complete tasks as instructed. +You never make up any information that isn't there.""" +``` + +### Sentiment Classification + +```toml +instruction_prompt = """ +Classify the sentiment of each conversation in >>>>>CONTENT<<<<< +with "🔥" for negative and "✅" for positive: + +#### START EXAMPLES + +------ Example Inputs ------ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! + +------ Example Outputs ------ +🔥 +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +✅ +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! + +#### END EXAMPLES +""" +role_prompt = """You are a thoroughly trained machine learning +model that is an expert at sentiment classification. +You diligently complete tasks as instructed. +You never make up any information that isn't there.""" +``` + +### Zero-shot CoT + +```toml +instruction_prompt = """ +Classify the sentiment of each conversation in >>>>>CONTENT<<<<< +with "🔥" for negative and "✅" for positive. + +Follow these steps when classifying the conversations: +1. Does the customer use swear words or 😤? +2. Does the customer seem aggravated or angry? + +If you answer "Yes" to one of the above questions, +then classify the conversation as negative with "🔥". +Otherwise classify the conversation as positive with "✅". + +Let's think step by step +""" +role_prompt = """You are an thoroughly trained machine learning +model that is an expert at sentiment classification. +You diligently complete tasks as instructed. +You never make up any information that isn't there.""" +``` + +### Chain-of-Thought (CoT) + +```toml +instruction_prompt = """ +Classify the sentiment of each conversation in >>>>>CONTENT<<<<< +with "🔥" for negative and "✅" for positive. + +#### START EXAMPLES + +------ Example Inputs ------ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! +The customer uses the 😤 emoji and seems aggravated, so the sentiment is negative. 🔥 + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! +The customer does not use any swear words or 😤 emoji and does not seem aggravated or angry, so the sentiment is positive. ✅ + +------ Example Outputs ------ +🔥 +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! + +✅ +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! + +#### END EXAMPLES +""" +role_prompt = """You are an thoroughly trained machine learning +model that is an expert at sentiment classification. +You diligently complete tasks as instructed. +You never make up any information that isn't there.""" +``` + +### Structured Output + +```toml +instruction_prompt = """ +Classify the sentiment of each conversation in >>>>>CONTENT<<<<< +as "negative" and "positive". +Return the output as valid JSON. + +#### START EXAMPLES + +------ Example Input ------ + +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! +The customer uses the 😤 emoji and seems aggravated, so the sentiment is negative. + +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! +The customer does not use any swear words or 😤 emoji and does not seem aggravated or angry, so the sentiment is positive. + +------ Example Output ------ + +{ + "negative": [ + { + "date": "2023-07-24", + "conversation": [ + "A: What can I help you with?", + "C: I CAN'T CONNECT TO MY 😤 ACCOUNT", + "A: Are you sure it's not your caps lock?", + "C: 😤! You're right!" + ] + } + ], + "positive": [ + { + "date": "2023-06-15", + "conversation": [ + "A: Hello! How can I assist you today?", + "C: I can't seem to find the download link for my purchased software.", + "A: No problem, ********. Let me find that for you. Can you please provide your order number?", + "C: It's ********. Thanks for helping me out!" + ] + } + ] +} + +#### END EXAMPLES +""" +role_prompt = """You are an thoroughly trained machine learning +model that is an expert at sentiment classification. +You diligently complete tasks as instructed. +You never make up any information that isn't there.""" +``` + +### Labeled Conversations + +```toml +[prompts] +instruction_prompt = """ +Classify the sentiment of each conversation in >>>>>CONTENT<<<<< +as "negative" and "positive". +Return the output as valid JSON. +""" +role_prompt = """You are a thoroughly trained machine learning model +that is an expert at sentiment classification. +You diligently complete tasks as instructed. +You never make up any information that isn't there.""" +positive_example = """ +[Agent] 2023-06-15 : Hello! How can I assist you today? +[Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. +[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ********. Thanks for helping me out! +""" +positive_reasoning = """The customer does not use any swear words or 😤 emoji +and does not seem aggravated or angry, so the sentiment is positive.""" +positive_output = """ +{ + "positive": [ + { + "date": "2023-06-15", + "conversation": [ + "A: Hello! How can I assist you today?", + "C: I can't seem to find the download link for my purchased software.", + "A: No problem, ********. Let me find that for you. Can you please provide your order number?", + "C: It's ********. Thanks for helping me out!" + ] + } + ] +} +""" +negative_example = """ +[Agent] 2023-07-24 : What can I help you with? +[Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT +[Agent] 2023-07-24 : Are you sure it's not your caps lock? +[Customer] 2023-07-24 : 😤! You're right! +""" +negative_reasoning = """The customer uses the 😤 emoji and seems aggravated, +so the sentiment is negative.""" +negative_output = """ +{ + "negative": [ + { + "date": "2023-07-24", + "conversation": [ + "A: What can I help you with?", + "C: I CAN'T CONNECT TO MY 😤 ACCOUNT", + "A: Are you sure it's not your caps lock?", + "C: 😤! You're right!" + ] + } + ] +} +""" +``` From d496bc6b2b94fd7222a2e9dc51db17bfeb53815e Mon Sep 17 00:00:00 2001 From: martin-martin Date: Mon, 24 Jul 2023 09:57:54 +0200 Subject: [PATCH 09/16] Fix code, improve README and file naming Co-authored-by: Bartosz --- prompt-engineering/README.md | 39 ++++++++++++++++--- prompt-engineering/app.py | 31 +++++---------- ...inal-settings.toml => settings-final.toml} | 0 3 files changed, 43 insertions(+), 27 deletions(-) rename prompt-engineering/{final-settings.toml => settings-final.toml} (100%) diff --git a/prompt-engineering/README.md b/prompt-engineering/README.md index 16376bce0b..a40ace69c7 100644 --- a/prompt-engineering/README.md +++ b/prompt-engineering/README.md @@ -1,6 +1,6 @@ # Practical Prompt Engineering -This repository contains a practical example to showcase a few common prompt engineering techniques. It's the code base used in the [associated Real Python tutorial on prompt engineering](https://realpython.com/practical-prompt-engineering/). The project allows you to preprocess customer service chats using GPT-3 and GPT-4 using the OpenAI API. +This repository contains a practical example to showcase a few common prompt engineering techniques. It's the code base used in the associated Real Python tutorial on [practical prompt engineering](https://realpython.com/practical-prompt-engineering/). The project allows you to preprocess customer service chats using GPT-3.5 and GPT-4 using the OpenAI API. ## Setup @@ -28,17 +28,35 @@ Read support chat conversations from a file, sanitize the text, classify by sent (venv) $ python app.py chats.txt ``` -You can provide a different file as input file. +You can also provide a different file as your input file. + +## Files + +The repository contains the following files: + +- [LICENSE](LICENSE): License information +- [README.md](README.md): Information on the project and how to use it +- [app.py](app.py): Code logic +- [chats.txt](chats.txt): Customer support chats used for building few-shot examples +- [requirements.txt](requirements.txt): Project requirements +- [sanitized-chats.txt](sanitized-chats.txt): Sanitized version of `chats.txt` that's used for building few-shot examples for sentiment analysis +- [sanitized-testing-chats.txt](sanitized-testing-chats.txt): Sanitized version of `testing-chats.txt` that's used for testing the prompt used for sentiment analysis +- [settings.toml](settings.toml): Main settings file used for iteratively improving the prompts +- [final-settings.toml](final-settings.toml): Final state of the settings file at the end of the tutorial +- [testing-chats.txt](testing-chats.txt): Customer support chats used for testing the prompt on new data + +You can find more information about when and how to use the different files [in the tutorial](https://realpython.com/practical-prompt-engineering/). ## Prompts -Change the prompts used in the script by editing the entries in `settings.toml`. The repository also contains a second settings file, `final-settings.toml`, which contains the prompts that you use in the final section. +Change the prompts used in the script by editing the entries in [`settings.toml`](settings.toml). The repository also contains a second settings file, [`settings-final.toml`](settings-final.toml), which contains the prompts that you use in the [final section](https://realpython.com/practical-prompt-engineering/#improve-your-output-with-the-power-of-conversation) of the tutorial. -While working through the tutorial, you'll learn how iteratively developing the prompt can give you better results based on a couple of prompting techniques. Here you'll find a collection of all the prompts you use throughout the tutorial: +While working through the tutorial, you'll learn how to improve your text completions by iteratively developing the prompt. You'll make these changes to your prompt based on a couple of prompt engineering techniques. Here you'll find a collection of all the prompts that you use throughout the tutorial: ### Zero-shot Prompting ```toml +[prompts] instruction_prompt = """ Remove personally identifiable information, only show the date, and replace all swear words with "😤" @@ -48,6 +66,7 @@ and replace all swear words with "😤" ### One-shot Prompting ```toml +[prompts] instruction_prompt = """ Remove personally identifiable information, only show the date, and replace all swear words with "😤" @@ -66,9 +85,10 @@ Example Output: """ ``` -# Few-shot Prompting +### Few-shot Prompting ```toml +[prompts] instruction_prompt = """ Remove personally identifiable information, only show the date, and replace all swear words with "😤" @@ -100,6 +120,7 @@ Example Outputs: ### Delimiters ```toml +[prompts] instruction_prompt = """Remove personally identifiable information from >>>>>CONTENT<<<<<, only show the date, and replace all swear words with "😤" @@ -135,6 +156,7 @@ and replace all swear words with "😤" ### Numbered Steps ```toml +[prompts] instruction_prompt = """ Sanitize the text provided in >>>CONTENT<<< in multiple steps: @@ -174,6 +196,7 @@ Sanitize the text provided in >>>CONTENT<<< in multiple steps: ### Increased Specificity ```toml +[prompts] instruction_prompt = """ Sanitize the text provided in >>>CONTENT<<< in multiple steps: @@ -215,6 +238,7 @@ Sanitize the text provided in >>>CONTENT<<< in multiple steps: ### Role Prompts ```toml +[prompts] instruction_prompt = """ Sanitize the text provided in >>>CONTENT<<< in multiple steps: @@ -258,6 +282,7 @@ Rephrase every line spoken by an Agent with your unique voice.""" ```toml +[prompts] instruction_prompt = """ Sanitize the text provided in >>>CONTENT<<< in multiple steps: @@ -303,6 +328,7 @@ You never make up any information that isn't there.""" ### Sentiment Classification ```toml +[prompts] instruction_prompt = """ Classify the sentiment of each conversation in >>>>>CONTENT<<<<< with "🔥" for negative and "✅" for positive: @@ -344,6 +370,7 @@ You never make up any information that isn't there.""" ### Zero-shot CoT ```toml +[prompts] instruction_prompt = """ Classify the sentiment of each conversation in >>>>>CONTENT<<<<< with "🔥" for negative and "✅" for positive. @@ -367,6 +394,7 @@ You never make up any information that isn't there.""" ### Chain-of-Thought (CoT) ```toml +[prompts] instruction_prompt = """ Classify the sentiment of each conversation in >>>>>CONTENT<<<<< with "🔥" for negative and "✅" for positive. @@ -410,6 +438,7 @@ You never make up any information that isn't there.""" ### Structured Output ```toml +[prompts] instruction_prompt = """ Classify the sentiment of each conversation in >>>>>CONTENT<<<<< as "negative" and "positive". diff --git a/prompt-engineering/app.py b/prompt-engineering/app.py index f42a2a77ca..35cba5a0e4 100644 --- a/prompt-engineering/app.py +++ b/prompt-engineering/app.py @@ -77,34 +77,21 @@ def get_chat_completion(content: str, settings: Settings) -> str: def assemble_prompt(content: str, settings: Settings) -> str: """Combine all text input into a single prompt.""" - instruction_prompt = settings["prompts"]["instruction_prompt"] - return f">>>>>\n{content}\n<<<<<\n\n" + instruction_prompt + return f">>>>>\n{content}\n<<<<<\n\n" + settings.instruction_prompt def assemble_chat_messages(content: str, settings: Settings) -> list[dict]: """Combine all messages into a well-formatted dictionary.""" return [ - {"role": "system", "content": settings["prompts"]["role_prompt"]}, - {"role": "user", "content": settings["prompts"]["negative_example"]}, - { - "role": "system", - "content": settings["prompts"]["negative_reasoning"], - }, - { - "role": "assistant", - "content": settings["prompts"]["negative_output"], - }, - {"role": "user", "content": settings["prompts"]["positive_example"]}, - { - "role": "system", - "content": settings["prompts"]["positive_reasoning"], - }, - { - "role": "assistant", - "content": settings["prompts"]["positive_output"], - }, + {"role": "system", "content": settings.role_prompt}, + {"role": "user", "content": settings.negative_example}, + {"role": "system", "content": settings.negative_reasoning}, + {"role": "assistant", "content": settings.negative_output}, + {"role": "user", "content": settings.positive_example}, + {"role": "system", "content": settings.positive_reasoning}, + {"role": "assistant", "content": settings.positive_output}, {"role": "user", "content": f">>>>>\n{content}\n<<<<<"}, - {"role": "user", "content": settings["prompts"]["instruction_prompt"]}, + {"role": "user", "content": settings.instruction_prompt}, ] diff --git a/prompt-engineering/final-settings.toml b/prompt-engineering/settings-final.toml similarity index 100% rename from prompt-engineering/final-settings.toml rename to prompt-engineering/settings-final.toml From 3b6ca2531cced3f91710d592fff786cfad3b8525 Mon Sep 17 00:00:00 2001 From: KateFinegan <95366190+KateFinegan@users.noreply.github.com> Date: Fri, 28 Jul 2023 16:16:19 -0600 Subject: [PATCH 10/16] README LE --- prompt-engineering/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/prompt-engineering/README.md b/prompt-engineering/README.md index a40ace69c7..7e5ed753b9 100644 --- a/prompt-engineering/README.md +++ b/prompt-engineering/README.md @@ -1,6 +1,6 @@ -# Practical Prompt Engineering +# Prompt Engineering: A Practical Example -This repository contains a practical example to showcase a few common prompt engineering techniques. It's the code base used in the associated Real Python tutorial on [practical prompt engineering](https://realpython.com/practical-prompt-engineering/). The project allows you to preprocess customer service chats using GPT-3.5 and GPT-4 using the OpenAI API. +This repository contains a practical example to showcase a few common prompt engineering techniques. It's the codebase used in the associated Real Python tutorial on [practical prompt engineering](https://realpython.com/practical-prompt-engineering/). The project allows you to preprocess customer service chats using GPT-3.5 and GPT-4 using the OpenAI API. ## Setup @@ -51,9 +51,9 @@ You can find more information about when and how to use the different files [in Change the prompts used in the script by editing the entries in [`settings.toml`](settings.toml). The repository also contains a second settings file, [`settings-final.toml`](settings-final.toml), which contains the prompts that you use in the [final section](https://realpython.com/practical-prompt-engineering/#improve-your-output-with-the-power-of-conversation) of the tutorial. -While working through the tutorial, you'll learn how to improve your text completions by iteratively developing the prompt. You'll make these changes to your prompt based on a couple of prompt engineering techniques. Here you'll find a collection of all the prompts that you use throughout the tutorial: +While working through the tutorial, you'll learn how to improve your text completions by iteratively developing the prompt. You'll make these changes to your prompt based on a few prompt engineering techniques. Here you'll find a collection of all the prompts that you use throughout the tutorial: -### Zero-shot Prompting +### Zero-Shot Prompting ```toml [prompts] @@ -63,7 +63,7 @@ and replace all swear words with "😤" """ ``` -### One-shot Prompting +### One-Shot Prompting ```toml [prompts] @@ -85,7 +85,7 @@ Example Output: """ ``` -### Few-shot Prompting +### Few-Shot Prompting ```toml [prompts] From b40087b0929a903480bbde91d179c3356e259fd3 Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 1 Mar 2024 16:00:45 +0100 Subject: [PATCH 11/16] Update README file --- prompt-engineering/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/prompt-engineering/README.md b/prompt-engineering/README.md index 7e5ed753b9..23c208965c 100644 --- a/prompt-engineering/README.md +++ b/prompt-engineering/README.md @@ -20,6 +20,12 @@ Create and activate a [virtual environment](https://realpython.com/python-virtua (venv) $ python -m pip install openai ``` +Or, to make sure that you're using the same versions as shown in the tutorial, you can install from `requirements.txt` instead: + +```bash +(venv) $ python -m pip install -r requirements.txt +``` + ## Usage Read support chat conversations from a file, sanitize the text, classify by sentiment, and format the output as JSON: From 53b6a3dd5a5e18f36d6fe8f5bc9db11357c4dee7 Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 1 Mar 2024 16:01:01 +0100 Subject: [PATCH 12/16] Reduced app code --- prompt-engineering/app.py | 98 +++++++++++---------------------------- 1 file changed, 28 insertions(+), 70 deletions(-) diff --git a/prompt-engineering/app.py b/prompt-engineering/app.py index 35cba5a0e4..1dc6bddc9b 100644 --- a/prompt-engineering/app.py +++ b/prompt-engineering/app.py @@ -3,39 +3,15 @@ import tomllib from pathlib import Path -import openai +from openai import OpenAI # Authenticate -openai.api_key = os.getenv("OPENAI_API_KEY") +client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) - -class Settings(dict): - """Handle loading and accessing application settings from file.""" - - @classmethod - def load(cls, path) -> "Settings": - """Load TOML settings file and pass it to class constuctor.""" - with path.open("rb") as file: - return cls(tomllib.load(file)) - - def __init__(self, *args, **kwargs) -> None: - """Add general settings and prompts as instance attributes.""" - super().__init__(*args, **kwargs) - # Settings - self.chat_models = self["general"]["chat_models"] - self.model = self["general"]["model"] - self.max_tokens = self["general"]["max_tokens"] - self.temperature = self["general"]["temperature"] - self.model_supports_chat_completions = self.model in self.chat_models - # Prompts - self.instruction_prompt = self["prompts"]["instruction_prompt"] - self.role_prompt = self["prompts"]["role_prompt"] - self.positive_example = self["prompts"]["positive_example"] - self.positive_reasoning = self["prompts"]["positive_reasoning"] - self.positive_output = self["prompts"]["positive_output"] - self.negative_example = self["prompts"]["negative_example"] - self.negative_reasoning = self["prompts"]["negative_reasoning"] - self.negative_output = self["prompts"]["negative_output"] +# Load settings file +settings_path = Path("settings.toml") +with settings_path.open("rb") as settings_file: + SETTINGS = tomllib.load(settings_file) def parse_args() -> argparse.Namespace: @@ -47,52 +23,34 @@ def parse_args() -> argparse.Namespace: def main(args: argparse.Namespace) -> None: file_content = args.file_path.read_text("utf-8") - settings = Settings.load(Path("settings.toml")) - if settings.model_supports_chat_completions: - print(get_chat_completion(file_content, settings)) - else: - print(get_completion(file_content, settings)) - - -def get_completion(content: str, settings: Settings) -> str: - """Send a request to the /completions endpoint.""" - response = openai.Completion.create( - model=settings.model, - prompt=assemble_prompt(content, settings), - max_tokens=settings.max_tokens, - temperature=settings.temperature, - ) - return response["choices"][0]["text"] + print(get_chat_completion(file_content)) -def get_chat_completion(content: str, settings: Settings) -> str: +def get_chat_completion(content: str) -> str: """Send a request to the /chat/completions endpoint.""" - response = openai.ChatCompletion.create( - model=settings.model, - messages=assemble_chat_messages(content, settings), - temperature=settings.temperature, + response = client.chat.completions.create( + model=SETTINGS["general"]["model"], + messages=assemble_chat_messages(content), + temperature=SETTINGS["general"]["temperature"], + seed=12345, # Doesn't do anything for older models ) - return response["choices"][0]["message"]["content"] - - -def assemble_prompt(content: str, settings: Settings) -> str: - """Combine all text input into a single prompt.""" - return f">>>>>\n{content}\n<<<<<\n\n" + settings.instruction_prompt - - -def assemble_chat_messages(content: str, settings: Settings) -> list[dict]: - """Combine all messages into a well-formatted dictionary.""" - return [ - {"role": "system", "content": settings.role_prompt}, - {"role": "user", "content": settings.negative_example}, - {"role": "system", "content": settings.negative_reasoning}, - {"role": "assistant", "content": settings.negative_output}, - {"role": "user", "content": settings.positive_example}, - {"role": "system", "content": settings.positive_reasoning}, - {"role": "assistant", "content": settings.positive_output}, + return response.choices[0].message.content + + +def assemble_chat_messages(content: str) -> list[dict]: + """Combine all messages into a well-formatted list of dicts.""" + messages = [ + {"role": "system", "content": SETTINGS["prompts"]["role_prompt"]}, + {"role": "user", "content": SETTINGS["prompts"]["negative_example"]}, + {"role": "system", "content": SETTINGS["prompts"]["negative_reasoning"]}, + {"role": "assistant", "content": SETTINGS["prompts"]["negative_output"]}, + {"role": "user", "content": SETTINGS["prompts"]["positive_example"]}, + {"role": "system", "content": SETTINGS["prompts"]["positive_reasoning"]}, + {"role": "assistant", "content": SETTINGS["prompts"]["positive_output"]}, {"role": "user", "content": f">>>>>\n{content}\n<<<<<"}, - {"role": "user", "content": settings.instruction_prompt}, + {"role": "user", "content": SETTINGS["prompts"]["instruction_prompt"]}, ] + return messages if __name__ == "__main__": From c35e659556defced8c7672a7a75d019b1ca341f4 Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 1 Mar 2024 16:38:06 +0100 Subject: [PATCH 13/16] Update models, remove max tokens --- prompt-engineering/settings-final.toml | 3 +-- prompt-engineering/settings.toml | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/prompt-engineering/settings-final.toml b/prompt-engineering/settings-final.toml index 8c8368898d..877bedb57d 100644 --- a/prompt-engineering/settings-final.toml +++ b/prompt-engineering/settings-final.toml @@ -1,7 +1,6 @@ [general] -chat_models = ["gpt-3.5", "gpt-3.5-turbo", "gpt-4"] +chat_models = ["gpt-3.5-turbo", "gpt-4"] model = "gpt-4" -max_tokens = 100 temperature = 0 [prompts] diff --git a/prompt-engineering/settings.toml b/prompt-engineering/settings.toml index aedae77ffe..554f38a528 100644 --- a/prompt-engineering/settings.toml +++ b/prompt-engineering/settings.toml @@ -1,7 +1,6 @@ [general] -chat_models = ["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4"] -model = "text-davinci-003" -max_tokens = 2100 +chat_models = ["gpt-3.5-turbo", "gpt-4"] +model = "gpt-3.5-turbo" temperature = 0 [prompts] From d81d62395c233672c38667cceceeec284ab3fb3e Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 1 Mar 2024 16:38:34 +0100 Subject: [PATCH 14/16] Blacken, requirements --- prompt-engineering/app.py | 26 ++++++++++++++++++++------ prompt-engineering/requirements.txt | 29 ++++++++++++++--------------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/prompt-engineering/app.py b/prompt-engineering/app.py index 1dc6bddc9b..1405739ac9 100644 --- a/prompt-engineering/app.py +++ b/prompt-engineering/app.py @@ -5,6 +5,8 @@ from openai import OpenAI +__all__ = ["get_chat_completion"] + # Authenticate client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) @@ -30,23 +32,35 @@ def get_chat_completion(content: str) -> str: """Send a request to the /chat/completions endpoint.""" response = client.chat.completions.create( model=SETTINGS["general"]["model"], - messages=assemble_chat_messages(content), + messages=_assemble_chat_messages(content), temperature=SETTINGS["general"]["temperature"], seed=12345, # Doesn't do anything for older models ) return response.choices[0].message.content -def assemble_chat_messages(content: str) -> list[dict]: +def _assemble_chat_messages(content: str) -> list[dict]: """Combine all messages into a well-formatted list of dicts.""" messages = [ {"role": "system", "content": SETTINGS["prompts"]["role_prompt"]}, {"role": "user", "content": SETTINGS["prompts"]["negative_example"]}, - {"role": "system", "content": SETTINGS["prompts"]["negative_reasoning"]}, - {"role": "assistant", "content": SETTINGS["prompts"]["negative_output"]}, + { + "role": "system", + "content": SETTINGS["prompts"]["negative_reasoning"], + }, + { + "role": "assistant", + "content": SETTINGS["prompts"]["negative_output"], + }, {"role": "user", "content": SETTINGS["prompts"]["positive_example"]}, - {"role": "system", "content": SETTINGS["prompts"]["positive_reasoning"]}, - {"role": "assistant", "content": SETTINGS["prompts"]["positive_output"]}, + { + "role": "system", + "content": SETTINGS["prompts"]["positive_reasoning"], + }, + { + "role": "assistant", + "content": SETTINGS["prompts"]["positive_output"], + }, {"role": "user", "content": f">>>>>\n{content}\n<<<<<"}, {"role": "user", "content": SETTINGS["prompts"]["instruction_prompt"]}, ] diff --git a/prompt-engineering/requirements.txt b/prompt-engineering/requirements.txt index 116fc72241..ae127ad5d9 100644 --- a/prompt-engineering/requirements.txt +++ b/prompt-engineering/requirements.txt @@ -1,15 +1,14 @@ -aiohttp==3.8.4 -aiosignal==1.3.1 -async-timeout==4.0.2 -attrs==23.1.0 -certifi==2023.5.7 -charset-normalizer==3.1.0 -frozenlist==1.3.3 -idna==3.4 -multidict==6.0.4 -openai==0.27.8 -python-dotenv==1.0.0 -requests==2.31.0 -tqdm==4.65.0 -urllib3==2.0.3 -yarl==1.9.2 +annotated-types==0.6.0 +anyio==4.3.0 +certifi==2024.2.2 +distro==1.9.0 +h11==0.14.0 +httpcore==1.0.4 +httpx==0.27.0 +idna==3.6 +openai==1.13.3 +pydantic==2.6.3 +pydantic-core==2.16.3 +sniffio==1.3.1 +tqdm==4.66.2 +typing-extensions==4.10.0 \ No newline at end of file From 61a4bd10984bfe1137aa6f0cd49028a9f3c7fd4e Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 1 Mar 2024 18:04:06 +0100 Subject: [PATCH 15/16] Update prompts --- prompt-engineering/README.md | 125 +++++++++++++++---------- prompt-engineering/settings-final.toml | 77 ++++++++------- 2 files changed, 118 insertions(+), 84 deletions(-) diff --git a/prompt-engineering/README.md b/prompt-engineering/README.md index 23c208965c..11b4820de4 100644 --- a/prompt-engineering/README.md +++ b/prompt-engineering/README.md @@ -405,6 +405,16 @@ instruction_prompt = """ Classify the sentiment of each conversation in >>>>>CONTENT<<<<< with "🔥" for negative and "✅" for positive. +Follow these steps when classifying the conversations: +1. Does the customer use swear words or 😤? +2. Does the customer seem aggravated or angry? + +If you answer "Yes" to one of the above questions, +then classify the conversation as negative with "🔥". +Otherwise classify the conversation as positive with "✅". + +Let's think step by step + #### START EXAMPLES ------ Example Inputs ------ @@ -412,13 +422,17 @@ with "🔥" for negative and "✅" for positive. [Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT [Agent] 2023-07-24 : Are you sure it's not your caps lock? [Customer] 2023-07-24 : 😤! You're right! -The customer uses the 😤 emoji and seems aggravated, so the sentiment is negative. 🔥 + - Does the customer use swear words or 😤? Yes + - Does the customer seem aggravated or angry? Yes + - Sentiment: 🔥 [Agent] 2023-06-15 : Hello! How can I assist you today? [Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. -[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? -[Customer] 2023-06-15 : It's ********. Thanks for helping me out! -The customer does not use any swear words or 😤 emoji and does not seem aggravated or angry, so the sentiment is positive. ✅ +[Agent] 2023-06-15 : No problem, ****. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ****. Thanks for helping me out! + - Does the customer use swear words or 😤? No + - Does the customer seem aggravated or angry? No + - Sentiment: ✅ ------ Example Outputs ------ 🔥 @@ -430,8 +444,8 @@ The customer does not use any swear words or 😤 emoji and does not seem aggrav ✅ [Agent] 2023-06-15 : Hello! How can I assist you today? [Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. -[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? -[Customer] 2023-06-15 : It's ********. Thanks for helping me out! +[Agent] 2023-06-15 : No problem, ****. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ****. Thanks for helping me out! #### END EXAMPLES """ @@ -450,21 +464,34 @@ Classify the sentiment of each conversation in >>>>>CONTENT<<<<< as "negative" and "positive". Return the output as valid JSON. -#### START EXAMPLES +Follow these steps when classifying the conversations: +1. Does the customer use swear words or 😤? +2. Does the customer seem aggravated or angry? + +If you answer "Yes" to one of the above questions, +then classify the conversation as "negative". +Otherwise classify the conversation as "positive". + +Let's think step by step ------- Example Input ------ +#### START EXAMPLES +------ Example Inputs ------ [Agent] 2023-07-24 : What can I help you with? [Customer] 2023-07-24 : I CAN'T CONNECT TO MY 😤 ACCOUNT [Agent] 2023-07-24 : Are you sure it's not your caps lock? [Customer] 2023-07-24 : 😤! You're right! -The customer uses the 😤 emoji and seems aggravated, so the sentiment is negative. + - Does the customer use swear words or 😤? Yes + - Does the customer seem aggravated or angry? Yes + - Sentiment: "negative" [Agent] 2023-06-15 : Hello! How can I assist you today? [Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. -[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? -[Customer] 2023-06-15 : It's ********. Thanks for helping me out! -The customer does not use any swear words or 😤 emoji and does not seem aggravated or angry, so the sentiment is positive. +[Agent] 2023-06-15 : No problem, ****. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ****. Thanks for helping me out! + - Does the customer use swear words or 😤? No + - Does the customer seem aggravated or angry? No + - Sentiment: "positive" ------ Example Output ------ @@ -486,8 +513,8 @@ The customer does not use any swear words or 😤 emoji and does not seem aggrav "conversation": [ "A: Hello! How can I assist you today?", "C: I can't seem to find the download link for my purchased software.", - "A: No problem, ********. Let me find that for you. Can you please provide your order number?", - "C: It's ********. Thanks for helping me out!" + "A: No problem, ****. Let me find that for you. Can you please provide your order number?", + "C: It's ****. Thanks for helping me out!" ] } ] @@ -510,32 +537,33 @@ Classify the sentiment of each conversation in >>>>>CONTENT<<<<< as "negative" and "positive". Return the output as valid JSON. """ -role_prompt = """You are a thoroughly trained machine learning model -that is an expert at sentiment classification. +role_prompt = """You are a thoroughly trained machine learning +model that is an expert at sentiment classification. You diligently complete tasks as instructed. You never make up any information that isn't there.""" positive_example = """ [Agent] 2023-06-15 : Hello! How can I assist you today? [Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. -[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? -[Customer] 2023-06-15 : It's ********. Thanks for helping me out! +[Agent] 2023-06-15 : No problem, ****. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ****. Thanks for helping me out! +""" +positive_reasoning = """ +- Does the customer use swear words or 😤? No +- Does the customer seem aggravated or angry? No +- Sentiment: "positive" """ -positive_reasoning = """The customer does not use any swear words or 😤 emoji -and does not seem aggravated or angry, so the sentiment is positive.""" positive_output = """ -{ - "positive": [ - { - "date": "2023-06-15", - "conversation": [ - "A: Hello! How can I assist you today?", - "C: I can't seem to find the download link for my purchased software.", - "A: No problem, ********. Let me find that for you. Can you please provide your order number?", - "C: It's ********. Thanks for helping me out!" - ] - } - ] -} +"positive": [ + { + "date": "2023-06-15", + "conversation": [ + "A: Hello! How can I assist you today?", + "C: I can't seem to find the download link for my purchased software.", + "A: No problem, ****. Let me find that for you. Can you please provide your order number?", + "C: It's ****. Thanks for helping me out!" + ] + } +] """ negative_example = """ [Agent] 2023-07-24 : What can I help you with? @@ -543,21 +571,22 @@ negative_example = """ [Agent] 2023-07-24 : Are you sure it's not your caps lock? [Customer] 2023-07-24 : 😤! You're right! """ -negative_reasoning = """The customer uses the 😤 emoji and seems aggravated, -so the sentiment is negative.""" +negative_reasoning = """ +- Does the customer use swear words or 😤? Yes +- Does the customer seem aggravated or angry? Yes +- Sentiment: "negative" +""" negative_output = """ -{ - "negative": [ - { - "date": "2023-07-24", - "conversation": [ - "A: What can I help you with?", - "C: I CAN'T CONNECT TO MY 😤 ACCOUNT", - "A: Are you sure it's not your caps lock?", - "C: 😤! You're right!" - ] - } - ] -} +"negative": [ + { + "date": "2023-07-24", + "conversation": [ + "A: What can I help you with?", + "C: I CAN'T CONNECT TO MY 😤 ACCOUNT", + "A: Are you sure it's not your caps lock?", + "C: 😤! You're right!" + ] + } +] """ ``` diff --git a/prompt-engineering/settings-final.toml b/prompt-engineering/settings-final.toml index 877bedb57d..b2bdf0b611 100644 --- a/prompt-engineering/settings-final.toml +++ b/prompt-engineering/settings-final.toml @@ -5,33 +5,37 @@ temperature = 0 [prompts] instruction_prompt = """ -Classify the sentiment of each conversation in >>>>>CONTENT<<<<< as "negative" and "positive". +Classify the sentiment of each conversation in >>>>>CONTENT<<<<< +as "negative" and "positive". Return the output as valid JSON. """ -role_prompt = """You are a thoroughly trained machine learning model that is an expert at sentiment classification. -You diligently complete tasks as instructed. You never make up any information that isn't there.""" +role_prompt = """You are a thoroughly trained machine learning +model that is an expert at sentiment classification. +You diligently complete tasks as instructed. +You never make up any information that isn't there.""" positive_example = """ [Agent] 2023-06-15 : Hello! How can I assist you today? [Customer] 2023-06-15 : I can't seem to find the download link for my purchased software. -[Agent] 2023-06-15 : No problem, ********. Let me find that for you. Can you please provide your order number? -[Customer] 2023-06-15 : It's ********. Thanks for helping me out! +[Agent] 2023-06-15 : No problem, ****. Let me find that for you. Can you please provide your order number? +[Customer] 2023-06-15 : It's ****. Thanks for helping me out! +""" +positive_reasoning = """ +- Does the customer use swear words or 😤? No +- Does the customer seem aggravated or angry? No +- Sentiment: "positive" """ -positive_reasoning = """The customer does not use any swear words or 😤 emoji -and does not seem aggravated or angry, so the sentiment is positive.""" positive_output = """ -{ - "positive": [ - { - "date": "2023-06-15", - "conversation": [ - "A: Hello! How can I assist you today?", - "C: I can't seem to find the download link for my purchased software.", - "A: No problem, ********. Let me find that for you. Can you please provide your order number?", - "C: It's ********. Thanks for helping me out!" - ] - } - ] -} +"positive": [ + { + "date": "2023-06-15", + "conversation": [ + "A: Hello! How can I assist you today?", + "C: I can't seem to find the download link for my purchased software.", + "A: No problem, ****. Let me find that for you. Can you please provide your order number?", + "C: It's ****. Thanks for helping me out!" + ] + } +] """ negative_example = """ [Agent] 2023-07-24 : What can I help you with? @@ -39,20 +43,21 @@ negative_example = """ [Agent] 2023-07-24 : Are you sure it's not your caps lock? [Customer] 2023-07-24 : 😤! You're right! """ -negative_reasoning = """The customer uses the 😤 emoji and seems aggravated, -so the sentiment is negative.""" -negative_output = """ -{ - "negative": [ - { - "date": "2023-07-24", - "conversation": [ - "A: What can I help you with?", - "C: I CAN'T CONNECT TO MY 😤 ACCOUNT", - "A: Are you sure it's not your caps lock?", - "C: 😤! You're right!" - ] - } - ] -} +negative_reasoning = """ +- Does the customer use swear words or 😤? Yes +- Does the customer seem aggravated or angry? Yes +- Sentiment: "negative" """ +negative_output = """ +"negative": [ + { + "date": "2023-07-24", + "conversation": [ + "A: What can I help you with?", + "C: I CAN'T CONNECT TO MY 😤 ACCOUNT", + "A: Are you sure it's not your caps lock?", + "C: 😤! You're right!" + ] + } +] +""" \ No newline at end of file From 78c178bcacc5c0ca11cc09cdcaa85234d879b70e Mon Sep 17 00:00:00 2001 From: martin-martin Date: Fri, 1 Mar 2024 18:04:27 +0100 Subject: [PATCH 16/16] Remove trailing whitespace --- prompt-engineering/sanitized-testing-chats.txt | 2 +- prompt-engineering/testing-chats.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/prompt-engineering/sanitized-testing-chats.txt b/prompt-engineering/sanitized-testing-chats.txt index 6da3659736..174c3c41c2 100644 --- a/prompt-engineering/sanitized-testing-chats.txt +++ b/prompt-engineering/sanitized-testing-chats.txt @@ -10,7 +10,7 @@ [Agent] 2023-08-13: Good morning! How may I assist you? [Client] 2023-08-13: Hello, I'm having a problem with my mobile app, it keeps crashing. -[Agent] 2023-08-13: I'm sorry to hear that, ********. Could you tell me what device you're using? +[Agent] 2023-08-13: I'm sorry to hear that, ********. Could you tell me what device you're using? [Client] 2023-08-13: I have an iPhone 11. [Agent] 2023-08-30: Good evening! How may I assist you today? diff --git a/prompt-engineering/testing-chats.txt b/prompt-engineering/testing-chats.txt index 04233b0d8e..d54c31c248 100644 --- a/prompt-engineering/testing-chats.txt +++ b/prompt-engineering/testing-chats.txt @@ -10,7 +10,7 @@ [support_luke] 2023-08-13T11:34:02+00:00: Good morning! How may I assist you? [anna_s] 2023-08-13T11:34:30+00:00: Hello, I'm having a problem with my mobile app, it keeps crashing. -[support_luke] 2023-08-13T11:34:58+00:00: I'm sorry to hear that, Anna. Could you tell me what device you're using? +[support_luke] 2023-08-13T11:34:58+00:00: I'm sorry to hear that, Anna. Could you tell me what device you're using? [anna_s] 2023-08-13T11:35:22+00:00: I have an iPhone 11. [support_lisa] 2023-08-30T20:38:00+00:00: Good evening! How may I assist you today?