예전 LLM 모델이 급부상하며 프롬프트 엔지니어링이라는 단어와 다양한 내용들이 넘쳐날 때에는 별게 다 엔지니어링이라며 터부시하며 지내왔었다.
이 땐 LLM을 단순 질문과 답변을 통한 지식 습득의 도구로서만 사용했기 때문이였는데 실제 세계의 문제를 해결하기 위한 에이전트로서 LLM을 활용하려 하다보니 프롬프트 엔지니어링의 중요성을 깨닫고 관련 내용들을 정리한다.
에이전트란
Artificial Intelligence agent
는 실제 세계의 데이터와 상호작용하며 데이터를 수집 및 활용하여 스스로에게 규정된 임무를 수행하는 일종의 소프트웨어 프로그램이다.
What are AI Agents?
정밀 프롬프팅의 원칙
프롬프트를 설계하는 것은 모호성을 최소화 하고 사용자 의도와 모델의 결과물을 최대한 일치시키기 위해 정보를 구조화하는 과정 을 의미한다. 잘 구성된 프롬프트는 단순한 지시를 넘어 구조화 된 인공물(artifact)로서 프레임워크로서의 역할을 할 수 있다.
프롬프트 엔지니어링을 통해 방대한 지식을 가진 모델의 출력 공간을 우리가 원하는 결과를 얻기 위해 가용해야 할 지식과 출력 공간을 동적으로 제한 할 수 있다.
프레임워크로서의 프롬프팅
이러한 프레임워크의 예시로는,현재까지는 가장 일반적으로 보이는 패턴으로서, 페르소나 -> 과업 -> 맥락 -> 형식 형태의 프레임워크가 있다.
페르소나 (Persona)
페르소나는 AI 모델에게 특정 역할이나 정체성을 부여하는 것이다. 이를 통해 부여받은 역할에 맞는 어조, 스타일, 전문 지식을 사용하여 답변을 생성하게 되며 응답의 일관성을 높이고 원하는 결과물에 더 가깝게 만들 수 있다.
페르소나를 설정하는 방식으론 다음과 같은 방식들이 있다.
- 역할 : "당신은 30년 경력의 베테랑 마케터입니다."
- 관점 : "냉소적이고 비판적인 시각으로 이 사안을 분석해줘."
- 특정 인물 : "셰익스피어의 스타일로 이 시를 작성해줘."
과업 (Task)
과업은 AI 모델이 수행해야 할 구체적인 임무를 명확하게 정의하는 것 이다. 무엇을 해야 하는지를 명시적으로 지시함으로써, 모델은 상요자의 요구사항을 정확히 이해하고 결과물을 생성 할 수 있다.
과업은 명확하고 간결 할 수록 좋다.
동일한 과업 난이도를 가진 과업이더라도 LLM 의 입력 토큰이 올라갈 수록 성능이 저하된다는 연구가 존재한다.
OpenAI, 구글, 클로드 다 마찬가지... 입력 길이 길어지면 생각보다 훨씬 더 성능 떨어진다 - 어떻게 대응해야 하나 | 컨텍스트 엔지니어링
이는 입력 길이가 높아짐에 따라 LLM 모델이 입력의 전체 컨텍스트를 처리하지 못하고 입력된 내용의 일부만 집중하는 경향이 있기 때문이다. 이러한 현상을 컨텍스트 소실 (Context Lost) 이라 한다.
과업은 추상적인 목표를 구체적이고 기계가 해석할 수 있는 제약 조건으로 변환 되어 서술되어야 한다.
무엇을 해야 한다는 행동 동사를 활용하고, 무엇을 하지 말라는 부정적 제약 조건보다 무엇을 하라는 긍정적 제약조건을 활용하는 것이 바람직하다.
또한 범위 및 길이, 원하는 구조를 정량적으로 제시함으로서 명확성을 높힐 수 있다.
맥락 (Context)
맥락은 LLM이 주어진 과업을 해결하는데 필요한 세계관을 설정하는 과정이다.
LLM의 지식 공간은 매우 방대하기에 사용하고자 하는 지식 공간을 특정 과업과 관련된 영역으로 좁히는 필터링 과정으로서 맥락을 정의하는 것이 중요하다.
맥락을 정의하는 방법의 예시로는 다음과 같은 방법들이 있다.
- 청중 명시 : 목표 청중을 명시적으로 정의하여 어휘 선택, 문장 복접성, 어조에 영향을 미치도록 한다.
- 목표 및 목적 명시 : 생성된 텍스트의 최종 목표를 정의함으로서 모델이 특정 수사적 전략 (특정 목표를 달성하기 위해 언어적, 비언어적 방법을 사용하는 기술) 을 우선순위에 두는데 도움이 된다.
- 사실적 기반 제공 : 관련 사실, 데이터 또는 원본 문서를 프롬프트 내에 포함시켜 모델의 응답을 현실에 기반하게 하고 환각을 줄인다.
형식 (Format)
형식은 AI가 결과물을 어떤 구조나 형태로 출력해야 하는지 를 정의하는 것이다.
약속된 형식을 통해 에이전트를 이용하는 사용자가 원하는 대로 결과물을 바로 활용 할 수 있도록 출력물의 스타일과 구조를 미리 정의한다.
인-컨텍스트 학습 (ICL)
인-컨텍스트 학습은 프롬프트 엔지니어링의 일종으로 모델에게서 원하는 출력을 얻기 위해 가중치를 업데이트 하지 않고 원하는 출력 형태를 프롬프트에 제공, 출력 형태를 추론 과정에서 모델이 학습하게 하여 출력 값을 얻어내는 방식 을 의미한다.
원하는 출력 형태를 추론하는 학습 과정은 입력에 대한 출력을 제공하는 기간 내의 컨텍스트에서만 유효하며, 모델 자체의 가중치를 업데이트 하지 않는다. 이를 통해 모델의 안정성을 유지한채로 효율적으로 시간과 비용을 아끼며 원하는 출력값을 얻어 낼 수 있다.
인-컨텍스트 학습의 예시는 다음과 같다.
[예시 1]
문장: 이 영화는 정말 환상적이었어요!
감성: 긍정
[예시 2]
문장: 음식이 너무 짜고 서비스도 별로였어요.
감성: 부정
[실제 과제]
문장: 기대했던 것보다는 조금 아쉽네요.
감성: ?
예를 들어 모델에게 감성 분석 과제를 시킬 때 프롬프트 내부에 적절한 입출력 예시를 주게 된다면 모델은 앞의 예시를 보고 사용자가 해결하길 원하는 과제가 감성 분석임을 추론하고 우리가 원하는 답변을 줄 확률이 높아진다.
이러한 인-컨텍스트 학습의 방식으론 예제를 직접 제공하지 않고 작업 설명과 기존의 학습 데이터에 의존한 채로 요구 사항을 추론하게 하는 제로샷 프롬프트 방식, 단일 입출력 예제를 통해 작업을 추론하게 하는 방식인 원샷 프롬프트 방식, 2개 이상의 입출력 상을 제공하는 퓨샷 학습 방식 이 존재한다.
각 학습 방식들은 도메인별 데이터의 양과 사용 목적, 모델의 추론 능력에 따라 적절히 사용한다.
다단계 프롬프팅 프레임워크
다단계 프롬프팅 프레임워크는 단일 프롬프트에서 벗어나 다단계 워크플로우를 통해 이뤄진 프레임워크 를 의미한다.
연쇄적 사고 (Chain of Thought)
연쇄적 사고 (이하 CoT) 는 프롬프트 단계에서 중간 추론 단계를 생성하도록 유도하는 기법이다.
무엇을 묻기에 집중하기 보다 어떻게 그 답에 도달했는지를 함께 요구 함으로서 동작하며, 모델이 추론 과정을 따라 갈 수 있는 논리적 경로를 제공함으로서 체계적으로 해결하도록 돕는다.
Zero Shot CoT 방식으로 프롬프트 말미에 어떻게 그 답에 도달했는지에 문장을 추가하거나 (단계별로 생각해보자 혹은 결론을 내리기 전에 모든 과정을 설명해줘) Few Shot CoT 방식으로 질문과 함께 단계별 추론 과정이 포함된 예시를 제공하여 모델이 따라야 할 사고 패턴을 명확히 보여줄 수 있다.
다만 최신 모델들은 이미 내부 추론 메커니즘을 기본적으로 탑재하고 있어 따로 프롬프트를 제공하지 않더라도 해결 할 수 있다고 한다. 실제로 실험해보니 큰 차이가 없었다. :>
과업 분해 및 프롬프트 체이닝
과업 분해는 하나의 거대하고 복잡한 과업을 더 작고 관리하기 쉬운 여러 개의 하위 과업으로 나누는 전략을 의미한다.
프롬프트의 출력은 다음 프롬프트의 입력값으로 사용되도록 순차적으로 과업들을 연결해줘야 한다.
이 과정을 통해 거대한 하나의 과업을 단순한 여러 개의 과업으로 나눠 세밀한 제어와 신뢰성 및 디버깅을 할 수 있도록 돕는다.
예시: "AI 마케팅의 미래"에 대한 블로그 글 작성 워크플로우
1단계: 아이디어 브레인스토밍
프롬프트 1: "AI 마케팅의 미래에 대한 흥미로운 블로그 글 주제 5가지를 제안해줘."
2단계: 개요 작성
프롬프트 2: "[1단계 결과 중 선택한 주제]에 대한 상세한 블로그 글 개요를 작성해줘. 서론, 본론 3가지 소주제, 결론을 포함해야 해."
3단계: 초고 작성
프롬프트 3: "[2단계에서 만든 개요]를 바탕으로, 독자의 흥미를 끌 수 있는 전문적인 톤의 블로그 글 초고를 작성해줘."
4단계: 제목 및 요약 생성
프롬프트 4: "[3단계의 초고] 내용을 바탕으로, 클릭을 유도할 만한 매력적인 제목 3가지와 SNS 공유를 위한 2줄 요약을 만들어줘."
반복적 정제 (Iterative Refinement) 및 자가 교정 (Self-Correction)
이 프레임워크는 LLM이 스스로 생성한 결과물을 비판하고 피드백을 바탕으로 결과물을 반복적으로 개선 하게 만드는 기법이다.
생성 -> 비판 -> 수정의 사이클을 자동화하여 외부의 개입 없이도 결과물의 품질을 점진적으로 향상 시킨다.
1단계: 초기 결과물 생성 (Generate)
프롬프트 1: "팀의 생산성을 높이는 방법에 대한 보고서 초안을 작성해줘."
2단계: 자가 비판 (Critique)
프롬프트 2: "방금 네가 작성한 보고서 초안을 비판적으로 검토해줘. 주장이 명확하지 않은 부분, 논리적 근거가 부족한 부분, 더 설득력 있게 개선할 수 있는 부분을 지적해줘."
3단계: 피드백 기반 수정 (Refine)
프롬프트 3: "방금 네가 직접 제기한 비판점들을 바탕으로, 보고서 초안을 전면적으로 수정하여 최종 완성본을 만들어줘."
프롬프트 평가
최고의 프롬프트를 설게하느 과정은 과학적 방법론에 기반한 반복적이고 경험적인 과정이다. 프롬프트의 작은 변화가 결과물에 큰 영향을 미칠 수 있으므로, 체계적인 평가 프레임워크를 통해 이러한 변화를 정량적으로 측정하고 최적의 솔루션을 찾아야 한다.
프롬프트는 기반 LLM 모델이 변경되거나 사용자 입력 패턴이 변화함에 따라 과거에 효과적이였던 프롬프트의 성능이 저하 될 수 있다. 이러한 드리프트 현상을 방지하기 위해 정기적인 재평가는 필수적이다.
성공 기준 정의
좋고 나쁨의 결과물이 무엇인지 정의하기 위핸 정량적인 지표로 정의해야 한다.
이는 인공 지능을 평가하는 정량적 척도 뿐 아니라 여러 프롬프트 버전이 생성한 결과물을 놓고 실제 사용자가 선호하는 비율을 측정하는 인간 선호도 점수, 자동화된 가독성 점수를 통해 텍스트의 복잡성과 가독성을 측정하는 방식 등을 사용해야 한다.
프롬프트를 코드처럼 관리하기
프롬프트는 에이전트를 이용하는 서비스에서 코드만큼이나 중요한 자산이다. 이에 Git을 통한 버전 관리 시스템을 통해 변경 사항을 추적하고, 특정 버전으로 쉽게 되돌릴 수 있어야 한다.