이번 포스팅에서는 6개월간 GPT API를 활용한 LLM 서비스를 개발하면서 가장 효과 있었다고 생각한 Prompt Engineering 기법 5개를 소개해볼게요. 지극히 개인적인 의견이고, GPT API에만 적용해본 사실이므로 실제 적용시에 충분한 검증을 진행하고 사용하시는 것을 추천드립니다! 😜

1. Prompt Chaining

 

Prompt Chaining – Nextra

A Comprehensive Overview of Prompt Engineering

www.promptingguide.ai

제가 서비스를 개발하며서 프롬프트를 작성해본 결과 프롬프트를 작성할 때 성능을 좌지우지하는 가장 큰 요소는 명확한 지시와 복잡한 Task의 분할이라고 느꼈습니다. 모델의 성능이 높아지고, Context Window 사이즈가 커지면서 엄청 긴 프롬프트도 모델이 잘 처리하게 되었지만, 실제로 사용하다 보면 Lost in Middle 현상이 엄청 심하다고 느꼈고, 중간중간 지시한 내용을 잘 이해하지 못하는 경우를 많이 경험했습니다. 프롬프트에 많은 요구사항이 들어가고 여러 업무를 지시하게 되면 좋지 못한 결과가 나오는 경우가 대부분이여서 여러 업무를 지시해야할 경우에는 프롬프트를 나누어서 작성하고, 결과를 잘 연결시키는 것이 효과가 좋았습니다. Prompt Chaining은 이런 문제에 대한 간단한 해결 방법론이고, 업무의 연결성을 잘 구조화해서 작은 업무의 단위로 나누어서 진행하는 것에 대한 방법론입니다. 저는 우선 하나의 프롬프트로 모든 업무를 작성하고, 나눌 수 있는 업무에 대해서 정의해서 프롬프트를 분리해서 서로의 결과를 연결시키는 방식으로 작업을 하는 방법이 좋았던것 같아서 대체적으로 그렇게 작업을 했는데, 더 좋다고 생각하는 방식이 있는 분은 댓글로 알려주시면 감사하겠습니다 😉

2. CoT - Chain of Thought & Few Shot

 

Few-Shot Prompting – Nextra

A Comprehensive Overview of Prompt Engineering

www.promptingguide.ai

 

이 두가지 기법은 사실 충분한 검증이 필요도 없이 무조건 사용하시면 되는 검증된 기법이긴 합니다. 그래서 나눠 작성하지 않고, 한번에 작성했습니다. 내맘대로 해석으로 CoT 기법은 사람의 인지구조와 비슷한 형태로 LLM의 추론 과정을 구성한 기법이라고 이해했습니다. 사람은 내일의 날씨를 생각하면 '오늘 구름이 많이 꼈고, 매우 습하기 때문에 내일 비가 올 수 있겠구나.'라는 생각을 하는데, LLM에게 내일의 날씨를 물어보면 이런 생각을 하기 어렵습니다. 물론 지금의 GPT-4o 이상의 모델은 이정도는 생각합니다...😅 하지만 더 어려운 질문을 하게 된다면 할 수 있을까요? 그래서 어려운 질문을 하거나 좀 더 좋은 결과를 얻기 위해 LLM에게 추론 과정을 제시해주는 것입니다. 내일의 날씨를 물어볼때, "오늘의 구름이 어느 정도인지 분석 & 오늘의 습도가 어느 정도인지 분석 -> 이를 바탕으로 내일의 날씨를 알려줘." 이런식으로 추론 과정에 이유를 추가해서 생각할 수 있도록 제시해주어서 답변의 질을 올리는 기법입니다.
그리고 Few Shot 기법은 몇개의 답변 예시를 질문과 함께 제시해주는 것입니다. 내맘대로 해석으로 프롬프트로 가볍게 Fine Tuning을 한다고 이해했습니다. Fine Tuning시에 본인이 원하는 방향의 데이터를 만들어서 Fine Tuning 후 예측을 하면 좀 더 알맞은 답을 내놓는 것처럼 몇가지 질문에 원하는 답변을 작성해서 같이 제공해주면 작성한 답변과 비슷한 답변을 작성해줍니다. 이때 경험적으로 적당한 Few Shot의 갯수는 3개 정도였습니다. 만약 답변이 Strict하게 나오길 원한다면 Few Shot으로 넣어주는 답변을 비슷한 형태로 구성해서 제공해주면 더 Strict하게 나오고, 좀 더 General한 답변을 원한다면 Few Shot으로 넣어주는 답변을 다양하게 구성해서 제공해주면 좀 더 General한 답변의 형태가 나옵니다.

3. Instruction & Role

Instruction & Role은 LLM에게 성격 및 역할을 부여해서 답변을 하도록 하는 것입니다. 개인적으로는 다른 무엇보다 이게 제일 효과적인 방법이었던 것 같습니다. 대화에서 신뢰도는 말을 어떻게 하는지, 본인의 말에 얼마나 설득력이 있는지에 따라 달라진다고 생각합니다. Task에 적절한 성격이나 역할을 부여하게 된다면 답변의 질이 올라가는건 당연한 이야기이고, 틀린 답변에도 틀린 이유가 생기는 것을 경험했습니다. 왜 이런 성능 향상이 있을까? 라는 생각을 했을때, 제 개인적으로 생각한 가설은 질문을 할때 GPT에게 Instruction을 설정하고 질문을 시작하면, 질문의 답변을 생각하기 전에 GPT가 어떤 질문이 올지를 생각하고 그에 대한 정보나 지식을 참고해서 답변하려고 준비를 할 수 있어서 그렇지 않을까라는 가설을 생각했습니다. 물론 이 가설은 검증하기도 불가능하고, 말도 안되는 말이라고 생각할 수 있겠지만, 현재 GPT의 추론 과정은 Black Box로 이론적으로 접근하면 이해하기 굉장히 어려운 영역인 것 같아 개인적으로 이런식의 의미부여를 해서 이해하고 있습니다... 좀 더 좋은 추론이나 가설이 있다면 댓글로 남겨주시면 감사하겠습니다 ㅎㅎ

4. Formatting

이건 뭐 논문을 읽은 것도 아니고, 개인적으로 Json 형태의 출력을 하거나 Service의 결과를 GPT로 만들때 결과를 구조화하기 위한 방법으로 제가 개인적으로 사용했던 방법입니다. Service의 결과를 Parsing 없이 GPT로 생성하기 위해서는 GPT의 결과가 Strict한 구조를 지키면서 나와야 합니다. 뭐 예상치 못한 결과가 나왔을때 재시도 하는 로직을 추가해서 확률적인 해결을 하는 방법을 추가해놓으면 언젠가는 해결되는 문제지만, 10번 중 3번의 예상치 못한 결과가 나온다면 Service가 불가능하기 때문에 확률을 낮춰야해서 사용한 기법이라고 보시면 될 것 같습니다. 제가 사용했던 방법 중 가장 잘 먹혔던 방법을 GPT가 작성해야 하는 부분은 (var1), (var2) 이런식으로 작성하고, # Format의 태그안에 (var1)에 대한 설명, (var2)에 대한 설명을 추가하는 방식으로 작성한 것이 가장 효과가 좋았습니다. 이건 다들 실험을 통해서 Strict한 방식의 결과를 만들기 위해 여러 포맷을 사용해봐야 하는 문제라 조심스럽지만, 이런 고민을 하고 계신 분에게 저의 방법이 조금이나마 도움이 될 것 같습니다.

5. 단어 수 제한보다는 문장 수 제한

LLM Service를 개발할때 결과의 품질 측면에서 영어 영역에서는 단어 수 혹은 알파벳 갯수를 제한하는 것으로 성능이 올라간다는 내용의 아티클이 있어서 한글로도 시도를 해봤는데, 단어 수나 글자 수에 대한 제한이 거의 이루어지지 않았습니다. 영어에서는 잘 되는게 왜 한글에서는 안 될까 생각을 해봤는데, 영어로 학습한 모델인 만큼 단어 갯수나 글자 수가 영어에 맞춰져 있어서 영어 -> 한글로 바꾸는 과정에서 많은 오차가 있는 것이 아닐까? 라는 가설을 세웠습니다. 그래서 그렇다면 문장 단위는 어짜피 영어나 한글이나 같은데, 문장 단위로 제한을 하면 효과가 있지 않을까? 라는 가설로 문장 수를 제한해보았고, 실제로 거의 모든 경우 제한이 지켜졌습니다. 하지만 Prompt의 길이가 길어지면서 문장 수에 대한 제한은 효과가 서서히 안 좋아졌고, GPT에게 명령의 우선순위가 있는데, 문장 수 제한의 우선 순위가 굉장히 낮은 것이 아닐까? 그래서 프롬프트가 길어지면서 다른 명령을 우선시 하는 것이 아닐까? 라는 가설로 문장 수의 제한에 대한 우선 순위를 높이기 위해 다양한 방법을 시도했습니다. 문장 수 제한은 반드시 지켜달라는 문구나 중요한 고려사항으로 문장 수 제한에 대한 Context를 추가하는 것으로 어느 정도 해결이 됐습니다.

 

6개월간 LLM 서비스를 개발하면서 5개의 논문과 20개 정도의 방법론을 읽었더라고요...(물론 제가 다 읽은건 아니고, 반정도는 ChatGPT가 읽어줬지만요..😅) 이 과정에서 가장 힘들었던 점은 LLM의 방법론은 검증이 굉장히 모호하다는 점이었습니다. LLM 서비스를 개발하기 전 생성 모델이 아닌 Vision 모델과 추천 시스템 개발을 할때에는 평가 지표와 Task의 Align이 굉장히 잘 되어서 이해하고, 사용하는데 어려움이 없었는데, LLM의 경우 대부분의 방법론이 가정으로 이루어져 있다는 느낌을 받았습니다. 그래서 이 방법론을 Service에 사용해도 되는 것인지 검증은 어떻게 해야하는 것인지에 대한 고민이 많았습니다. 이런 고민을 하면서 체득한 방법이 방법론이 LLM에서 작동한 원리를 내맘대로 이해를 해보고, 그 이해한 방법으로 반복 사용해보면서 납득할 정도의 오차가 나오면 사용하자는 방법이었습니다. 아직 이런 방법이 완벽하게 납득이 된건 아니지만, LLM은 기존의 Supervised Train된 모델과는 다르기 때문에 어느 정도 타협을 하면서 이해해나가려고 노력중입니다.

 

다들 LLM 분야에서 연구를 하시면서 본인의 업무와 논문, 방법론을 어떻게 Align 시켰는지, 경험을 공유해주시면 좋을 것 같습니다!!!!

 

만약 틀린 내용이 있거나 수정이 필요한 부분이 있다면 댓글 남겨주시면 꼭 참고하도록 할게요 😉