본문 바로가기

공부방

프롬프트 엔지니어링 5편 | Chain of Thought(CoT), Self-consistency

딱 한 줄 바꿨을 뿐인데, 답변의 퀄리티가 이렇게 차이난다고? 맞습니다. 똑같은 돈을 내고 AI 모델을 사용하더라도, 어떻게 질문을 하느냐에 따라 얻을 수 있는 결과는 천차만별입니다. 어떻게 하면 AI의 성능을 최대로 끌어내어 정확하고 의미있는 답변을 출력하게 할 수 있을까요? 구글에서 발간한 화제의 백서, “Lee Boonstra의 프롬프트 엔지니어링 백서”를 보면 알 수 있습니다. 원문은 모두 영어로 되어 있는데요. 이번 백서의 내용을 꼼꼼히 공부하고, 직접 실험해보면서 중요한 개념들을 해설하는 시리즈를 기획했습니다. 총 8편에 걸쳐 진행될 예정이며, 구글 백서 원문은 이곳(링크)에서 확인할 수 있습니다. 

[구글 프롬프트 엔지니어링 백서 파헤치기 시리즈]

1편 - LLM의 작동 방식과 config 조정하기
2편 - 일반 프롬프트, 제로샷, 원샷, 퓨샷
3편 - 시스템, 컨텍스트, 역할 프롬프트
4편 - 스텝백 프롬프트
5편 - CoT, 자기 일관성(현재글)
6편 - ToT, ReAct
7편 - 자동 프롬프트 엔지니어링, 코드, 멀티모달
8편(완) - 실제 사례 살펴보기(5월 7일 발행 예정)



자기 전에 눈을 감으면 생각이 꼬리에 꼬리를 물며 이어집니다. 그렇게 망상을 하다가 잠에 들기도 하지만, 이를 잘 다듬어보면 이전에 생각해보지 못했던 새로운 생각에 다다르기도 하죠. 사람은 이렇게 머릿속에서 자유롭게 연상할 수 있습니다.(LLM에 비유한다면 temperature가 높은 상황) 

그리고 해결해야 할 복잡한 문제가 있을 때에는 생각에 단계와 논리를 추가합니다. 여행 예산을 짤 때나 게임을 할 때, 약속을 정하고 효율적인 경로를 계산하는 등 일상 생활에서 우리는 수많은 문제를 마주할 때마다 논리적 추론을 하게 됩니다. 그렇다면 LLM에게 인간이 하는 이러한 자연스러운 추론 과정을 가르치면 어떨까요? 

 

생각의 사슬을 연결한다, Chain of Thought(CoT)

출처: 프롬프트 엔지니어링 백서

[질문] 내가 3살이었을 때, 내 파트너는 내 나이의 3배였다. 지금 나는 20살이다. 내 파트너의 나이는? 
[답변] 63살

LLM은 가끔 터무니없는 답변을 할 때가 있습니다. LLM은 텍스트 생성이나 요약, 번역과 같은 언어 작업에 대해서는 뛰어난 성능을 보였지만, 수학 문제라던가 복잡한 논리적 추론이 필요한 작업에 대해서는 잘못된 대답을 내놓는 약점을 보였던 것입니다. 

백서에서 제시한 예시처럼, 나이를 계산하는 문제에 틀린 답을 내놓았습니다. 문제 전체를 한번에 이해하고 답을 하려고 했기 때문입니다. 어떻게 하면 LLM이 논리적 추론을 더 잘하게 할 수 있을까? 이러한 고민 끝에 탄생한 기술이 Chain of Thought, CoT입니다. 문제를 쪼개고 단계별로 나눠서 중간 추론 단계를 만들어 주는 기술입니다. 

CoT는 모델이 최종 답변을 내기 전에 중간 추론 단계를 생성하도록 유도함으로써 더 정확한 답변을 얻을 수 있게 합니다. 마치 수학 문제를 풀 때 풀이 과정을 차근차근 적어나가는 것처럼, LLM도 생각의 흐름을 단계별로 표현하면서 더 나은 결과에 도달하게 됩니다. 먼 곳으로 점프하기 위해서는 힘이 많이 들지만, 중간에 징검다리가 있으면 좀 더 손쉽게 갈 수 있는 것처럼요. 

동일한 질문에 “단계 별로 생각해봐”라는 말 한마디를 붙였을 때 결과가 어떻게 달라졌을까요. 

출처: 프롬프트 엔지니어링 백서

 

Let’s think step by step. 딱 한 마디 더 붙였을 뿐인데, 답변이 크게 달라졌습니다. 정답도 맞췄고요. 

단계별로 생각하라는 말은 LLM에게 문제 해결 과정을 단계별로 설명하도록 지시함으로써 모델이 최종 답변에 도달하기 전에 논리적인 사고 과정을 거치도록 유도합니다. 이는 LLM이 단순히 패턴을 인식하는 것을 넘어 실제 추론에 더 가깝게 작동하도록 만들어줍니다. 

하지만 논리적 추론 과정이 불필요하게 복잡한 것 같습니다. 내가 3살 일 때, 파트너는 3배이므로 9살이고, 두 사람의 나이차는 6. 현재 나이는 내가 20이므로 나이차 6을 더해 26으로 계산하면 훨씬 간단한데 말이죠. 이런 추론 방식을 따르게 하고 싶다면, few shot으로 이 추론 과정을 알려줄 수 있습니다. 

 

출처: 프롬프트 엔지니어링 백서

 

Zero-shot vs. Few-shot CoT

위 예시들에서 볼 수 있듯이 CoT 프롬프팅은 두 가지 방식으로 적용할 수 있습니다. "단계별로 생각해봅시다"와 같은 간단한 지시문만 추가한다면 Zero-shot CoT, 모델에게 예시 문제와 그 해결 과정을 보여준 후 새로운 문제를 제시한다면 Few-shot CoT입니다. 예시를 제공하면 모델은 같은 패턴을 따라 올바른 답변을 생성할 가능성이 높아집니다.

 

어디에, 어떻게 쓸까

CoT는 다양한 분야에서 활용될 수 있습니다.

1. 코딩

복잡한 코딩 문제를 해결할 때, 바로 코드를 작성하는 대신 먼저 문제를 논리적인 단계로 분해하고, 그 다음 각 단계를 구현하는 코드를 작성하게 할 수 있습니다. 

예를 들어서, "폴더 내 모든 텍스트 파일의 이름을 찾아서 파일명 앞에 '중요_'라는 접두사를 추가하는 파이썬 스크립트를 작성해주세요."라고 질문을 한다고 해보겠습니다. CoT를 적용한다면, 이 문제를 논리적 단계로 먼저 쪼갭니다. 

1단계: 사용자로부터 폴더 경로를 입력받아야 한다 
2단계: 해당 폴더 내 모든 파일을 확인해야 한다 
3단계: 각 파일이 텍스트 파일(.txt)인지 확인해야 한다 
4단계: 텍스트 파일이라면, "중요_" 접두사를 붙인 새 이름을 생성해야 한다 
5단계: 원래 파일을 새 이름으로 변경해야 한다

이후에 코드를 작성합니다. 코드에는 각 단계에 대한 주석이 달려있을 것이고요. 이와 같이 CoT는 알고리즘, 데이터 처리, 웹 어플리케이션 개발 등 여러 단계가 필요한 코딩 작업에서 매우 유용하게 쓸 수 있습니다. 

2. 합성 데이터 생성

합성 데이터란 실제 데이터가 아닌, 인공적으로 생성된 데이터를 말합니다. 특정 시드를 기반으로 데이터를 생성하는 경우 CoT를 이용하면 모델이 가정을 통해 단계를 밟도록 안내할 수 있습니다. 예를 들어서 제품명을 주고 그 제품에 대한 설명을 작성하라고 하는 프롬프트를 가정해보겠습니다. 

일반 프롬프트
솔라브리즈 휴대용 선풍기에 대한 제품 설명을 작성해 주세요.
CoT 프롬프트

제품명: "솔라브리즈 휴대용 선풍기"
1단계: 제품명에서 어떤 정보를 알 수 있는지 분석하세요.
2단계: 각 단어가 암시하는 제품의 특성을 나열하세요.
3단계: 이 제품의 주요 사용 용도와 대상 고객층을 추론하세요.
4단계: 위 정보를 바탕으로 마케팅에 적합한 제품 설명을 작성하세요.

이런 방식으로 CoT는 마케팅 컨텐츠, 제품 설명, 가상 인물 프로필, 시나리오 기반 데이터 등 다양한 유형의 합성 데이터를 생성하는 데 활용될 수 있습니다. AI가 각 단계에서 어떤 추론을 하는지 명시적으로 보여줌으로써, 더 풍부하고 논리적인 데이터 생성이 가능해집니다. 

이 외에도 수학 문제와 단계별 해결이 필요한 모든 작업에 CoT를 활용할 수 있습니다. 

CoT 프롬프팅의 장점

  • 적은 노력으로 높은 효과를 얻을 수 있습니다
  • 기성 LLM에서도 잘 작동합니다(파인 튜닝 불필요)
  • 모델의 추론 과정을 볼 수 있어 해석 가능성이 높아집니다
  • 오작동이 발생했을 때 원인을 파악하기 쉽습니다
  • 서로 다른 LLM 버전 간에도 안정적으로 작동합니다

물론 단점도 있습니다. CoT 응답에는 추론 체인이 포함되므로 출력 토큰이 많아져 비용이 증가하고 응답 시간이 길어질 수 있습니다.

 

CoT를 쓸 때 주의해야 할 점

추론 과정 이후에 최종 답변을 제시해야 합니다. 이는 추론 단계의 생성이 모델이 최종 답변을 예측할 때 받는 토큰에 영향을 미치기 때문입니다. 또한 바로 뒤에서 나올 자기일관성을 CoT와 함께 사용하는 경우, 추론 과정과 최종 답변을 명확하게 분리하여 추출할 수 있어야 합니다. 

CoT 프롬프팅을 사용할 때는 temperature를 0(탐욕적 디코딩, greedy decoding)으로 설정하세요. CoT는 추론을 통해 최종 정답을 도출하는 과정이며, 추론 과정에는 대개 하나의 정확한 정답이 있으므로 무작위성을 최소화하기 위해 온도를 0으로 설정하는 것이 좋습니다. 


+추가)

CoT는 모델의 파라미터가 클 때 더욱 효과적이다. (반대로 말하면 파라미터 수가 적은 모델에서는 CoT 성능이 떨어진다. 100B 이하)
사람이 직접 사고 과정을 문장으로 작성해야 해서 번거롭다. 
프롬프트 완성도가 높지 않으면 결과도 별로 좋지 않다. 

 

Self-consistency: 여러 생각의 길 탐색하기 

CoT가 AI에게 처음으로 차근차근 생각하는 법을 가르쳐줬다면, Self-consistency는 이를 한 단계 더 발전시킨 방법입니다. “한 번만 생각하지 말고, 여러 번 다양하게 생각한 다음 가장 많이 나온 답을 선택하자”는 접근법으로 추론 능력을 더욱 강화한 프롬프팅 기법입니다. 

일반적인 CoT는 문제를 하나의 길로만 풀어나갑니다. 단순한 '탐욕적 디코딩' 전략을 사용하기 때문입니다. 탐욕적 디코딩은 온도 설정이 0일 때, 다음 토큰으로 올 여러 선택지 중 확률이 가장 높은 하나만 고르는 방식입니다. 그러나 실제 추론에서는 약간의 불확실성이 존재할 수 있으며, 가장 높은 확률을 선택하는 것이 항상 최적의 결과로 이어지지는 않습니다. 만약 초기 단계에서 잘못된 선택을 하면 그 오류가 이후 모든 추론 과정에 영향을 미쳐, 답에서 완전히 멀어질 수 있는 것입니다. 또한 실제 문제 해결에서는 여러 가지 접근법이 있을 수 있는데, 탐욕적 디코딩은 다양한 가능성을 무시한다는 문제점도 있습니다. 

이러한 한계 때문에 CoT로도 잘못된 추론이 발생하기도 합니다. Self-consistency는 이 문제를 해결하기 위해 여러 갈래의 길을 동시에 탐색합니다. 같은 문제를 여러 번 풀어보고(샘플링), 가장 많이 나온 답을 최종 답으로 채택(다수결 투표)하는 방식이죠. 마치 중요한 결정을 내릴 때 여러 전문가의 의견을 듣고 다수결로 결정하는 것과 비슷합니다. 이로써 우연한 오류나 편향을 줄이고, LLM의 응답의 정확성과 일관성을 향상시킵니다. 다만 동일한 프롬프트를 여러 번 실행하므로 계산 비용이 많이 든다는 단점도 있습니다.

 

어떻게 다양한 길을 동시에 찾을까 

  • 다양한 추론 경로 생성: LLM에 동일한 프롬프트를 여러 번 제공합니다. 높은 temperature 설정으로 모델이 다양한 추론 경로와 관점을 생성하도록 합니다. (temperature를 높게 설정하는 전략을 샘플링에서도 다뤘습니다. temperature를 높이면 토큰 선택의 무작위성을 높여 다양한 출력을 유도합니다.) 
  • 각 응답에서 답변 추출: 생성된 여러 응답에서 최종 답변을 추출합니다.
  • 가장 많이 나온 답변 선택: 가장 일반적인 답변을 선택합니다. 추출된 답변들 중에서 가장 빈번하게 나타나는 답변을 최종 답변으로 선택합니다.

 

활용 사례

백서에서는 홈페이지에서 버그가 발생했다며, 이를 비꼬는 말투로 제보한 이메일을 보여주고 이 메일이 중요한지 중요하지 않은지를 분류하라는 예시를 들었습니다. 동일한 프롬프트를 계속해서 넣어주자, ‘중요함’과 ‘중요하지 않음’이 랜덤하게 나오는 모습을 볼 수 있었습니다. 만약 10번 반복했을 때 중요함이 7번, 중요하지 않음이 3번 나왔다면 ‘중요함’으로 최종 분류하는 방식이 Self-consistency입니다. 이처럼 Self-consistency는 미묘한 뉘앙스나 맥락으로 LLM이 오해할 수 있는 작업에서 유용하게 활용될 수 있습니다. 

수학 문제 해결에 CoT와 Self-consistency를 적용해보겠습니다. 

A와 B는 도서관에서 함께 책을 정리하고 있습니다. A는 혼자서 모든 책을 4시간 안에 정리할 수 있고, B는 혼자서 6시간 안에 정리할 수 있습니다. 두 사람이 함께 일할 경우, 모든 책을 정리하는 데 얼마나 시간이 걸릴까요? 단계별로 생각해봅시다.

temperature(0.7 이상)로 여러 번 실행하고 결과를 집계했을 때, 

응답 1: 2.4시간 (올바른 답)

응답 2: 2시간 24분 (올바른 답)

응답 3: 2.5시간 (잘못된 계산)

응답 4: 2.4시간 (올바른 답)

응답 5: 2.4시간 (올바른 답)

최종 답변: 2.4시간 (다수결) 으로 정답을 식별할 수 있습니다. 

Self-consistency을 사용할 때에는 추론 과정과 최종 답변을 분리하여 추출해야 합니다. 즉, 최종 결정을 할 때에는 답변만 집계하여 가장 빈번히 등장한 답을 선택해야 한다는 뜻입니다. 모델은 가끔 올바른 답을 내놓으면서도 잘못된 추론 과정을 생성할 수 있기 때문입니다. 굳이 추론 과정까지 복잡하게 고려할 필요 없이 최종 답변들만 비교하면 정확한 답변을 신속하게 구할 수 있습니다. 

 

정리

이번 편에서 다룬 Chain of Thought와 Self-consistency는 LLM이 복잡한 추론 작업을 수행하는 데 있어 획기적인 기법입니다. 이는 단순히 최종 답변만 생성하는 것이 아니라, 인간과 유사한 사고 과정을 모방함으로써 더 정확하고 신뢰할 수 있는 결과를 도출합니다. 

두 가지 테크닉은 약간의 추가 비용과 시간이 들더라도, 복잡한 문제에서 더 나은 결과를 얻기 위한 기법입니다. 특히 복잡한 수학 문제, 코드 생성, 논리적 추론이 필요한 작업에서 LLM의 성능을 크게 향상시킬 수 있다는 점을 기억해두시면 좋겠습니다. 




 

재밌게 읽으셨나요?
이 글이 흥미로웠다면 제가 직접 쓰고 만드는
AI 안테나 뉴스레터도도 재밌을 거예요!
매주 수요일마다 주요 AI 소식과 인사이트를
메일함에 넣어드립니다.
AI 안테나에서 또 만나요.

https://eddienewsletter.stibee.com/

 

AI안테나

인공지능과 함께 만드는 AI 뉴스

eddienewsletter.stibee.com