본문 바로가기

공부/AI

[Project] 프롬프트 엔지니어링 사이드 프로젝트 개발기

 

🚀 Prompt Enhancer (프롬프트 엔지니어링 자동화 AI 툴) 사이드 프로젝트 개발기 

얼마 전에 사이드 프로젝트로 프롬프트 엔지니어링을 자동화할 수 있는 툴을 개발해보았다. 그래서 사이드 프로젝트를 진행하면서 문제 정의와 해결 과정, 앞으로 추가적으로 보완하고 싶은 점들에 대한 회고를 해보고자 한다. 

 

 

📌 프로젝트 소개, 깃허브 및 링크 

프로젝트 깃허브 : https://github.com/lim-hyo-jeong/Prompt-Enhancer

⭐ 프로젝트 링크 : https://prompt-enhancer.streamlit.app/

 

Prompt Enhancer는 최신 논문 연구 결과에서 검증된 프롬프트 엔지니어링 스킬들을 곧바로 사용해볼 수 있는 프롬프트 엔지니어링 자동화 툴이다. 또한 사용자가 적용할 프롬프트 엔지니어링 스킬을 개별 선택하여 각 스킬 적용을 AI를 통해 자동화할 수 있다. 

 

 

 

📌 아이디어 도출

예전부터 프롬프트 엔지니어링을 자동화하는 툴을 만들어봐야 겠다는 생각을 했었다. 프롬프트를 발굴하거나 개선하는 업무를 하면서, 여러가지 프롬프트 엔지니어링 기법을 정리해두고 직접 적용을 해보곤 했는데 이러한 방식이 자동화 및 체계화가 되면 좋겠다는 생각이 들었기 때문이다. 

그러던 도중, 3주 전에 "Principled Instructions Are All You Need for Questioning LLaMA-1/2, GPT-3.5/4"라는 논문을 접했는데, 이 논문에서는 효과적인 프롬프트 엔지니어링의 원칙을 26가지로 정리하고 있었다. 특히 인상 깊었던 점은, 단순히 어떤 기법이 경험적으로 효과가 좋았다는 것을 넘어서, ATLAS라는 별도의 프롬프트 엔지니어링 성능 검증 데이터셋을 통해 각 원칙의 성능을 boosting과 correctness 두 가지 측면에서 평가하고 그 효과에 대한 근거를 객관적으로 제시했다는 점이었다. 그래서 이 논문에서 정리된 프롬프트 엔지니어링 원칙들을 기반으로 프롬프트를 자동 개선해주는 프로그램을 만들어본다면 좀 더 체계적인 구성이 가능할 것 같다는 판단이 들었다.

 

📌 아이디어의 구체화 

‘프롬프트 엔지니어링 AI 자동화 툴을 만들어봐야 겠다!’라는 생각을 한 후에, 아이디어를 좀 더 디벨롭하기에 앞서서 이러한 고민을 해보았다.

이미 시중에 프롬프트 엔지니어링 툴이 많은데 굳이 내가 더 만들 필요가 있을까?

 

 

사실 이미 프롬프트를 개선해주는 AI 서비스들이 시중에 많아졌다. 커스텀 GPT에도 있고, 그냥 구글링으로 검색해봐도 많은 서비스들이 존재한다. 심지어 저 논문에서 제시된 원칙을 기반으로 프롬프트 엔지니어링을 적용해주는 서비스도 존재하였다.

그리고 직접 써본 결과 이러한 기존 서비스들의 프롬프트 엔지니어링 자동화 품질이 좋았다. 그렇지만 기존에 존재하는 서비스들은 프롬프트 엔지니어링을 포괄적으로 적용하고 있었기 때문에, 가끔 적용하고 싶지 않은 기법들도 적용될 때가 있었고 내가 구체적으로 원하는 기법이 있는데 그것이 적용되지 않는 경우도 있었다. 그래서 나는 이미 존재하는 프롬프트 엔지니어링 툴도 좋지만, 다양한 프롬프트 엔지니어링 기법들을 한꺼번에 적용해서 개선해주는 기능은 이미 많으므로 각 프롬프트 엔지니어링 기법들을 세분화해서 사용자가 필요로 하는 기법들을 선택하고 각각의 선택된 기법을 적용하여 프롬프트를 좀 더 개선해주는 기능이 필요하다고 느꼈다. 또한 여러가지 기법을 선택한다면 각 기법이 적용되는 단계별로 어떻게 개선이 되는지를 점진적으로 확인할 수 있게끔 하면 좋을 것 같았다. 그리고 내가 자주 쓰는 매직 프롬프트들(예를 들어 Emotional Prompt인 "This is very important to my career"나 제로샷 CoT로 알려져있는 "Take a deep breath and work on this problem step-by-step” 등)이 있는데 프롬프트 개선 작업이 이루어질 때 스킬 적용과 더불어 매직 프롬프트을 포함하여 통합적으로 개선된 프롬프트를 도출한다면 쓰기에 편할 것이라는 생각을 했다. 

 

그래서 "이미 시중에 프롬프트 엔지니어링 툴이 많은데 굳이 내가 더 만들 필요가 있을까?"라는 질문을 스스로에게 던져보고 그에 대한 답으로, 다음과 같은 요소들을 반영하여 차별화를 해봐야 겠다고 생각했다. 

 

1. 최신 논문 연구 결과에서 검증된 프롬프트 엔지니어링 스킬들을 곧바로 사용해볼 수 있는 툴

2. 프롬프트 엔지니어링 기법 중 사용자가 스킬을 개별 선택할 수 있고 각 스킬 적용을 AI를 통해 자동화할 수 있는 툴 

3. 여러가지 스킬을 선택할 경우 스킬 적용 단계별로 프롬프트 개선 결과를 확인할 수 있는 툴

4. 매직 프롬프트를 곧바로 포함할 수 있는 툴

 

 

📌 기술 스택 정하기 

아이디어를 구체화하면서 자연스럽게 기술 스택도 정할 수 있었다. 우선 LLM을 통해 프롬프트 엔지니어링을 자동화하기로 하였으므로 모델이 필요했다. 모델에도 여러가지 옵션이 있지만 일단은 가장 대중적인 OpenAI 모델들을 사용하기로 결정했다. 그리고 랭체인은 필수적으로 필요한 건 아니었지만 LLM 연결이 직관적이고 앞으로 다른 기능을 추가한다면 랭체인이 갖고 있는 강점이 많아서 선택하게 되었다. 또한 이러한 서비스를 웹으로 구현하고 배포하기에 streamlit이 빠르고 간편하게 사용할 수 있어서 사용하였다. 

 

1. Streamlit: 웹 UI 구현 및 배포

2. LangChain: 랭체인을 통해 LLM 연결 및 응답 생성

3. OpenAI API: 프롬프트 엔지니어링을 진행할 AI 모델을 서비스에 연결

4. Prompt Engineering : 사용자가 선택한 프롬프트 엔지니어링 스킬을 AI로 자동화하여 적용하기 위해 AI에 해당 스킬을 적용하게끔 하는 프롬프트 엔지니어링 템플릿 제작

 

 

📌 필수 기능 및 UI 설계 

Prompt Enhancer에서 필수적인 기능을 OpenAI API KEY 입력 부분, 프롬프트 엔지니어링 스킬 선택 부분, 매직 프롬프트 선택 부분, 사용자 프롬프트 입력 부분으로 정의하고, 페이지에 각각의 부분을 어떻게 할당할지에 대하여 고민을 했다. 레이아웃을 구상하는 과정이 좀 오래 걸렸던 것 같다. 프롬프트 입력 부분과 스킬 선택 부분이 자연스럽게 연결될 수 있도록 “내가 사용자라면?” 이라는 질문을 던져보고 레이아웃을 여러 차례 수정하는 과정을 거쳤다.

 

결과적으로, 컬럼을 두개로 나눠서 스킬 선택과 프롬프트 입력 부분이 한꺼번에 보이게끔 구성하는 것이 가장 좋겠다고 생각이 들었다. 그리고 스킬 선택 버튼도 토글과 체크박스 중 어떤 것이 더 직관적으로 와닿을 수 있을지, 스킬 선택과 매직 프롬프트 포함 여부 각각을 일렬로 구성할지 또는 나눠서 배치할지, 프롬프트를 개선할 AI 모델을 어떻게 선택할 수 있게 할지, API 키 입력도 사이드바에 배치할지 그냥 화면 페이지에서 곧바로 보이게끔 할지 팝오버 방식으로 가능할게 할지 등등을 고민하면서 화면 레이아웃 구성에 신경을 많이 쓴 것 같다. 나중에 이런 레이아웃 배치를 어떻게 하면 효율적이면서 직관적으로 할 수 있을지에 대한 공부도 더 해보고 싶다.

 

 

📌  서비스에 구현할 프롬프트 엔지니어링 기법 선택 

 

어떤 프롬프트 엔지니어링 기법을 적용할 수 있게끔 할까? 

또한 논문에서 정리된 프롬프트 엔지니어링 원칙 26가지 중 어떤 것을 사용자에게 선택 옵션으로 제공할지 선택하는 것도 고민이 필요하였다. 그래서 샘플 프롬프트들을 몇개 설정해두고 해당 샘플들에 26가지 원칙들을 각각 개별적으로 적용해보면서 AI로 개선이 용이하면서도 효과적인 스킬들을 선별하였다.

우선 논문에서는 26가지 원칙을 총 5가지 카테고리로 분류하고 있었는데, 이 중에서 User Interaction and Engagement 카테고리의 프롬프트들은 LLM과 사용자가 상호작용을 하면서 효과적인 결과를 도출하는 ‘과정적인’ 측면에 초점이 맞추어져 있기 때문에 프롬프트의 개선된 결과를 도출하는 작업에서 이 카테고리의 스킬들을 적용하기가 어려워 보였다. 만약 이 기법들을 적용할 경우에는, 아예 LLM과 사용자가 대화를 할 수 있는 chat UI를 탭으로 따로 구성하고, 사용자가 프롬프트를 입력할 때마다 LLM이 해당 프롬프트의 요청에 답하기 위해서 필요한 정보를 충분히 확보할 수 있도록 사용자에게 재질문을 하게끔 유도하는 시스템 프롬프트를 넣어서 구현하면 될 것이라는 생각이 들었다. 그러나 나는 프로젝트를 시작하면서, 서비스를 간단하게라도 3월 안에 완성하는 것이 목표였다. 즉, 1차적으로는 즉각적인 적용이 가능한 스킬들을 중심으로 구성하고자 했다. 이에 따라, 과정적인 상호작용을 요구하는 ‘User Interaction and Engagement’ 카테고리의 스킬들은 초기 단계에서는 제외하고, 추후 서비스의 기능을 확장할 때 추가하는 방향으로 결정하였다.

또한 굳이 LLM으로 개선할 필요가 없이 템플릿으로 만들어서 사용자가 빈칸만 넣으면 되는 스킬들도 존재하였다. Explanation Prompts, Style mimicking, Continuation Prompt, Code Generation 등이 있었다. 예를 들어 “Explain [specific topic] in simple terms.([주제]에 대하여 간단한 용어로 설명하세요.)”과 같은 프롬프트는 템플릿으로 주제만 사용자가 채워넣을 수 있으면 되는 형태이다. 이러한 스킬들은 구현하기엔 간단하지만, 따로 템플릿 탭으로 모아서 사용하게끔 하는게 좋을 것 같아서 나중에 기능 확장을 할 때 추가할 예정이다. 

한편, LLM으로 개선할 필요도 없고 템플릿도 필요 없고 그냥 곧바로 문구를 추가하여 LLM의 출력 결과를 개선할 수 있는 프롬프트들, 일명 매직 프롬프트라고 불리는 문장들은 사용자가 체크박스로 선택하게 하여 최종적인 개선된 프롬프트 결과에 추가되는 방식으로 구성하였다. 이 때 이러한 매직 프롬프트들은 문장 맨 앞에 구성할지, 맨 뒤에 넣을지를 고민하다가 프롬프트 사용 사례들을 구글링하면서 일반적으로 사람들이 쓸 때 가장 빈도가 높게 배치되는 순서로 구성되게 하였다. 

 

 어떤 순서로 기법이 적용되게끔 할까?

이런저런 테스트를 해보니 문제점이 있었다. 개별 스킬을 하나씩 적용하면 프롬프트 개선이 효과적으로 이루어지는 편이지만, 여러가지 스킬들을 일괄 적용하면 적용되는 순서에 따라서도 개선 결과가 달라지기도 하고 충돌되는 케이스들도 존재하였다. 예를 들어 순서에 따라 개선 결과가 달라지는 경우는, Few-Shot Prompting, Audience Integration, Role Assignment과 같이 프롬프트를 좀 더 구체화하는 스킬들이 먼저 적용되고 No Politeness와 같이 프롬프트를 간결하게 만드는 스킬이 나중에 적용될 경우 앞에서 적용한 스킬의 결과가 무시되는 경우들이었다. 그래서 프롬프트 엔지니어링 스킬들을 조합별로 다르게 하여 어떻게 결과가 도출되는지를 확인하여, 가장 원활하게 개선의 흐름이 이루어지는 순서를 찾아 적용해주었다. 

그럼에도 불구하고 순서와 상관없이 아예 스킬들 자체가 충돌되어 버리는 경우도 있었다. 가령 Impertavie Task는 Your task is"(당신의 작업은)또는 "You MUST"(반드시)와 같은 표현을 추가한다는 스킬이고, Penalty Warning은 "You will be penalized" (페널티를 받을 것)이라는 표현을 추가하는 스킬인데 둘 다 모델에게 특정 부분을 강조하는 목적이기 때문에 표현이 충돌하곤 한다. 한편, Guideline Indicators는 모델이 콘텐츠를 생성하기 위하여 따라야 할 요구사항을 키워드, 제약사항, 힌트, 지시 등의 형태로 명확하게 명시하는 것인데, Formatted Prompt의 경우 포맷팅이나 여러개의 줄바꿈을 통하여 지시사항, 예시, 질문, 맥락, 입력 데이터를 구분하는 것이라 두개를 동시에 쓸 경우 다른 하나의 적용이 제대로 이루어지지 않을 때가 많았다. 이런 경우 함께 선택되는걸 방지하도록 하는 것도 생각해보았는데 사용자의 자유도를 제한할 수도 있을 것이라는 생각이 들어서 일단은 warning에 '몇몇 스킬들은 함께 적용할 경우 충돌될 수 있다'는 점만 명시해두었다. 이 부분도 이후 좀 더 다양한 샘플에 대하여 여러 스킬 조합의 실험을 해보면서 확률적으로 충돌이 잘 되는 스킬을 정리해두고, 만약 사용자가 충돌되는 스킬들을 함께 선택할 경우 경고 메시지가 뜨게 한다는 식으로 보완 방식을 생각하게 되었다. 

그리고 애초에 사용자가 적용할 스킬을 개별적으로 선택하게끔 하려던 이유는, 기존에 존재하는 프롬프트 엔지니어링 툴들이 일괄적으로 여러가지 프롬프트 엔지니어링 스킬들을 적용하면서 생략되는 스킬들이 많았기 때문에 사용자가 직접 선택을 하는 자유도를 주고 싶었던 것이었다. 이러한 측면에서 가장 중요한건 여러 스킬을 선택할 때 충돌되는 스킬이 동시에 선택되는 걸 방지하는 것보다는, 여러 스킬을 한꺼번에 적용할 때 프롬프트가 개선되는 각 단계를 점진적으로 사용자가 확인할 수 있게 하여서 충돌되는 케이스가 발생할 경우 사용자가 스킬 선택을 조정할 수 있는 가능성을 열어두는 것이라고 생각이 들었다. 그래서 스킬 적용의 각 단계를 사용자가 바로바로 확인할 수 있게끔 해두었다. 

 

 

📌  LLM을 통한 '프롬프트 엔지니어링 기법 적용 프롬프트' 만들기 

프롬프트 엔지니어링을 LLM을 통해 자동화할 것이므로, 이러한 스킬을 적용하여 프롬프트를 개선하도록 LLM에 입력할 '프롬프트 엔지니어링 적용 프롬프트'를 만들어두었다. 대략적으로 프롬프트 엔지니어링 스킬에 대한 설명, 해당 스킬의 목적, 스킬 적용 예제, 요구사항(사용자가 입력한 프롬프트에 해당 스킬을 적용해서 개선된 버전으로 출력)으로 구성하였다. 이 때 GPT-4로는 간단히 입력해도 잘 개선해주지만 GPT-3.5 기준으로도 개선이 잘 이루어지도록 하고 싶었기 때문에 GPT-3.5 기준으로 테스트를 해서 스킬의 목적이나 예제 등을 명시해주는 방향으로 해두었는데 만약 다음에 기능 확장을 할 경우 사용자가 선택하는 모델 종류에 따라 다르게 '프롬프트 엔지니어링 적용 프롬프트'를 구성해볼 생각이다. (GPT-4는 좀 더 간단하게 하고 GPT-3.5는 요구사항을 좀 더 명확하게 구체화하는 식으로) 

또한 각 스킬을 적용할 프롬프트 뿐만 아니라 시스템 프롬프트를 구성하여 프롬프트 엔지니어링에 대한 역할을 강조하고 스킬 적용 과정에서 유의할 사항들을 명시해두었다. 

 

 

📌  추가 계획 및 느낀 점

일단 아이디어를 생각하고 3월 내로 빠르게 완성하는게 목표였기 때문에 기본적으로 필요한 기능들 위주로 구현을 하였다. 구현을 하고나니 좀 더 보완하고 싶거나 추가하고 싶은 기능들이 보여서 차근차근 작업해볼 계획이다. 

 

 추가 계획 

1. 현재까지는 사용자가 직접 적용할 프롬프트 엔지니어링 스킬을 선택하게끔 했는데 추가적으로 사용자 입력 프롬프트에 적용하기에 적절한 스킬을 자동적으로 판단하고 적용해주는 Automated Prompt Engineering 기능을 추가하고 싶다. 

2. 지금까지는 어떤 언어로 입력해도 영어로 변환해서 개선된 프롬프트를 반환하였다. 왜냐하면 LLM에게는 다른 언어의 답변을 원하여도 프롬프트 자체는 일반적으로 영어로 입력하는 것이 결과물이 좋기 때문이다. 그렇지만 한국어 언어 기반 모델을 사용하거나, 한국 지역에 특화된 쿼리를 입력하는 경우에는 입력 프롬프트의 언어를 유지해야 한다. 그래서 입력 프롬프트의 언어를 개선된 프롬프트의 언어에서도 유지하는 옵션을 추가하려고 한다. → 기능 추가 (입력 프롬프트의 언어로 개선 프롬프트가 나오게끔 디폴트로 설정하였고, 개선 프롬프트를 영어로 받고자 할 경우 선택하게끔 옵션을 주었다)

3. 지금은 최종 결과물로 개선된 프롬프트만 반환하고 있는데, 개선된 프롬프트로 곧바로 LLM에게 답변을 받고, 사용자의 기존 프롬프트로도 답변을 받아서 두개를 비교해주는 옵션도 추가해볼지 고민 중이다. 

4. 템플릿 탭을 별도로 만들어 두고자 한다. 예를 들어, Explanation Prompts, Style mimicking, Continuation Prompt, Code Generation 등이 있었다. 가령 “Explain [specific topic] in simple terms.([주제]에 대하여 간단한 용어로 설명하세요.)”과 같은 프롬프트 템플릿을 모아두는 것이다. 

5. 사용자와의 상호작용이 필요한 ‘User Interaction and Engagement’ 카테고리의 스킬을 chat UI로 구현하고 싶다. 이건 좀 까다로울 것 같아서 가장 후순위로 생각하고 있다. 

 

 느낀 점

1. streamlit을 처음 써봤는데 제한 사항이 많기는 했지만 프로토타입 정도의 웹서비스를 구현하고 배포하기에 매우 간편해서 앞으로 다른 서비스를 만들 때 또 이용할 것 같다.

2. 프롬프트 엔지니어링이라는 직무와 직접적으로 연결된 사이드 프로젝트를 해보니 재미있었다. 현재는 초기 기능들만 구현했는데 추가적으로 구현하고 싶은 기능들이 더 생겨서 앞으로 시간 날 때 틈틈이 작업해보려고 한다.

3. 구현을 하는 과정에서 추가하고 싶은 기능이 너무나 많았지만 일단은 빠른 완성이 목표였기 때문에 기본 기능 외에는 다음에 추가하는 것으로 계획해두었다. 이렇게 하니까 좋은 점은 일단 프로젝트 하나를 완성했으므로 구현의 각 단계에서 생기는 문제들을 정의해두고 이후에는 그에 맞춰서 추가 기능만 쌓으면 되니까 좀 더 수월해진다는 것이다. 다만 완성 이후에는 다소 게을러지는 마음이 생겨서 이후에도 방치하지 말고 꾸준히 개선하도록 스스로 동기부여를 잘 해야 할 것 같다.

4. 사이드 프로젝트를 할 때마다 문제 정의와 해결 과정에 대하여 많이 배우는 것 같다. 기술이나 구현적인 측면도 중요하긴 하지만, 스스로 뭔가를 기획해서 만드는 과정에서는 '내가 뭘 만들고 싶은지, 내가 생각한 아이디어와 이미 비슷한게 시중에 존재한다면 어떻게 차별화를 둘지, 어떤 방식과 기능으로 구성해야 목표로 하는 아이디어를 구현할 수 있을지' 등과 같은 문제를 정의해두고 그에 대한 해답을 고민하며 찾아가는 과정에서 여러모로 배우는 게 많은 것 같아서 재미있다. 

 

📌  데모 

프로젝트를 테스트해보기 위해 샘플로 "기부를 하기 위해 믿을 수 있는 곳을 선택할 때 고려할 요소에 대하여 설명해주세요. 그리고 이러한 요소를 근거로 한국 내의 기부처를 비교하는 도표를 만들어주세요. 한국의 기부처에 대한 정보를 얻기 위해 빙 서치를 활용해주세요. 불필요한 설명은 포함하지 말고 한국어로 답변하세요" 라는 프롬프트를 사용하여 GPT4에게 결과를 얻어보았다.

첫번째 이미지는 그냥 프롬프트를 입력했을 때이고, 두번째 이미지는 Prompt Enhancer로 프롬프트 엔지니어링을 거친 후에 프롬프트를 입력했을 때이다. 사실 GPT4는 매우 똑똑하기 때문에 웬만한 요구사항은 찰떡같이 알아듣고 잘 답변을 해주는 편이다. 그래도 대체적으로 프롬프트 엔지니어링 후의 프롬프트를 사용했을 때 요구조건을 더 확실히 반영해서 답변해주는 것을 확인할 수 있었다. 예컨대 이 샘플에서도 '기부처를 비교하는 도표를 만들어달라'는 요구사항에 있어서 원 프롬프트는 이를 누락했지만 개선된 프롬프트에선 반영하였다.

 

원 프롬프트와 엔지니어링 후의 프롬프트의 LLM 결과 비교

 

 

 

⭐ 프로젝트 링크 : https://prompt-enhancer.streamlit.app/ 

 

Prompt Enhancer

Welcome to Prompt Enhancer, a streamlit-powered application designed to improve your prompts effo...

prompt-enhancer.streamlit.app

 

 

반응형