Prompt Engineering Guide - Intruduction

Introduction

생성형 AI가 대세가 되면서 다양한 사람들이 ChatGPT, Bing, Bard처럼 빅테크들이 만든 생성형 LLM들을 사용하고 있습니다. 한 번 써보고 “와 신기하다”정도로 넘어가는 사람들은 모르겟지만, 이런 서비스들을 여러번 사용해보면 똑같은 질문을 하더라도 내가 어떻게 물어보냐에 따라 굉장히 다른 결과가 나오는 것을 알 수 있는데요, 최대한 우리가 원하는 결과를 얻기 위한 다양한 방법들을 “prompt engineering” 이라고 합니다.

Prompt를 어떻게 설계하냐에 따라서 Question answering, summarization 등등 복잡한 task에서 우리가 원하는 답변을 robust하게 생성할 수 있습니다. 단순히 입력 문장을 어떻게 작성하는가의 관점 뿐만 아니라 이를 효율적으로 하기 위한 다양한 방법들이 ChatGPT 등장 이전부터 어느 정도 연구가(Tree of thought 등…) 되어 있기도 했습니다. 이번 포스트에서는 prompt engineering의 기본적인 스킬에 대해 설명해보보도록 하겠습니다.

LLM hyperparameter setting

기본적으로 Generative AI 모델들에는 하이퍼파라미터 설정이 가능합니다. 실제로 파라미터 값을 변경하면서 실행해보면 굉장히 다른 결과 값이 나오는 것을 확인할 수 있습니다.

  • Temperature : 0~1 사이의 값이며 값이 작을수록 결과가 거의 변동 없이 나오고, 값이 커질수록 무작위의 결과가 나오게 됩니다. 진짜 사실에 기반한 결과 값을 얻고 싶다면 해당 값을 낮추고, 만약 소설의 내용을 창작하거나 이야기에 다양성을 준다면 이 값을 1에 가깝게 주면 됩니다. 값이 높을수록 모델의 출력 분포가 더 균등해져서 다양한 선택지를 고르게 됩니다.
  • top_p : Nuclues sampling 또는 top-p sampling으로 알려진 방법으로 모델이 다음 단어를 선택할 때 확률 분포에서 상위 확률을 가진 가장 가능성 높은 단어들 중에서만 선택하도록 하는 것을 의미합니다. temperature와 마찬가지고 낮을수록 더 일관된, 사실에 가까운 결과가 나오게 됩니다.

요약하자면, top_p는 상위 확률을 가진 단어들 중에서만 선택하는 방식을 조정하는 하이퍼파라미터이며, temperature은 출력 분포의 다양성을 조정하는 하이퍼파라미터입니다. 다만 일반적으로는 하나만 바꿔가면서 결과를 생성하는걸 추천한다고 합니다.

Bing을 써보신 분은 아래 그림에서 “대화 스타일”부분을 연상하시면 됩니다.

Basics of Prompting

Basic Prompts

간단한 prompt를 작성할 때도 문장을 약간만 수정하면 prompt를 완성시킬 수 있습니다. 모델에서 명확하게 무엇을 해야하는지 지정해준다면 원하는 결과를 일관적으로 얻기가 훨씬 편해집니다.

  • Input
    The sky is
    
  • Ouput
    blue
    The sky is blue on a clear day. On a cloudy day, the sky may be gray or white.
    

위 예시를 보면 결과에서 “blue”라는 단어에 추가적으로 다른 답변까지 나오게 됩니다. 하이퍼파라미터 값을 바꿔서 좀 더 명확하게 짧은 문장을 받을 수도 있지만 내가 원하는게 정확히 무엇인지 아래 예시처럼 명시해준다면 더 일관된 답이 나오게 됩니다.

  • Input
    Complete the sentence: 
    The sky is
    
  • Ouput
    so  beautiful today.
    

“Complete the sentence”라는 명확한 지시 문장을 추가해서 원하는 결과를 얻을 수 있는 것을 확인할 수 있습니다. Prompt를 할 때는 기본적으로 내가 모델이 어떤 행동을 하길 원하는지 명시적으로 작성해 주는 것이 중요합니다.

Prompt Formatting

다음으로는 prompt를 좀 더 task에 알맞게 바꾸는 방식입니다. 만약 일반적인 Question and Answering task를 시키고 싶다면 아래처럼 prompt를 작성해주면 됩니다.

  • input
    Q: <Question>?
    A: 
    

    위 방식을 zero-shot prompting 이라고도 하며 직접적으로 모델에게 “Answer”를 작성하라는 것과 같습니다. 기본적으로 LLM들은 이런 zeo-shot task도 어느 정도 풀 수 있도록 셋팅되어 있습니다. (다만 문제가 복잡해지면 성능이 좀 떨어지기는 합니다)

  • input
    Q: <Question>?
    A: <Answer>
    Q: <Question>?
    A: <Answer>
    Q: <Question>?
    A: <Answer>
    Q: <Question>?
    A:
    

Zero-shot prompt 보다 더 효과적인 few-shot prompt 입니다. 사람이 직접 prompt에 예시를 넣어서 같이 전달하게 되면 LLM은 훨씬 더 좋은 답변을 내놓게 됩니다. 위 prompt 예시에서도 question, answer 조합을 여러 개 보여주고(few-shot) 마지막에 Answer를 요구하고 있습니다. 굳이 위에서 작성한 방식이 아니더라도 아래 예시처럼 특정 규칙이 있는 prompt만 작성한다면 모델이 더 좋은 답변을 내놓을 확률이 올라갑니다.

  • input
    This is awesome! // Positive
    This is bad! // Negative
    Wow that movie was rad! // Positive
    What a horrible show! //
    
  • output
    Negatvie
    

Elements of a Prompt

Prompt를 구성하는 요소는 아래 4가지로 나눌 수 있습니다.

  • Instruction : 모델이 무엇을 해야할지 지시하는 부분입니다. 위 예시에서 나왔던 “Complter the sentence”와 같은 문장도 instruction 중 하나입니다.
  • Context : 모델이 더 좋은 결과를 뽑아줄 수 있는 추가적인 정보입니다. Few-shot prompt의 경우에는 다른 예시들이 이러한 context라고 할 수 있습니다.
  • Input data : 내가 답을 찾고 싶은 입력 데이터입니다.
  • Output Indicator : 결과를 얻고 싶은 형태입니다. 예시에서는 계속 스트링 형식의 문장만 받았지만 필요하다면 json, list, dictionary 등 다양한 형태로 결과값을 변형하여 받을 수 있습니다. (json 같은 경우는 특정 양식을 지정해주면 정말 놀랍도록 잘 뽑아줍니다)

위 네 가지 구성요소가 항상 다 있어야만 하는 것은 아니지만 필요한 상황에 추가로 넣어준다면 우리가 원하는 결과를 뽑아내는데 매우 도움이 됩니다.

General Tips for Designing Prompts

Prompt를 작성하면서 알고 있으면 좋을 몇 가지 팁입니다.

Start Simple

무조건 처음부터 복잡하게 prompt를 작성할 필요가 없다는걸 항상 염두에 두고 있어야 합니다. ChatGPT처럼 대화형 AI는 사람과 모델이 지속적으로 정보를 주고받으며 원하는 결과가 나올 때까지 다양한 실험을 계속 이어가야 합니다. 그래서 처음에는 간단한 prompt로 시작을 해서 결과가 나오게끔 계속 모델을 유지하는 것도 중요합니다.

만약 다양한 subtask가 있는 하나의 커다란 big task를 완성해야 한다면, 간단한 subtask를 하나씩 완성해가면서 결과를 얻는게 더 나은 경우가 많습니다. 그래서 처음부터 너무 복잡하게 시작하기 보다는 간단하고 쉽게 접근하는걸 추천한다고 하네요.

The instruction

지시어를 명확하게 작성해야합니다. 계속 위에서도 강조하는 표현이긴 하지만, 모델이 어떤 작업을 해야하는지 명확하게 작성해주기만 하면 기본적인 결과는 받을 수 있게 되는데요, ‘write’, ‘classify’, ‘summarize’, ‘recommend’, ‘translate’ 등 이런 특정 지시어를 예로 들 수 있겠습니다.

  • input
    ### Instruction ###
    Translate the text below to Spanish:
    Text: "hello!"
    Output:
    
  • output
    ¡Hola!
    

특정 지시를 했을 때 원하는 결과가 나오지 않는다면 다양하게 바꿔서 지시 하는 것도 시도하면 좋은 방법이라고 합니다. 단어를 바꾼다던지, context에 변형을 준다던지 시도해볼 필요가 있습니다. 특히 context를 조금 더 명확한 걸 제시하거나 하면 더 좋은 결과가 나올 수 있습니다. 그리고 instruction 부분은 위 예시의 ### 처럼 구분이 확시랗게 되는 seperator를 사용해야 더 좋다고 합니다.

Specificity

모델이 무엇을 해야하는지에 대한 내용을 구체적으로 명시하는 것도 매우 중요하다고 합니다. 자세한 설명이 곁들여져 있는 prompt일수록 당연히 결과가 더 좋아질 수밖에 없겠죠. 특히나 결과물이나 어떤 방식으로 생성되는지 스타일을 지정해야 할때는 명확히 내가 무엇을 원하는지 표현해야 합니다. 특정 키워드에 모델이 잘 반응하는게 아니라 명확하고 설명이 잘 되어있는 prompt에서 더 좋은 결과가 나오는 것을 항상 명심하고 있어야 합니다. Prompt에 example을 제공하는 것도 “specificity”에 도움이 되는 부분입니다.

Prompt를 써보신 분들은 알겠지만, 토큰이 너무 길어지면 결국 hallucination 현상이 발생하게 되는데요, 이를 방지하기 위해서는 적은 글자 수로 효율적인 prompt를 작성하는 것도 중요합니다. 구체적이로 명확한건 좋지만 불필요한 세부사항을 너무 많이 포함하는 것은 좋지 않은 방식입니다.

  • input
    Extract the name of places in the following text. 
    Desired format:
    Place: <comma_separated_list_of_company_names>
    Input: "Although these developments are encouraging to researchers, much is still a mystery. “We often have a black box between the brain and the effect we see in the periphery,” says Henrique Veiga-Fernandes, a neuroimmunologist at the Champalimaud Centre for the Unknown in Lisbon. “If we want to use it in the therapeutic context, we actually need to understand the mechanism.""
    
  • output
    Place: Champalimaud Centre for the Unknown, Lisbon
    

Avoid Impreciseness

위에서 언급한 명확성, 지시어 등 다양한 방안들을 고려하면 prompt를 너무 부정확하게 만들게 될 수도 있습니다. 좀 더 구체적이고 직접적일수록 더 좋은 prompt라고 할 수 있는데요, “짧게 설명해” 보다는 “한 문장으로 설명해줘” 처럼 정확하게 지시하는게 더 좋은 prompt 입니다. 예를 들어, 고등학생들에게 prompt engineering 개념을 설명하고 싶다면 아래와 같이 prompt를 작성할 수 있습니다.

Explain the concept prompt engineering. Keep the explanation short, only a few sentences, and don't be too descriptive.

위 prompt의 문제점은 지시는 명확하게 했지만 정확히 어떤 일을 해야하는지 명시적으로 작성하지 않았다는 것입니다. 위 prompt에서 안좋은 결과가 나온다는 것은 아니지만 더 나은 prompt는 확실히 구체적이고 모호한 표현이 없습니다. 다시 작성한다면 아래처럼 바꿀 수 있겠네요.

Use 2-3 sentences to explain the concept of prompt engineering to a high school student.

To do or not to do?

마지막 팁으로는 prompt에 모델이 “무엇을 하면 안되는가” 보다는 “무엇을 해야하는가”에 초점을 맞춰 작성하는 것입니다. 이렇게 작성해야 더 구체성이 증가하고 모델한테 좋은 응답을 받기 위한 세부사항에 초점을 받을 수 있습니다. 아래 예시는 모델이 “하면 안되는” prompt에 초점을 맞춰 원하는 결과가 나오지 않은 예시입니다.

Prompt:

The following is an agent that recommends movies to a customer. DO NOT ASK FOR INTERESTS. DO NOT ASK FOR PERSONAL INFORMATION.
Customer: Please recommend a movie based on my interests.
Agent: 

Output:

Sure, I can recommend a movie based on your interests. What kind of movie would you like to watch? Do you prefer action, comedy, romance, or something else?

“유저의 관심사”와 “개인적인 정보”를 물어봐선 안된다고 하니까 오히려 엉뚱한 답변을 내놓는 것을 볼 수 있습니다. 아래와 같이 수정하면 더 좋은 prompt를 만들 수 있습니다.

Prompt:

The following is an agent that recommends movies to a customer. The agent is responsible to recommend a movie from the top global trending movies. It should refrain from asking users for their preferences and avoid asking for personal information. If the agent doesn't have a movie to recommend, it should respond "Sorry, couldn't find a movie to recommend today.".
Customer: Please recommend a movie based on my interests.
Agent:

Output:

Sorry, I don't have any information about your interests. However, here's a list of the top global trending movies right now: [list of movies]. I hope you find something you like!
Some of the examples above were adopted from the "Best practices for prompt engineering with OpenAI API" article.

더 좋은 결과를 얻기 위한 Prompt engineering 기본 스킬들을 알아봤습니다. 다음 포스트부터는 다양한 예시들과 더 복잡한 prompt skill 들에 대해 작성해보도록 하곘습니다.

Reference