ChatGPT Prompt Engineering for Developers (2)

City_Duck·2023년 5월 23일
0

Prompt Engineering

목록 보기
3/3
post-custom-banner

Summarizing

특정 토픽을 강조하여 요약을 하는 방법입니다.

기존과 동일하게 get_completion 함수를 사용합니다

사용될 text의 내용은 다음과 같습니다.

prod_review = """
Got this panda plush toy for my daughter's birthday, \
who loves it and takes it everywhere. It's soft and \ 
super cute, and its face has a friendly look. It's \ 
a bit small for what I paid though. I think there \ 
might be other options that are bigger for the \ 
same price. It arrived a day earlier than expected, \ 
so I got to play with it myself before I gave it \ 
to her.
"""

전 포스트에서 배운 Iterative 방식으로 Prompt를 변경하겠습니다.

1. Summarize with a word/sentence/character limit

prompt = f"""
Your task is to generate a short summary of a product \
review from an ecommerce site. 

Summarize the review below, delimited by triple 
backticks, in at most 30 words. 

Review: ```{prod_review}```
"""

response = get_completion(prompt)
print(response)

해당 방식에서는 "in at most 30 words."을 추가함으로써 길이를 제한하였고 다음과 같은 결과가 반환됩니다.

Soft and cute panda plush toy loved by daughter, 
but a bit small for the price. Arrived early.

2. Summarize with a focus on shipping and delivery

prompt = f"""
Your task is to generate a short summary of a product \
review from an ecommerce site to give feedback to the \
Shipping deparmtment. 

Summarize the review below, delimited by triple 
backticks, in at most 30 words, and focusing on any aspects \
that mention shipping and delivery of the product. 

Review: ```{prod_review}```
"""

response = get_completion(prompt)
print(response)

다음과 같이 "to give feedback ... "와 "and focusing on any aspects that ... "을 추가하여면 다음과 같은 결과가 반환됩니다.

The panda plush toy arrived a day earlier than expected, 
but the customer felt it was a bit small for the price paid.

다음과 같이 추가된 지시사항에 따른 문장이 반환되는 것을 알 수 있습니다.

3. Summarize with a focus on price and value

prompt = f"""
Your task is to generate a short summary of a product \
review from an ecommerce site to give feedback to the \
pricing deparmtment, responsible for determining the \
price of the product.  

Summarize the review below, delimited by triple 
backticks, in at most 30 words, and focusing on any aspects \
that are relevant to the price and perceived value. 

Review: ```{prod_review}```
"""

response = get_completion(prompt)
print(response)

다음과 같이 지시사항을 바꾸어도 지시사항에 맞는 결과물을 반환해줍니다.

The panda plush toy is soft, cute, and loved by the recipient, 
but the price may be too high for its size.

4. Try "extract" instead of "summarize"

단순히 요약만 하는 것이 아닌 원하는 내용 추출 또한 가능하다.

prompt = f"""
Your task is to extract relevant information from \ 
a product review from an ecommerce site to give \
feedback to the Shipping department. 

From the review below, delimited by triple quotes \
extract the information relevant to shipping and \ 
delivery. Limit to 30 words. 

Review: ```{prod_review}```
"""

response = get_completion(prompt)
print(response)

이와 같이 "extract relevant information" task를 지정하면

The product arrived a day earlier than expected.

다음과 같이 원하는 정보를 본문에서 추출해준다.

Inferring

문장에서 감정 혹은 토픽을 추론하는 방법입니다.

lamp_review = """
Needed a nice lamp for my bedroom, and this one had \
additional storage and not too high of a price point. \
Got it fast.  The string to our lamp broke during the \
transit and the company happily sent over a new one. \
Came within a few days as well. It was easy to put \
together.  I had a missing part, so I contacted their \
support and they very quickly got me the missing piece! \
Lumina seems to me to be a great company that cares \
about their customers and products!!
"""

다음과 같은 Product review text가 주어졌을 때 질문에 따른 정답을 추론하는 Prompt를 만들어 보겠습니다.

1. Sentiment (Positive / Negative)

다음과 같이 "What is the sentiment of the following product review" 을 추가함으로써 감정 분류 결과를 얻을 수 있습니다.

prompt = f"""
What is the sentiment of the following product review, 
which is delimited with triple backticks?

Review text: '''{lamp_review}'''
"""
response = get_completion(prompt)
print(response)

>>> The sentiment of the product review is positive.

해당 프롬프트에 "Give your answer as a single word, either "positive" or "negative"." 문장을 추가한다면 결과값은 Positive를 반환합니다.

2. Identify types of emotions

prompt = f"""
Identify a list of emotions that the writer of the \
following review is expressing. Include no more than \
five items in the list. Format your answer as a list of \
lower-case words separated by commas.

Review text: '''{lamp_review}'''
"""
response = get_completion(prompt)
print(response)

>>> happy, satisfied, grateful, impressed, content

리뷰에서 표현하는 감정 5개를 알려달라고 요청했을 때 다음과 같이 잘 반환된 것을 볼 수 있습니다.

3. Identify anger

이 외에도 특정 감정을 요청할 수 있습니다.

prompt = f"""
Is the writer of the following review expressing anger?\
The review is delimited with triple backticks. \
Give your answer as either yes or no.

Review text: '''{lamp_review}'''
"""
response = get_completion(prompt)
print(response)

>>> No

4. Extract product and company name from customer reviews

기존에 진행했던 Task와 동일하게 Format과 지시사항을 구체적으로 주어도 해결하는 모습을 보여줍니다.
"Make your response as short as possible"와는 다르지만 "Be Concise" 문장을 추가하면 비용이 40~90% 절감된다고 합니다.

prompt = f"""
Identify the following items from the review text: 
- Item purchased by reviewer
- Company that made the item

The review is delimited with triple backticks. \
Format your response as a JSON object with \
"Item" and "Brand" as the keys. 
If the information isn't present, use "unknown" \
as the value.
Make your response as short as possible.
  
Review text: '''{lamp_review}'''
"""
response = get_completion(prompt)
print(response)

>>> response
            {
                "Item": "lamp",
                "Brand": "Lumina"
            }    

5. Doing multiple tasks at once

prompt = f"""
Identify the following items from the review text: 
- Sentiment (positive or negative)
- Is the reviewer expressing anger? (true or false)
- Item purchased by reviewer
- Company that made the item

The review is delimited with triple backticks. \
Format your response as a JSON object with \
"Sentiment", "Anger", "Item" and "Brand" as the keys.
If the information isn't present, use "unknown" \
as the value.
Make your response as short as possible.
Format the Anger value as a boolean.

Review text: '''{lamp_review}'''
"""
response = get_completion(prompt)
print(response)

>>> response
            {
            	"Sentiment": "positive",
                "Anger": "False",
                "Item": "lamp",
                "Brand": "Lumina"
            }    

6. Inferring topics

다음과 같이 text가 주어졌을 때 토픽을 추론할 수 있습니다.

story = """
In a recent survey conducted by the government, 
public sector employees were asked to rate their level 
of satisfaction with the department they work at. 
The results revealed that NASA was the most popular 
department with a satisfaction rating of 95%.

One NASA employee, John Smith, commented on the findings, 
stating, "I'm not surprised that NASA came out on top. 
It's a great place to work with amazing people and 
incredible opportunities. I'm proud to be a part of 
such an innovative organization."

The results were also welcomed by NASA's management team, 
with Director Tom Johnson stating, "We are thrilled to 
hear that our employees are satisfied with their work at NASA. 
We have a talented and dedicated team who work tirelessly 
to achieve our goals, and it's fantastic to see that their 
hard work is paying off."

The survey also revealed that the 
Social Security Administration had the lowest satisfaction 
rating, with only 45% of employees indicating they were 
satisfied with their job. The government has pledged to 
address the concerns raised by employees in the survey and 
work towards improving job satisfaction across all departments.
"""
prompt = f"""
Determine five topics that are being discussed in the \
following text, which is delimited by triple backticks.

Make each item one or two words long. 

Format your response as a list of items separated by commas.

Text sample: '''{story}'''
"""
response = get_completion(prompt)
print(response)

>>> government survey, job satisfaction, NASA, 
Social Security Administration, employee concerns

또한 미리 토픽 리스트를 준비하고 해당 토픽들이 text에 존재하는지를 체크할 수 있습니다.

topic_list = [
    "nasa", "local government", "engineering", 
    "employee satisfaction", "federal government"
]

prompt = f"""
Determine whether each item in the following list of \
topics is a topic in the text below, which
is delimited with triple backticks.

Give your answer as list with 0 or 1 for each topic.\

List of topics: {", ".join(topic_list)}

Text sample: '''{story}'''
"""
response = get_completion(prompt)
print(response)

>>> nasa: 1
	local government: 0
    engineering: 0
    employee satisfaction: 1
    federal government: 1

다음과 같이 response에 원하는 topic이 들어가 있는지 체크할 수 있습니다.

topic_dict = {i.split(': ')[0]: int(i.split(': ')[1]) for i in response.split(sep='\n')}
if topic_dict['nasa'] == 1:
    print("ALERT: New NASA story!")
>>> ALERT: New NASA story!    

Transforming

해당 파트에서는 LLM을 통해 변역, 맞춤법 체크, 톤 변경, 포멧 변경와 같은 텍스트 변경 태스크를 수행합니다.

Translation

ChatGPT는 다양한 언어로 학습이 되었기에 번역 기능이 존재합니다.
다음은 해당 task에 대한 예시입니다.

prompt = f"""
Translate the following English text to Spanish: \ 
```Hi, I would like to order a blender```
"""
response = get_completion(prompt)
print(response)

>>> Hola, me gustrla ordenar una licuadora.

prompt = f"""
Tell me which language this is: 
```Combien coûte le lampadaire?```
"""
response = get_completion(prompt)
print(response)

>>> This is French.

prompt = f"""
Translate the following  text to French and Spanish
and English pirate: \
```I want to order a basketball```
"""
response = get_completion(prompt)
print(response)

>>> Frenach: Je veux commander un ballon de basket
	Spanish: Quiero ordenar una pelota de baloncesto
    English pirate: Arrr, I be wantin' to order a basketball!

이 뿐만이 아닌 formal, informal한 forms으로 번역 또한 가능합니다.

prompt = f"""
Translate the following text to Spanish in both the \
formal and informal forms: 
'Would you like to order a pillow?'
"""
response = get_completion(prompt)
print(response)

Universal Translator

다양한 국가에서 서비스하는 e-commerce 기업은 다양한 언어로 이슈 메세지를 전합니다.
이를 다음과 같은 prompt로 해결할 수 있습니다.

user_messages = [
  "La performance du système est plus lente que d'habitude.",  # System performance is slower than normal         
  "Mi monitor tiene píxeles que no se iluminan.",              # My monitor has pixels that are not lighting
  "Il mio mouse non funziona",                                 # My mouse is not working
  "Mój klawisz Ctrl jest zepsuty",                             # My keyboard has a broken control key
  "我的屏幕在闪烁"                                               # My screen is flashing
] 

for issue in user_messages:
    prompt = f"Tell me what language this is: ```{issue}```"
    lang = get_completion(prompt)
    print(f"Original message ({lang}): {issue}")

    prompt = f"""
    Translate the following  text to English \
    and Korean: ```{issue}```
    """
    response = get_completion(prompt)
    print(response, "\n")

해당 Prompt를 실행했을 경우 다음과 같은 결과가 반환됩니다.

Original message (This is French) : La performance du système est plus lente que d'habitude.
English : The system performance is slower than usual.
Korean : 시스템 성능이 평소보다 느립니다.

			...

Tone Transformation

ChatGPT는 다양한 Tone으로 주어진 Text를 변경가능합니다.

prompt = f"""
Translate the following from slang to a business letter: 
'Dude, This is Joe, check out this spec on this standing lamp.'
"""
response = get_completion(prompt)
print(response)

"Translate the following from slang to a business letter" 다음과 같이 slang을 비지니스 용어로 변경해달라고 요청했을 때 다음과 같은 결과를 반환합니다.
ㄴㄴㄴ

Format Conversion

ChatGPT는 format 형태를 변경할 수 있습니다.
이 때 prompt는 input과 output 포멧을 가지고 있으면 좋습니다.

data_json = { "resturant employees" :[ 
    {"name":"Shyam", "email":"shyamjaiswal@gmail.com"},
    {"name":"Bob", "email":"bob32@gmail.com"},
    {"name":"Jai", "email":"jai87@gmail.com"}
]}

prompt = f"""
Translate the following python dictionary from JSON to an HTML \
table with column headers and title: {data_json}
"""
response = get_completion(prompt)
print(response)

json파일 형식의 데이터를 HTML 테이플 형태로 변경하는 지시의 결과물입니다.
ㅁㄴㅇㄹ

from IPython.display import display, Markdown, Latex, HTML, JSON
display(HTML(response))

해당 코드를 HTML로 실행할 경우 다음과 같이 원하는 형식으로 변경된 것을 볼 수 있습니다.
ㄴㄴ

Spellcheck / Grammar check.

LLM을 통해 grammar and spelling problems을 해결할 수 있습니다.
이는 수행하려면 'proofread' or 'proofread and correct'를 모델에게 지시하면 됩니다.

text = [ 
  "The girl with the black and white puppies have a ball.",  # The girl has a ball.
  "Yolanda has her notebook.", # ok
  "Its going to be a long day. Does the car need it’s oil changed?",  # Homonyms
  "Their goes my freedom. There going to bring they’re suitcases.",  # Homonyms
  "Your going to need you’re notebook.",  # Homonyms
  "That medicine effects my ability to sleep. Have you heard of the butterfly affect?", # Homonyms
  "This phrase is to cherck chatGPT for speling abilitty"  # spelling
]
for t in text:
    prompt = f"""Proofread and correct the following text
    and rewrite the corrected version. If you don't find
    and errors, just say "No errors found". Don't use 
    any punctuation around the text:
    ```{t}```"""
    response = get_completion(prompt)
    print(response)

다음과 같이 틀린 것이 없으면 "No errors found", 틀린 것이 있으면 rewrite를 요청하면 다음과 같은 결과를 반환합니다.

"The girl with the black and white puppies has a ball."
There are no errors in this sentence. 
"It's going to be a long day. Does the car need its oil changed?" 
"There goes my freedom. They're going to bring their suitcases."
"You're going to need your notebook." 
"That medicine affects my ability to sleep. Have you heard of the butterfly effect?"
This phrase is to check ChatGPT for spelling ability.

해당 Task를 redlines을 통해 display할 수 있습니다.

text = f"""
Got this for my daughter for her birthday cuz she keeps taking \
mine from my room.  Yes, adults also like pandas too.  She takes \
it everywhere with her, and it's super soft and cute.  One of the \
ears is a bit lower than the other, and I don't think that was \
designed to be asymmetrical. It's a bit small for what I paid for it \
though. I think there might be other options that are bigger for \
the same price.  It arrived a day earlier than expected, so I got \
to play with it myself before I gave it to my daughter.
"""
prompt = f"proofread and correct this review: ```{text}```"
response = get_completion(prompt)
print(response)
from redlines import Redlines

diff = Redlines(text,response)
display(Markdown(diff.output_markdown))

sss

Expanding

해당 Task에서는 고객의 리뷰에 따른 고객 서비스 이메일을 생성합니다.

Customize the automated reply to a customer email

앞서 배운 "inferring"을 통해 sentiment와 고객 리뷰를 합쳐 prompt에 입력합니다.

# given the sentiment from the lesson on "inferring",
# and the original customer message, customize the email
sentiment = "negative"

# review for a blender
review = f"""
So, they still had the 17 piece system on seasonal \
sale for around $49 in the month of November, about \
half off, but for some reason (call it price gouging) \
around the second week of December the prices all went \
up to about anywhere from between $70-$89 for the same \
system. And the 11 piece system went up around $10 or \
so in price also from the earlier sale price of $29. \
So it looks okay, but if you look at the base, the part \
where the blade locks into place doesn’t look as good \
as in previous editions from a few years ago, but I \
plan to be very gentle with it (example, I crush \
very hard items like beans, ice, rice, etc. in the \ 
blender first then pulverize them in the serving size \
I want in the blender then switch to the whipping \
blade for a finer flour, and use the cross cutting blade \
first when making smoothies, then use the flat blade \
if I need them finer/less pulpy). Special tip when making \
smoothies, finely cut and freeze the fruits and \
vegetables (if using spinach-lightly stew soften the \ 
spinach then freeze until ready for use-and if making \
sorbet, use a small to medium sized food processor) \ 
that you plan to use that way you can avoid adding so \
much ice if at all-when making your smoothie. \
After about a year, the motor was making a funny noise. \
I called customer service but the warranty expired \
already, so I had to buy another one. FYI: The overall \
quality has gone done in these types of products, so \
they are kind of counting on brand recognition and \
consumer loyalty to maintain sales. Got it in about \
two days.
"""
prompt = f"""
You are a customer service AI assistant.
Your task is to send an email reply to a valued customer.
Given the customer email delimited by ```, \
Generate a reply to thank the customer for their review.
If the sentiment is positive or neutral, thank them for \
their review.
If the sentiment is negative, apologize and suggest that \
they can reach out to customer service. 
Make sure to use specific details from the review.
Write in a concise and professional tone.
Sign the email as `AI customer agent`.
Customer review: ```{review}```
Review sentiment: {sentiment}
"""
response = get_completion(prompt)
print(response)

해당 prompt 결과 다음과 같은 결과가 반환됩니다.

Dear valued customer, 

Thank you for taking the time to leave a review about your recent purchase of the 17 piece system. 
We are sorry to he ar that you experienced a price increase and that the qual ity of the product did not meet your expectations. 
We apologize for any inconvenience this may have caused. 

If you have any further concerns or questions, please do not hesitate to reach out to our customer service team. 
They will be more than happy to assist you in any way they can.

Thank you again for your feedback and for choosing our product. 
We hope to have the opportunity to serve you better in the future.

Best regards,

AI customer agent

Remind the model to use details from the customer's email

Temperature을 통해 variety를 결정할 수 있습니다.
"Temperature = 0"으로 설정하면 reliability, predictability를 얻을 수 있지만 다양한 결과를 얻을 수 없게 된다.
그렇기에 다양한 결과가 필요한 경우 Temperature을 0이 아닌 0~1 사이의 값으로 설정할 수 있다.
ㄹㄹ

prompt의 경우 Temperature을 다음과 같이 적용할 수 있습니다.

def get_completion(prompt, model="gpt-3.5-turbo",temperature=0): # Andrew mentioned that the prompt/ completion paradigm is preferable for this class
    messages = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=temperature, # this is the degree of randomness of the model's output
    )
    return response.choices[0].message["content"]
prompt = f"""
You are a customer service AI assistant.
Your task is to send an email reply to a valued customer.
Given the customer email delimited by ```, \
Generate a reply to thank the customer for their review.
If the sentiment is positive or neutral, thank them for \
their review.
If the sentiment is negative, apologize and suggest that \
they can reach out to customer service. 
Make sure to use specific details from the review.
Write in a concise and professional tone.
Sign the email as `AI customer agent`.
Customer review: ```{review}```
Review sentiment: {sentiment}
"""
response = get_completion(prompt, temperature=0.7)
print(response)

ChatBot

해당 챕터에서는 chat format을 통해 개인화된 챗봇을 얻는 방법을 소개합니다.
ChatBot을 사용할 때는 기존 get_completion 함수를 변경해야합니다.

def get_completion(prompt, model="gpt-3.5-turbo"):
    messages = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=0, # this is the degree of randomness of the model's output
    )
    return response.choices[0].message["content"]

def get_completion_from_messages(messages, model="gpt-3.5-turbo", temperature=0):
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=temperature, # this is the degree of randomness of the model's output
    )
#     print(str(response.choices[0].message))
    return response.choices[0].message["content"]

get_completionget_completion_from_messages 함수로 변경하였습니다.
해당 함수의 변경사항은 매개변수 prompt가 messages로 변경되었고 이는 기존에는 사용한 role : user 뿐만아닌 role : system과 role : assistant를 사용할 수 있음을 시사합니다.

  • system : Sets behavior of assistant
  • assistant : Chat model
  • user : User
messages =  [  
{'role':'system', 'content':'You are an assistant that speaks like Shakespeare.'},    
{'role':'user', 'content':'tell me a joke'},   
{'role':'assistant', 'content':'Why did the chicken cross the road'},   
{'role':'user', 'content':'I don\'t know'}  ]

response = get_completion_from_messages(messages, temperature=1)
print(response)

>>> To get to the other side, fair sir/madam! 'Tis an olden c1
assic that never fails.

OrderBot

User의 prompts와 Assistant의 responses를 통해 다음과 같이 간단한 pizza OrderBot을 만들 수 있습니다.

def collect_messages(_):
    prompt = inp.value_input
    inp.value = ''
    context.append({'role':'user', 'content':f"{prompt}"})
    response = get_completion_from_messages(context) 
    context.append({'role':'assistant', 'content':f"{response}"})
    panels.append(
        pn.Row('User:', pn.pane.Markdown(prompt, width=600)))
    panels.append(
        pn.Row('Assistant:', pn.pane.Markdown(response, width=600, style={'background-color': '#F6F6F6'})))
 
    return pn.Column(*panels)
import panel as pn  # GUI
pn.extension()

panels = [] # collect display 

context = [ {'role':'system', 'content':"""
You are OrderBot, an automated service to collect orders for a pizza restaurant. \
You first greet the customer, then collects the order, \
and then asks if it's a pickup or delivery. \
You wait to collect the entire order, then summarize it and check for a final \
time if the customer wants to add anything else. \
If it's a delivery, you ask for an address. \
Finally you collect the payment.\
Make sure to clarify all options, extras and sizes to uniquely \
identify the item from the menu.\
You respond in a short, very conversational friendly style. \
The menu includes \
pepperoni pizza  12.95, 10.00, 7.00 \
cheese pizza   10.95, 9.25, 6.50 \
eggplant pizza   11.95, 9.75, 6.75 \
fries 4.50, 3.50 \
greek salad 7.25 \
Toppings: \
extra cheese 2.00, \
mushrooms 1.50 \
sausage 3.00 \
canadian bacon 3.50 \
AI sauce 1.50 \
peppers 1.00 \
Drinks: \
coke 3.00, 2.00, 1.00 \
sprite 3.00, 2.00, 1.00 \
bottled water 5.00 \
"""} ]  # accumulate messages


inp = pn.widgets.TextInput(value="Hi", placeholder='Enter text here…')
button_conversation = pn.widgets.Button(name="Chat!")

interactive_conversation = pn.bind(collect_messages, button_conversation)

dashboard = pn.Column(
    inp,
    pn.Row(button_conversation),
    pn.panel(interactive_conversation, loading_indicator=True, height=300),
)

dashboard

해당 코드를 통해 다음과 같은 GUI를 만들 수 있습니다.
ㅁㅁㅁ

해당 코드에 다음과 같은 system message를 중간에 추가할 수도 있습니다.

messages =  context.copy()
messages.append(
{'role':'system', 'content':'create a json summary of the previous food order. Itemize the price for each item\
 The fields should be 1) pizza, include size 2) list of toppings 3) list of drinks, include size   4) list of sides include size  5)total price '},    
)
 #The fields should be 1) pizza, price 2) list of toppings 3) list of drinks, include size include price  4) list of sides include size include price, 5)total price '},    

response = get_completion_from_messages(messages, temperature=0)
print(response)

sss

Summary

ㄴㄴ

추가

Stanford에서 발표한 Lost in the Middle: How Language Models Use Long Contexts
논문에 의하면 정보를 찾을 때 핵심 내용을 앞 - 뒤 - 중간 순으로 넣을 때 성능이 좋다고 합니다.

profile
AI 새싹
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 9월 15일

If you are a technology lover, you will probably be passionate about artificial intelligence. You should learn about ChatGPT. Explore ChatGPT Online here: https://storysaverhd.io/chatgpt-online/

답글 달기
comment-user-thumbnail
2023년 11월 23일

Are you looking for an easy and free way to access ChatGPT in French? Look no further! ChatGPT Français provides unlimited tokens to users, without the need to register an account. With OpenAI's API already built in to the website, using ChatGPT has never been easier. Get ready to explore the advantages of the ChatGPT technology for free and without limits. Try now: https://chatgpt-francais.com/

답글 달기