2024. 3. 10. 20:12ㆍDevelopment
안녕하세요, 이번 시간도 저번 게시물에 이어 프롬프트 공학을 다뤄볼 거예요.
이번 게시물은 아래 게시물과 이어지는 내용이니 안 보신 분은 보는 걸 추천드려요.
Prompt Engineering: ChatGPT와 대화하기 1편
안녕하세요, 오늘은 ChatGPT 같은 LLM을 사용할 때 알면 좋은 내용인 프롬프트 공학(Prompt Enginnering)에 대해 다뤄보려고 해요. ChatGPT를 사용할 때, "Message ChatGPT..."에 물어보고 싶은 말들을 열심히 쓰
dalmeng-commeng.tistory.com
Prompt Engineering: ChatGPT와 대화하기 2편
안녕하세요, 이번 시간에는 저번 시간에 이어 프롬프트 공학을 다뤄볼 거예요. 이번 게시물은 아래 게시물과 이어지는 내용이니 안 보신 분은 보는 걸 추천드려요. Prompt Engineering: ChatGPT와 대화
dalmeng-commeng.tistory.com
이 글은 GPT 모델을 만든 OpenAI 사의 프롬프트 공학 가이드를 참고했어요.
https://platform.openai.com/docs/guides/prompt-engineering
1. 지시문을 명확하게 작성하라 - Write clear instructions
2. 참고할 수 있는 자료를 제공하라 - Provide Reference Text
3. 간단한 작업으로 나누어 진행하라 - Split complex tasks into simpler subtasks
4. 모델에게 생각할 시간을 주어라 - Give model time to think
5. 외부 도구를 활용하라 - Use External Tools
이 글에서 제가 사용한 모델은 모두 GPT-3.5와 GPT-4를 섞어서 사용했어요.
4. 모델에게 생각할 시간을 주어라 - Give model time to think
이전 게시물에서도 말했지만, GPT는 추론 능력이 뛰어나요. 그래서 GPT가 생각하기 좋은 환경을 만들어줄 수 있도록 만들어주는 것이 중요해요.
우리 사람도 생각하고 있는데 자꾸 옆에서 뭐라고 하면 생각이 잘 안 되는 것처럼요.
그렇다고 프롬프트에 "천천히 말해도 되니깐 충분히 생각하고 말해줘." 라고 작성하는 건 아니에요.
대신, "~를 해줘." 라고 결론만 요구하는 프롬프트보다는 "~에 대해서 너의 생각을 제시하고, 그걸 바탕으로 ~를 해줘."와 같이 추론을 먼저 시킨 뒤 결론을 내는 방식으로 생각할 시간을 주도록 할게요.
4 - 1. 추론 과정을 거쳐 결론을 내도록 하자 - Instruct the model to work out its own solution before rushing to a conclusion
초등학교 수준의 수학 문제를 예시로 모델에게 생각하는 시간을 주는 것이 어떤 의미인지 알아볼게요.
너는 수학 문제에 대해 학생의 풀이가 맞는지 판단해야 해.
하지만 학생의 풀이가 맞는지 판단하기 전에, 너가 먼저 풀고 너의 풀이를 토대로 학생의 풀이가 맞는지 판단해.
중요한 점으로, 학생의 풀이가 틀릴 수도 있기 때문에 너가 문제를 푸는 과정에는 학생의 풀이를 절대 참고하지 마.
너의 풀이가 끝난 뒤, 학생의 풀이를 보고 비교하며 학생의 풀이가 맞는지 판단해야 해.
학생의 답안을 평가하기 전 너가 답을 도출한 과정을 출력해. 그리고 학생의 답에 대해서 평가해.
[문제]
길이가 1,000m인 터널이 있고, 길이가 20m인 트럭이 있습니다.
트럭이 터널을 80km/h로 달리고 있다고 할 때, 트럭이 완전히 통과하려면 몇 초가 걸릴까요?
[학생의 풀이]
80km/h를 m/s로 환산하면 약 22.22 m/s이다. 터널의 길이가 1,000m이므로 터널을 통과하는 데에는 1,000 / 22.22 = 약 45.0초가 걸리게 된다.
[학생의 답]
45.0초
프롬프트를 보면 알 수 있듯이, 먼저 추론을 하라고 강조했죠? 그리고 그 과정에 학생의 답을 절대 참고하지 말라고도 강조했어요.
이로써 GPT는 자신의 추론 능력만 온전히 사용하여 문제를 풀게 되었어요.
이제 GPT의 답변을 볼까요?


결과를 보면 알 수 있듯이, 학생의 답안을 언급하지 않고 문제를 일단 푸는 것을 볼 수 있습니다. 그 후, 약 45.9초라는 결과를 도출했네요.
GPT가 문제를 푼 후, 그제야 학생의 답안을 검토하는 것을 볼 수 있습니다.
이 방법은 실제로 좋은 결과를 얻는데 도움이 된다고 하니 적극적으로 사용하면 좋은 효과를 볼 수 있을 거예요.

4 - 2. 강제로 추론 과정을 숨길 수도 있다 - Use inner monologue or a sequence of queries to hide the model's reasoning process
추론 과정을 숨긴다는 의미가 잘 와닿지 않는 분도 분명히 계실 거예요. "추론 과정을 받아보면 무조건 좋은 거 아닌가?"라고 생각하고 계시지 않으신가요?
하지만 어떤 서비스를 개발하냐에 따라 추론 과정을 드러내면 안 되는 경우도 있어요.
예를 들어, 학생의 답안을 검토하고 틀리면 풀이가 아닌 힌트를 주는 튜터 서비스를 개발하고 있다고 해볼게요.
모델에게 추론을 하도록 해서 정확도는 올려야 하는데, 추론 과정을 공개해버리면 풀이를 제공하는 것과 똑같죠.
하지만 그 추론 과정은 저장이 되어있어야 운영자나 개발자가 참고하기 좋겠죠.
따라서 추론 과정을 볼 수는 있게는 하되, 사용자가 보게 해서는 안 돼요. 이걸 어떻게 구현할 수 있을까요?
내적 독백(Inner Monologue)을 하도록 지시할 거예요.
물론 "추론 과정을 속으로만 생각하고 드러내지는 마."라고 말하는 건 아니에요.
드러내지 말아야 하는 내용(추론 과정)과 드러내야 하는 내용(힌트)을 형식을 다르게 하여 출력하도록 지시할 거예요.
아까와 같은 문제를 예시로 사용할게요.
너는 아래 과정을 거쳐 수학 문제에 대해 학생의 풀이가 맞는지 판단해야 해.
1. 먼저 너가 주어진 문제를 풀어. 이 과정에서 학생의 풀이가 틀릴 수도 있기 때문에 학생의 풀이를 절대 참고하지 마. 이 결과를 출력할 때는 큰 따옴표 세 개로 둘러싸. (예시: """풀이를 여기에...""")
2. 다음으로 너의 풀이와 학생의 풀이를 비교하고 그 결과를 분석해. 이 결과 역시 출력할 때는 큰 따옴표 세 개로 둘러싸. (예시: """분석 결과를 여기에...""")
3. 만약 학생의 풀이 과정과 답이 맞았으면 "맞았습니다!"를 출력하고, 그렇지 않으면 간단한 힌트를 제공해야 해. 이 경우에는 "틀렸습니다. 하지만 ~를 참고해보세요."라고 출력하면 돼. 이 과정의 출력은 큰 따옴표로 둘러싸지 말고 그냥 출력해.
[문제]
길이가 1,000m인 터널이 있고, 길이가 20m인 트럭이 있습니다. 트럭이 터널을 80km/h로 달리고 있다고 할 때, 트럭이 완전히 통과하려면 몇 초가 걸릴까요?
[학생의 풀이]
80km/h를 m/s로 환산하면 약 22.22 m/s이다. 터널의 길이가 1,000m이므로 터널을 통과하는 데에는 1,000 / 22.22 = 약 45초가 걸리게 된다.
드러내지 않고 싶은 내용은 큰 따옴표 세 개로 둘러싸서 출력하라고 했고, 힌트는 큰 따옴표 없이 그냥 출력하라고 지시했어요.
따라서 드러내지 않고 싶은 내용과 드러내고 싶은 내용의 출력 형식을 다르게 한 거죠.
아래는 출력 결과입니다.


앞선 두 단계는 내적 독백 처리했으므로 큰 따옴표로 둘러싸인 것과 힌트는 큰 따옴표 없이 출력된 것을 알 수 있죠?
이와 같이 내적 독백을 통해 드러내지 않고 싶은 내용과 드러내고 싶은 내용을 구분할 수 있어요.
이제 내적 독백의 의도는 알겠어요. 그러면 이 점을 어떻게 활용해야 할까요?
아래와 같이 프로그래밍 언어로 파싱할 때, 그 진가가 드러나요.
드러내고 싶지 않은 내용이 어떻게 다뤄지는지 알기 때문에 프로그래밍 언어로 파싱(Parsing)하기 쉬워요.
def parse_result(result):
result = [s for s in result.strip("\n").split("\"\"\"") if len(s.strip("\n"))]
return {
"infer_process": result[0],
"answer_analysis": result[1],
"hint": result[2]
}
{
'infer_process': '주어진 문제를 기반으로 계산하면, ...',
'answer_analysis': '학생은 트럭이 터널을 통과하는 데 45초가 걸린다고 계산했습니다. ...',
'hint': '틀렸습니다. 하지만 트럭이 터널을 완전히 통과하기 위해선 터널 길이와 트럭 길이의 합을 이동해야 한다는 점을 참고해보세요.'
}
꼭 내적 독백 형식을 활용할 필요 없이, 결과를 아예 JSON 형식으로 활용하기 좋도록 받는 방법도 있어요. (사실 이 방법이 더 편하고 널리 쓰이는 듯 해요.)
JSON으로 결과를 받아볼 수 있도록 아래와 같이 프롬프트를 수정해보았어요.
너는 아래 과정을 거쳐 수학 문제에 대해 학생의 풀이가 맞는지 판단해야 해.
1. 먼저 너가 주어진 문제를 풀어. 이 과정에서 학생의 풀이가 틀릴 수도 있기 때문에 학생의 풀이를 절대 참고하지 마.
2. 다음으로 너의 풀이와 학생의 풀이를 비교하고 그 결과를 분석해.
3. 만약 학생의 풀이 과정과 답이 맞았으면 "맞았습니다!"를 출력하고, 그렇지 않으면 간단한 힌트를 제공해야 해. 이 경우에는 "틀렸습니다. 하지만 ~를 참고해보세요."라고 출력하면 돼.
결과는 JSON 형식이야. 아래 예시를 참고해.
{
"infer_process" : "과정 1의 결과를 여기에...",
"answer_analysis": "과정 2의 결과를 여기에...",
"hint": "과정 3의 결과를 여기에..."
}
[문제]
길이가 1,000m인 터널이 있고, 길이가 20m인 트럭이 있습니다.
트럭이 터널을 80km/h로 달리고 있다고 할 때, 트럭이 완전히 통과하려면 몇 초가 걸릴까요?
[학생의 풀이]
80km/h를 m/s로 환산하면 약 22.22 m/s이다.
터널의 길이가 1,000m이므로 터널을 통과하는 데에는 1,000 / 22.22 = 약 45초가 걸리게 된다.
답 : 약 45초

이러면 바로 결과를 받아 파이썬의 json 라이브러리의 json.loads(result) 함수를 이용해서 바로 활용할 수 있겠죠?
오늘 내용은 여기까지입니다.
GPT-4는 특히 추론 능력이 좋으니 그 능력을 최대로 활용할 수 있도록 해줍니다!
그리고 결과 형식을 정의하는 것도 결국 저희가 하는 거예요. 내적 독백 방식을 활용하여 결과를 아예 바로 활용할 수 있도록 Json으로 받는 것도 매우 자주 사용되니 반드시 알아두는 게 좋아요.
다음 글에는 드디어 프롬프트 공학을 마무리 해볼게요.
제 글이 많은 도움이 되었길 바라며,
긴 글 봐주셔서 감사합니다!
멋진 개발자가 되기 위해 더 열심히 달리겠습니다!
- 달맹 -
'Development' 카테고리의 다른 글
| 로그 공유 시스템 만들기 : AWS EKS & EFS (0) | 2024.03.12 |
|---|---|
| Prompt Engineering: ChatGPT와 대화하기 4편 [끝] (0) | 2024.03.10 |
| Prompt Engineering: ChatGPT와 대화하기 2편 (0) | 2024.03.10 |
| TOPCIT 체험기 [문제 예시, 유형, 후기] (0) | 2024.03.10 |
| Prompt Engineering: ChatGPT와 대화하기 1편 (0) | 2024.03.09 |