커리어리와 카카오 사내 아지트에 공유한 글인데 기술 블로그에도 공유합니다.
앤드류 응 교수 (Andrew Ng) 님의 프롬프트 강의 와 OpenAI Cookbook 을 참고하여 프롬프트 작성 가이드를 정리해보았습니다.
최근 ChatGPT가 등장하면서 개발자들에게 이를 잘 활용하는 것이 매우 중요해졌다고 생각합니다.
TDD 창시자인 켄트 벡은 ChatGPT가 등장한 후, 자신이 가진 기술의 90%가 무의미해졌다고 말할 정도입니다. 그러나 나머지 10%는 1000배 더 중요해졌다고 말합니다.
ChatGPT를 잘 활용하려면 프롬프트를 잘 작성하는 것이 중요한데요, 이에 대한 방법들을 알아보고 글로 정리해보겠습니다.
"13 * 17 = ?" 이라는 질문에 3초 내로 대답해보라는 명령을 받았다고 가정해봅시다. 인간은 이런 질문에 틀릴 수 있습니다.
하지만 그렇다고 인간이 두 자리 수 곱셈 계산을 못하느냐고 묻는다면 그렇지 않습니다.
LLMs도 이와 비슷합니다. 한 번에 답을 요구하면 틀릴 수 있지만 차근차근 계산하도록 (= Let's think step by step) 질문하면 제대로 답합니다.
사람들이 자주하는 오해 중 하나는, 나의 질문에 언어 모델이 답을 틀리게 낸다면 "아, 이 정도 수준의 일은 못하는구나!"라고 생각할 수 있는데, 어떤 프롬프트로 지시하느냐에 따라 정답을 낼 수도 있고 못 낼 수도 있습니다.
프롬프트에 Let's think step by step
를 추가하면 답변을 더 정확하게 작성한다고 합니다. 이 프롬프트는 상당히 일반적으로 사용할 수 있으며, 특히 문제 해결에서 정답률을 급격히 높입니다. (18% → 79% 향상)
프롬프트 작성 원칙에는 크게 두 가지를 기억해야 합니다.
1. 명확하고 구체적인 지시 작성하기
2. 모델에게 생각할 시간을 주기
명확하다는 의미는 이런 것입니다.
엘런 튜닝에 대해 무언가를 작성해주세요 (X)
엘런 튜닝의 과학적 업적과 개인적인 삶에 대해서 작성해주세요. (O)
명확한 지시를 위해 Few-shot Prompting이라는 방법이 있습니다. 이는 프롬프트에 예시를 제시하는 것입니다.
예를 들어 다음과 같은 문제 풀이를 내는 프롬프트를 살펴봅시다.
Q: 로저는 5개의 테니스 공이 있습니다. 그는 테니스 공이 들어간 두 개의 캔을 샀고, 각각의 캔에는 3개의 공이 들어있습니다. 이때 테니스 공의 총 개수는?
A: (바로 답을 알려주는게 아니라 여기서 어떻게 계산하는지 알려주는 것입니다.) 로저는 5개의 공으로 시작했고, 2개의 캔에는 각각 3개의 공이 들어있으니 총 6개의 공이 있습니다. 그러므로 5 + 6 = 11 입니다.
Q: (이제 내가 물어보고 싶은 문제를 작성합니다.) 카페에는 23개의 사과가 있습니다. 20개는 점심에 사용했고, 6개를 추가로 샀습니다. 이때 사과의 총 개수는?
이처럼 프롬프트에 Few-shot 방식으로 예시를 제시하면 훨씬 더 잘 대답합니다. 성능적으로는 약 3배 정도 (18% -> 57%) 더 뛰어납니다.
이제 다음 방법인 모델에게 생각할 시간을 주는 방법을 알아봅시다.
모델에게 한 번에 결론을 내도록 하는 것이 아니라 중간 단계인 Step들을 명시해서 이를 먼저 수행하도록 하거나, 결론을 내기 전에 풀어야 할 핵심 과제가 있다면 이를 먼저 수행하도록 지시하는 것입니다.
Step별로 질문을 단순화하여 복잡한 질문을 처리하는 방법으로 Least-to-most prompting 이라고 합니다.
프롬프트로는 To solve {question}, we need to first solve:
을 명시하는 것입니다. 또는 Perform the following actions: step1: … , step2: … step3: …
이렇게 step을 명시하면 됩니다.
Least-to-most prompting을 사용했을 때 복잡한 추론 문제에 대해 성능이 16% -> 99.7%로 향상되었다고 합니다.
예를 들어 다음 질문을 하는 프롬포트를 살펴봅시다.
Q: 다음 문제에 대해서 학생의 답안이 정확한지 여부를 판단해 주세요.
문제는 다음과 같습니다.
- 태양광 발전 시설을 건설하고 있는데, 재정 계획에 대한 도움이 필요합니다.
- 토지는 1 평방피트당 $100입니다.
- 태양광 패널을 1 평방피트당 $250에 구입할 수 있습니다.
- 매년 고정으로 $100,000의 유지 보수 비용과, 추가로 1 평방피트당 $10의 비용이 드는 계약을 체결했습니다.
- 첫 해 운영 비용의 총액은 평방 피트 수에 따라 어떻게 변하는지 구하세요.
Student Solution:
- 설치 규모를 평방 피트로 나타내는 변수를 x라고 합시다.
- 비용:
- 토지 비용: 100x
- 태양광 패널 비용: 250x
- 유지 보수 비용: 100,000 + 100x
- 총 비용: 100x + 250x + 100,000 + 100x = 450x + 100,000
A: The student's solution is correct.
모델이 곧바로 결론을 내도록 하면 정확하지 않은 결론을 내기도 합니다. 하지만 결론을 내기전에 모델이 스스로 계산하도록 하면 올바른 정답을 냅니다.
Q: 당신의 작업은 학생의 해결책이 정확한지 아닌지 판단하는 것입니다.
문제를 해결하려면 다음과 같이 하세요:
- 먼저 문제에 대한 자신만의 해결책을 찾으세요.
- 그런 다음 학생의 해결책과 자신의 해결책을 비교하여 학생의 해결책이 올바른지 평가하세요.
- 문제를 직접 풀기 전에 학생의 해결책이 정확한지 결정하지 마세요.
다음 형식을 사용하세요:
질문: (여기에 질문)
학생의 해결책: (여기에 학생의 해결책)
실제 해결책: (해결책을 계산하는 단계와 여기에 당신의 해결책)
학생의 해결책이 방금 계산한 실제 해결책과 같습니까? (예 또는 아니오)
A:
질문:
- 태양광 발전 시설을 건설하고 있는데, 재정 계획에 대한 도움이 필요합니다.
- 토지는 1 평방피트당 $100입니다.
- 태양광 패널을 1 평방피트당 $250에 구입할 수 있습니다.
- 매년 고정으로 $100,000의 유지 보수 비용과, 추가로 1 평방피트당 $10의 비용이 드는 계약을 체결했습니다.
- 첫 해 운영 비용의 총액은 평방 피트 수에 따라 어떻게 변하는지 구하세요.
학생의 해결책:
- 설치 규모를 평방 피트로 나타내는 변수를 x라고 합시다.
- 비용:
- 1. 토지 비용: 100x
- 2. 태양광 패널 비용: 250x
- 3. 유지 보수 비용: 100,000 + 100x
- 총 비용: 100x + 250x + 100,000 + 100x = 450x + 100,000
실제 해결책:
- 설치 규모를 평방 피트로 나타내는 변수를 x라고 합시다.
- 비용:
- 토지 비용: 100x
- 태양광 패널 비용: 250x
- 유지 보수 비용: 100,000 + 10x
- 총 비용: 100x + 250x + 100,000 + 10x = 360x + 100,000
학생의 해결책이 방금 계산한 실제 해결책과 같습니까?
- 아니오
LLMs 가 특정 테스크에서 최대 성능을 얻기 위한 방법으로 Fine-tune 을 하는 방법이 있습니다. Few-shot 이 1~2 개의 에시만 주는 반면에 Fine-tune 은 수천개의 예시를 더 제공해주는 것을 말합니다.
이런 예시를 만들어야 하기 때문에 비용이 비싸다는 단점이 있습니다.
근데 STaR (Self-taught Reasoner) 방식을 이용하면 이 Fine-tune 의 비용을 줄이면서, 기존의 Fine-tune 보다 성능이 더 잘나온다고 합니다.
방법은 다음과 같습니다.
프롬프트는 반복적인 개발 프로세스(Iterative Prompt Development)를 통해 개발됩니다.
특별히 복잡한 것은 없습니다. 분석하고 개선하는 노력이 필요할 뿐입니다.
프롬프트 개발 프로세스는 다음과 같습니다.
1. LLMs에게 명확하고 구체적인 지시를 전달합니다.
2. 원하는 결과가 나오지 않았다면 왜 그런지 분석합니다.
3. 이를 바탕으로 프롬프트를 수정(refine)합니다.
4. 1-3 과정을 반복합니다.
앤드류 응(Andrew Ng) 교수님은 효과적인 프롬프트 엔지니어조차도 처음부터 모든 프롬프트를 완벽하게 알고 있지 않을 것이라고 말씀하십니다. 단지 이 과정을 잘 수행할 뿐입니다.
결론적으로, 프롬프트를 잘 작성하려면 다음과 같은 요소들을 고려해야 합니다.