[LLM] Prompt Engineering

CHOI HYUK·2025년 8월 13일
0

AI

목록 보기
1/6
post-thumbnail

💻 Prompt Engineering

저번에는 LangChain을 통해서 Prompt Engineering을 적용하는 법을 알아보았는데, 사실 Prompt Engineering 최근 LLM을 구성하는데 있어서 매우 중요한 기술이다. 따라서
Prompt Engineering Guide에서 학습 한 내용을 내 나름대로 정리해 보았다.

프롬프팅 엔지니어링이란? 🤖

프롬프팅 엔지니어링은 사람이 모델의 프롬프트를 개발하는 행위를 이야기한다. 따라서 비교적 최근에 활발히 연구되고 있는 분야다. 프롬프팅 엔지니어링은 LLM(Large Language Model, 거대 언어 모델)의 역량을 향상시키고, LLM 및 기타 도구와 인터페이스를 형성할 수 있다.

또한 중요한 점은 바로 하드웨어적이 변경 없이 오직 내부의 자연어로 처리된 프롬프팅을 통해 성능을 개선한다는 점이다. 사실 지금은 크게 와 닿지는 않는다...


매개변수 (Parameters) ⚙️

매개변수는 프롬프팅 엔지니어링에서 사용하는 용어들과 더불어 성능을 조절할 수 있는 변수들이다. 프레임워크, 도구를 사용해서 프롬프팅을 할 때 이러한 변수들을 사용해서 성능과 출력 결과를 조절하게 된다.

Temperature

모델이 생성하는 텍스트의 무작위성을 조절하는 매개변수다.

  • 낮은 값을 설정하면 확률이 가장 높은 단어를 선택하여 결정적이고 사실적인 응답을 생성한다. 이는 질의응답과 같은 작업에 적합하다.
  • 높은 값을 설정하면 다양한 단어의 선택 가중치를 높여 다양하고 창의적인 응답을 촉진한다. 이는 시 창작과 같은 작업에 유용하다.

Top-p

온도와 유사하게 텍스트 생성의 결정성을 제어하는 매개변수다.

  • 낮은 값을 설정하면 정확하고 사실적인 답변을 생성한다.
  • 높은 값을 설정하면 보다 다양한 응답을 유도한다.
  • 일반적으로 온도(temperature)와 Top-p 중 하나만 조정하는 것이 권장된다.

최대 길이 (Max Length)

모델이 생성할 수 있는 최대 토큰(단어) 수를 설정하는 매개변수다. 길고 불필요한 응답을 방지하고 비용을 관리하는 데 도움이 된다.

정지 시퀀스 (Stop Sequences)

모델의 텍스트 생성을 중단시키는 특정 문자열이다. 응답의 길이와 구조를 제어하는 데 사용된다.

빈도 페널티 (Frequency Penalty)

이미 생성된 단어가 다시 등장할 확률을 낮추는 매개변수다. 값이 높을수록 모델의 응답에서 단어의 반복을 방지한다.

존재 페널티 (Presence Penalty)

이미 한 번이라도 등장한 단어에 동일한 페널티를 적용하여 반복을 방지하는 매개변수다.

  • 값이 높을수록 다양한 텍스트를 생성하는 데 도움이 되고, 낮은 값은 사실 기반의 집중적인 응답에 적합하다.
  • 빈도 페널티와 존재 페널티 중 하나만 조정하거나 둘 다 조정하지 않는 것이 일반적인 권장 사항이다.

프롬프팅 기법 (Prompting Techniques) ✨

Zero-shot

Zero-shot은 모델에게 예시를 제공하지 않고, 질문과 지시만으로 답변을 유도하는 기법이다. 모델의 사전 학습된 지식을 활용하여 직접적인 답변을 생성한다.

텍스트를 중립, 부정 또는 긍정으로 분류합니다.
텍스트: 휴가는 괜찮을 것 같아요.
감정:
중립

이 프롬프트는 별도의 배경 정보나 예시 없이 모델에게 바로 질문을 던진다. 예제를 제시하지 않지만 모델의 사전 학습된 지식을 통해서 답변을 하게 된다. LLM은 뛰어난 제로샷 능력을 보여준다고 한다. 하지만 복잡한 작업에서는 개선이 필요하다.

Few-shot

Few-shot은 원하는 답변의 패턴을 모델에게 학습시키기 위해 질문과 함께 몇 가지 예시를 제공하는 기법이다. 이를 통해 모델은 예시의 형식을 모방하여 답변을 생성한다.

정말 멋지네요! // 긍정
이건 나쁘다! // 부정
와우 그 영화 정말 멋졌어요! // 긍정
정말 끔찍한 쇼였어! // 부정

이 프롬프트는 답변을 유도해서 정확한 출력을 하게 한다.

정말 멋지네요! // 부정
이건 나쁘다! // 긍정
와우 그 영화 정말 멋졌어요! // 긍정
정말 끔찍한 쇼였어! //

현재 대규모 모델들은 이러한 Zero-shot, Few-shot 전부 가능하며, 위와 같이 무작위로 입력된 프롬프트에 대해서도 정확한 답변을 가져올 수 있다고 한다. 하지만 Few-shot 프롬프트도 복잡한 추론 작업에서는 완벽한 기술은 아니다.

이 집합 {15, 32, 5, 13, 82, 7, 1}에서 홀수를 모두 더하면 짝수이다.
A:
네, 이 집합의 홀수를 모두 더하면 짝수인 107입니다.

만약 질의 결과가 이렇게 나왔을 때는 다른 방식으로 프롬프팅을 진행해야 한다.

이 집합 {4, 8, 9, 15, 12, 2, 1}에서 홀수의 합은 짝수입니다.
A: 답은 거짓입니다.
이 집합 {17, 10, 19, 4, 8, 12, 24}에서 홀수의 합은 짝수입니다.
A: 정답은 참입니다.
이 집합 {16, 11, 14, 4, 8, 13, 24}에서 홀수의 합은 짝수입니다.
A: 답은 참입니다.
이 집합 {17, 9, 10, 12, 13, 4, 2}에서 홀수의 합은 짝수입니다.
A: 답은 거짓입니다.
이 집합 {15, 32, 5, 13, 82, 7, 1}에서 홀수의 합은 짝수입니다.
A:
답은 참입니다.

위의 결과로 프롬프팅을 해도 안 되는 경우가 존재할 것이다. 이럴 때 필요한 것이 Chain-of-Thought다.

Chain-of-Thought (CoT) 🧠

CoT는 모델에게 "단계별로 생각하라"는 지시를 내려 복잡한 문제를 논리적인 사고 과정을 통해 해결하도록 유도하는 기법이다. 이를 통해 모델의 추론 오류를 줄이고 정확도를 높인다.

이 기법이 프롬프트 엔지니어링의 핵심이되는 추론 과정을 탑재한 기법이다.

앞으로 나오는 기법들은 해당 CoT를 활용해서 추론 과정을 바꾸고 여러가지 도구를 중간에 넣어서 성능을 향상시킨 것이다.

Image
집합 {4, 8, 9, 15, 12, 2, 1}에서 홀수를 모두 더하면 짝수야.
답변: 홀수(9, 15, 1)를 모두 더하면 25가 돼. 위의 명제는 거짓이야.
집합 {17, 10, 19, 4, 8, 12, 24}에서 홀수를 모두 더하면 짝수야.
답변: 홀수(17, 19)를 모두 더하면 36이 돼. 위의 명제는 참이야.
집합 {16, 11, 14, 4, 8, 13, 24}에서 홀수를 모두 더하면 짝수야.
답변: 홀수(11, 13)를 모두 더하면 24가 돼. 위의 명제는 참이야.
집합 {17, 9, 10, 12, 13, 4, 2}에서 홀수를 모두 더하면 짝수야.
답변: 홀수(17, 9, 13)를 모두 더하면 39가 돼. 위의 명제는 거짓이야.
집합 {15, 32, 5, 13, 82, 7, 1}에서 홀수를 모두 더하면 짝수야.
답변:
홀수(15, 5, 13, 7, 1)를 모두 더하면 41이 돼. 위의 명제는 거짓이야.

위의 프롬프팅과 같이 추론 과정을 입력하면 모델이 훨씬 정확한 답변을 하게 된다.

Zero-shot CoT Prompting 🚀

모델의 성능이 향상되면서, Let's think step by step과 같은 질의 예시가 없는 Zero-shot이어도 모델이 추론 도출을 진행한다는 것이다.

현재의 LLM들은 이러한 제로샷 능력을 가지고 있다고 보면 된다.

나는 시장에 가서 사과 10개를 샀어. 사과 2개를 이웃에게 주고, 2개를 수리공에게 주었어. 그리고 사과 5개를 더 사서 1개는 내가 먹었어. 나는 몇 개의 사과를 가지고 있었니?
사과 11개

여기서 Zero-shot CoT Prompting을 적용하면 이렇게 구현할 수 있다.

나는 시장에 가서 사과 10개를 샀어. 나는 사과 2개를 이웃에게 주고, 2개를 수리공에게 주었어.
그리고 사과 5개를 더 사서 1개는 내가 먹었어.
사과가 몇 개나 남았니?
단계별로 생각해 보자.
먼저 사과 10개로 시작했어.
이웃에게 2개, 수리공에게 2개를 나누어 주었으므로 사과가 6개가 남았어.
그런 다음 사과 5개를 더 사서 이제 사과가 11개가 되었어.
마지막으로 사과 1개를 먹었으므로 사과 10개가 남게 된다.

Self-Consistency 🔄

Self-Consistency는 CoT를 확장한 기법으로, 같은 질문에 대해 여러 가지 다른 사고 경로를 탐색하여 다양한 답변을 생성한 뒤, 가장 일관된 답변을 최종 결과로 선택하는 방식이다.

참고로 디코딩은 LLM의 사고를 바탕으로 실제 텍스트를 선택해서 결과를 내놓는 과정이다. LLM에서 많이 쓰이는 디코딩 방식은 크게 세 가지로 요약할 수 있다. 이 방식들은 각각 속도, 품질, 다양성 측면에서 서로 다른 장단점을 가지고 있으며, 해결하고자 하는 문제의 성격에 따라 적절한 방식을 선택하여 사용한다.

탐욕 알고리즘 (Greedy Decoding)

가장 단순하고 빠른 방식으로, 매 단계에서 확률이 가장 높은 단어 하나만을 선택한다.

  • 속도: 매우 빠르다.
  • 결과: 매번 동일한 결과를 생성하며, 다양성이 전혀 없다.
  • 장점: 계산 비용이 매우 낮아 리소스 소모가 적다.
  • 단점: 지역 최적해(local optimum)에 빠져 최적의 문맥을 놓칠 수 있다.

빔 서치 (Beam Search)

매 단계에서 가장 확률이 높은 **K개의 단어(빔)**를 동시에 추적하며, 여러 가능한 경로를 탐색한다. K개의 경로 중 최종적으로 가장 높은 확률의 문장을 선택한다.

  • 속도: 탐욕 알고리즘보다 느리다.
  • 결과: 탐욕 알고리즘보다 더 나은 품질의 결과를 생성할 가능성이 높다.
  • 장점: 탐욕 알고리즘의 한계를 보완하며, 전체적인 문맥을 고려한다.
  • 단점: 계산 비용이 높고, 생성된 문장이 다소 반복적이거나 일관성이 떨어질 수 있다.

샘플링 (Sampling)

확률이 가장 높은 단어 하나만 선택하는 것이 아니라, 예측된 확률 분포에 기반하여 무작위로 단어를 선택하는 방식이다.

  • 속도: 탐욕 알고리즘과 비슷하거나 조금 더 느리다.
  • 결과: 매번 다른 결과물을 생성하며, 다양성과 창의성이 높다.
  • 장점: 창의적인 글쓰기나 Self-Consistency와 같이 여러 다른 추론 경로를 생성하는 데 필수적이다.
  • 단점: 때때로 의미 없는 문장이나 논리적이지 않은 결과물을 생성할 수 있다.

만약 탐욕 알고리즘 디코딩으로 자연어를 생성한다면, 확률이 높은 결과로 나아가는 특징이 있지만, 만약 지역 최적해에 빠지게 되면 최악의 결과를 내놓게 된다. 따라서 이를 보완한 것이 샘플링을 사용하는 Self-Consistency이다.

내가 6살이었을 때 내 여동생은 내 나이의 절반인 나이였어.
지금 나는 70살이라면 여동생은 몇 살일까?
35

위의 프롬프팅을 CoT를 적용할 수 있다.

Q: 과수원에는 15그루의 나무가 있어. 과수원의 일꾼들이 오늘 과수원에 나무를 심을 거야. 나무 심기가 끝나면 21그루의 나무가 있을 거야. 오늘 과수원 일꾼들은 몇 그루의 나무를 심었을까?
A: 15그루로 시작합니다. 나중에 나무가 21그루가 됩니다. 그 차이가 그들이 심은 나무의 수일 것입니다. 따라서 그들은 21 - 15 = 6그루의 나무를 심었어야 합니다. 정답은 6입니다.
Q: 주차장에 3대의 차량이 있고, 2대의 차량이 더 도착하면 주차장에 몇 대의 차량이 있을까?
A: 주차장에 이미 3대의 차량이 있습니다. 2대가 더 도착합니다. 이제 3 + 2 = 5대의 차량이 있습니다. 정답은 5입니다.
Q: 지호는 초콜릿을 32개, 여동생은 42개를 가지고 있었어. 둘이 35개를 먹었다면 총 몇 개가 남았을까?
A: 레아는 초콜릿 32개, 레아의 여동생은 42개를 가지고 있었습니다. 즉, 원래 32개 + 42개 = 74개의 초콜릿이 있었습니다. 35개를 먹었습니다. 따라서 총 74 - 35 = 39개의 초콜릿이 남아 있습니다. 정답은 39입니다.
Q: 선우는 막대 사탕을 20개 가지고 있었어. 그는 두리에게 막대 사탕을 몇 개 주었어. 이제 선우는 막대 사탕 12개를 가지고 있어. 선우는 두리에게 몇 개의 막대 사탕을 줬을까?
A: 선우는 막대 사탕 20개를 가지고 있었습니다. 이제 선우는 12개만 가지고 있으므로, 나머지는 두리에게 주었을 것입니다. 선우가 두리에게 준 막대 사탕의 수는 20 - 12 = 8개다. 정답은 8개다.
Q: 내가 6살이었을 때 내 여동생은 내 나이의 절반인 나이였어. 지금 나는 70살이고 내 여동생은 몇 살일까?
A:

이렇게 CoT를 진행하면 샘플링으로 여러 개의 답이 나올 것이다.

내가 6살이었을 때 여동생은 내 나이의 절반이었으므로 3살이었다. 이제 나는 70살이므로 여동생은 70 - 3 = 67살이다. 정답은 67이다.
화자가 6살이었을 때 여동생은 화자의 절반 나이인 3살이었다. 이제 화자가 70살이 되었으므로 여동생은 70 - 3 = 67살이 된다. 정답은 67이다.
내가 6살이었을 때 여동생은 내 나이의 절반이었으므로 3살이고, 이제 나는 70살이므로 여동생은 70/2 = 35살이다. 정답은 35이다.

디코딩으로 3개의 출력이 나왔고 이제 Self-Consistency는 다수결 합의를 통해 67과 35 중 더 많은 67을 선택하게 된다.


Generative knowledge prompting 💡

Generative knowledge prompting은 말 그대로 프롬프팅에 사용할 지식을 미리 생성하는 기법이다.

골프의 목적 중 하나는 다른 사람보다 더 높은 점수를 얻기 위해 노력하는 것이다.
예, 아니오?
예.

골프는 홀에 공을 넣어서, 타수가 최저가 되게 해야 한다. 이때 타수는 점수로 계산되므로, 점수가 낮도록 노력해야 된다. 따라서 해당 출력은 오답이다. 이를 개선하려면 위와 같은 형태의 질문이 들어왔을 때 해당 주제의 전반적인 지식을 지시하여 지식 수준을 높이는 프롬프팅이 가능하다.

만약 LLM에게 해당 질문을 하기 전에, 골프에 대한 지식을 알려줘라고 입력하면 골프에 대한 지식을 출력할 것이다.

Input: 그리스는 멕시코보다 크다.
Knowledge: 그리스는 약 131,957 제곱 킬로미터이고, 멕시코는 약 1,964,375 제곱 킬로미터로 멕시코가 그리스보다 1389% 더 크다.
Input: 안경은 항상 김이 서린다.
Knowledge: 안경 렌즈에는 땀, 호흡 및 주변 습도에서 나오는 수증기가 차가운 표면에 닿아 식은 다음 작은 액체 방울로 변하여 안개처럼 보이는 막을 형성할 때 응결이 발생한다. 특히 외부 공기가 차가울 때는 호흡에 비해 렌즈가 상대적으로 차가워진다.
Input: 물고기는 생각할 수 있다.
Knowledge: 물고기는 보기보다 훨씬 더 똑똑하다. 기억력과 같은 많은 영역에서 물고기의 인지 능력은 인간이 아닌 영장류를 포함한 '고등' 척추동물과 비슷하거나 그 이상이다. 물고기의 장기 기억력은 복잡한 사회적 관계를 추적하는 데 도움이 된다.
Input: 평생 담배를 피우는 것의 일반적인 결과는 폐암에 걸릴 확률이 정상보다 높다는 것입니다.
Knowledge: 평생 동안 하루 평균 담배를 한 개비 미만으로 꾸준히 피운 사람은 비흡연자보다 폐암으로 사망할 위험이 9배 높았다. 하루에 한 개비에서 열 개비 사이의 담배를 피운 사람들은 폐암으로 사망할 위험이 비흡연자보다 거의 12배 높았다.
Input: 돌은 조약돌과 같은 크기다.
Knowledge: 조약돌은 퇴적학의 우든-웬트워스 척도에 따라 입자 크기가 4~64밀리미터인 암석 덩어리다. 조약돌은 일반적으로 과립(직경 2~4밀리미터)보다는 크고 자갈(직경 64~256밀리미터)보다는 작은 것으로 간주된다.
Input: 골프의 목적 중 하나는 다른 사람보다 더 높은 점수를 얻기 위해 노력하는 것이다.
Knowledge:

위의 출력 마지막 질문에 답을 하기 전에 LLM은 골프에 대한 지식을 생성할 것이다.

# Knowledge 1
골프의 목적은 최소의 스트로크로 한 세트의 홀을 플레이하는 것이다. 골프 라운드는 일반적으로 18홀로 구성된다.
각 홀은 표준 골프 코스에서 라운드 중 한 번씩 플레이된다. 각 스트로크는 1점으로 계산되며 총 스트로크 수를 사용하여 게임의 승자를 결정한다.

# Knowledge 2
골프는 경쟁하는 선수(또는 골퍼)가 여러 종류의 클럽을 사용하여 가장 적은 수의 스트로크로 코스에 있는 한 세트의 홀에 공을 치는 정밀한 클럽 앤 볼 스포츠다.
각 홀에서 기록한 총 타수를 합산하여 계산하는 점수가 최저가 되도록 코스를 완주하는 것이 목표다.
가장 낮은 점수를 기록한 플레이어가 게임에서 승리한다.

이렇게 지식이 생성이 되면, LLM은 훨씬 쉽게 추론이 가능할 것이다.


Prompt Chaining ⛓️

프롬프트 체이닝 기법은 LLM의 작업을 하위 작업으로 나누는 것이다. 만약 하나의 작업에 대해 여러 개의 하위 작업으로 나누어지게 된다면, 각 응답을 서로 활용해서 보완이 가능하다. 이러한 연쇄적인 작용을 프롬프트 체이닝이라고 한다.

프롬프트 체이닝은 이러한 성능 개선뿐만 아니라 안전성과 작업의 직관성, 투명성을 높여줘서 사람 기준에서 디버깅과 분석을 하기에 용이하게 한다. 특히 문서 기반 자료를 분석할 때 유용한데, 아래 예시가 있다.

# Prompt 1
You are a helpful assistant. Your task is to help answer a question given a document. The first step is to extract quotes relevant to the question from the document, delimited by ####. Please output the list of quotes using <quotes></quotes>. Respond with "No relevant quotes found!" if no relevant quotes were found.
####
{{document}}
####

이렇게 인용문을 #### 기준으로 나누어서 생성해 달라고 지시할 수 있다.

Given a set of relevant quotes (delimited by <quotes></quotes>) extracted from a document and the original document (delimited by ####), please compose an answer to the question. Ensure that the answer is accurate, has a friendly tone, and sounds helpful.
####
{{document}}
####
<quotes>
- Chain-of-thought (CoT) prompting[27]
- Generated knowledge prompting[37]
- Least-to-most prompting[38]
- Self-consistency decoding[39]
- Complexity-based prompting[41]
- Self-refine[42]
- Tree-of-thought prompting[43]
- Maieutic prompting[45]
- Directional-stimulus prompting[46]
- Textual inversion and embeddings[59]
- Using gradient descent to search for prompts[61][62][63][64]
- Prompt injection[65][66][67]
</quotes>

그러면 이렇게 출력이 나오게 되면 다시 해당 인용문을 사용해서 프롬프팅할 수 있다.

The prompting techniques mentioned in the document include:
1. Chain-of-thought (CoT) prompting[27]
2. Generated knowledge prompting[37]
3. Least-to-most prompting[38]
4. Self-consistency decoding[39]
5. Complexity-based prompting[41]
6. Self-refine[42]
7. Tree-of-thought prompting[43]
8. Maieutic prompting[45]
9. Directional-stimulus prompting[46]
10. Textual inversion and embeddings[59]
11. Using gradient descent to search for prompts[61][62][63][64]
12. Prompt injection[65][66][67]
Each of these techniques employs unique strategies to enhance or specify the interactions with large language models to produce the desired outcomes.

이제 모델은 인용문과 문서를 기반으로 응답하여 훨씬 정확한 답변을 할 것이다.


Tree of Thoughts (ToT) 🌳

해당 기법은 기존의 CoT에서 여러 가지의 의견을 가진 추론 과정을 생성하는 방법을 사용한다. 입력이 들어오면 위의 그림과 같이 여러 개의 추론 과정을 생성해낸다. 이때, 추론 과정에서 생성된 생각들을 평가하여 가장 높은 확률의 생각을 판단한다.

Image Image

위의 그림에서 Propose Prompt는 프롬프팅이 추론하여 생각을 생성하는 과정이다. Value prompt는 값을 평가하여 각 생각들의 정답 도달 확률을 구하게 된다.
Image

연구 결과를 보면 ToT가 다른 기법들보다 월등히 뛰어나다고 한다. 그러나 연산이 매우 오래 걸려서 고도화된 작업이나 퍼즐 문제 등 복잡한 연산 문제를 처리하는 데 적절하다.

[참고] Prompt Engineering Guide

0개의 댓글