Self-Consistency란? 여러 추론 경로로 AI 정확도 올리기
같은 질문을 여러 번 던지는 것이 전략이 된다. Self-Consistency로 AI 정답률을 극적으로 높이는 법.
들어가며: '일관성 없음'을 무기로 바꾼다
프롬프트 엔지니어링을 처음 시작하는 사람들이 공통적으로 겪는 당혹스러운 순간이 있습니다. 분명 어제 잘 작동하던 프롬프트가 오늘은 다른 답을 냅니다. 같은 프롬프트를 두 번 실행했더니 결과가 다릅니다. 처음에는 버그라고 생각합니다. 프롬프트를 다듬어도, 다시 실행해도 결과는 매번 조금씩 다릅니다.
이것은 버그가 아닙니다. LLM의 설계된 특성입니다.
언어 모델은 텍스트를 생성할 때 다음에 올 토큰을 확률 분포에서 샘플링합니다. 결정론적으로 가장 높은 확률의 토큰만 고르는 것이 아니라, 설정된 temperature 값에 따라 확률 분포에서 무작위로 선택합니다. 이 덕분에 같은 프롬프트에서 다양한 답이 나옵니다. 창의적 글쓰기에서는 장점입니다. 그런데 수학 문제, 논리 추론, 사실 판단 같은 태스크에서는 어떨까요?
정답이 하나인 문제에서 AI가 매번 다른 답을 낸다면, 어느 쪽을 신뢰해야 할까요?
Self-Consistency(왕 등, 2022)는 이 질문에 대한 강력한 답입니다. 핵심 직관은 단순합니다. 올바른 추론 경로는 수렴하고, 잘못된 추론 경로는 발산한다. 같은 질문을 여러 번 실행했을 때 틀린 답들은 제각각 다른 방향으로 흩어지는 반면, 맞는 답은 반복적으로 등장합니다. 이 수렴 패턴을 포착해서 다수결로 최종 답을 고르면 단일 실행보다 훨씬 높은 정확도를 달성할 수 있습니다.
1. 왜 단일 실행은 실패하는가
1.1. Temperature와 샘플링의 본질
LLM이 텍스트를 생성하는 방식을 이해하면 Self-Consistency가 왜 효과적인지 직관적으로 납득됩니다.
모델은 매 토큰을 생성할 때마다 어휘 전체에 대한 확률 분포를 계산합니다. 예를 들어 "사과는 ___색이다"라는 문장 뒤에 올 단어의 확률 분포는 "빨간(0.55)", "초록(0.30)", "노란(0.10)", "파란(0.02)" 식으로 구성됩니다. 여기서 두 가지 전략이 있습니다.
Greedy Decoding: 항상 가장 높은 확률의 토큰을 선택합니다. 결정론적이고 재현 가능합니다. 하지만 각 단계에서의 '지역 최적해'를 따라가다 보면 전체 문장의 품질이 낮아지는 경우가 많습니다. 여행으로 비유하자면 매 갈림길에서 가장 인기 있는 길만 고르는 것입니다. 안전해 보이지만, 결국 가장 평범한 경로에 도달합니다.
Sampling: temperature 값이 0보다 크면 확률 분포에서 무작위로 샘플링합니다. temperature = 1.0이면 원래 분포 그대로 샘플링하고, 값이 높아질수록 낮은 확률의 토큰도 선택될 가능성이 높아집니다. 이 무작위성 덕분에 같은 프롬프트에서 매번 다른, 때로는 더 창의적인 결과가 나옵니다.
문제는 추론 태스크(reasoning task)에 있습니다. 창의적 답변이 필요한 것이 아니라 정확한 답이 필요한 상황에서, sampling의 무작위성은 오류의 원천이 됩니다. 단 한 번의 샘플링에서 잘못된 추론 경로에 들어서면, 그 오류가 최종 답까지 이어집니다.
1.2. 단일 실행의 취약성
구체적인 예를 보겠습니다. 다음 수학 문제를 AI에게 물어봅니다.
한 상점에서 사과를 12개 구입했습니다. 그 중 1/3을 먹었고,
남은 것 중 절반을 친구에게 줬습니다. 지금 남은 사과는 몇 개입니까?
단일 실행에서 모델이 선택하는 추론 경로는 여러 가지일 수 있습니다.
- 경로 A (정답): 12개 → 1/3 먹음(4개) → 8개 남음 → 절반을 줌(4개) → 4개 남음
- 경로 B (오류): 12개 → 1/3 먹음(4개) → 8개 남음 → "남은 것 중 절반"을 전체의 절반으로 오해 → 2개 남음
- 경로 C (오류): 12개 → "1/3을 먹었고 절반을 줬으니" 직접 계산 → 12 × (1 - 1/3 - 1/2) = 2 → 2개 남음
단일 실행은 이 세 경로 중 하나를 무작위로 탑니다. 어떤 경로를 타느냐는 샘플링의 운에 달려 있습니다. 하지만 여러 번 실행하면 어떨까요?
2. Self-Consistency의 동작 원리
2.1. Sample → Reason → Aggregate
Self-Consistency는 세 단계로 작동합니다.
Step 1 — 다양한 추론 경로 샘플링 (Sample)
동일한 프롬프트를 여러 번 실행합니다. temperature를 0이 아닌 값(보통 0.70.9)으로 설정해 각 실행이 서로 다른 추론 경로를 탐색하도록 유도합니다. 실행 횟수는 태스크의 난이도와 비용 허용 범위에 따라 결정하지만, 일반적으로 520회 정도면 충분한 수렴을 얻을 수 있습니다.
Step 2 — 각 경로에서 독립적으로 추론 (Reason)
각 실행이 서로를 참조하지 않고 독립적으로 문제를 풀어야 합니다. Chain of Thought와 결합하면 더 강력합니다. "단계별로 생각해줘"라는 지시를 추가하면 각 실행이 추론 과정을 명시적으로 서술하고, 이를 통해 최종 답이 도출되는 경로를 추적할 수 있습니다.
Step 3 — 최종 답 집계 (Aggregate)
모든 실행의 최종 답을 모아 다수결로 최종 답을 결정합니다. 5번 실행에서 4개, 4개, 2개, 4개, 4개가 나왔다면 최종 답은 "4개"입니다. 이 과정에서 추론 경로는 버려지고 최종 답만 집계됩니다. 다양한 경로가 같은 정답에 수렴했다는 사실 자체가 그 답의 신뢰도를 높여줍니다.
2.2. 왜 다수결이 정확도를 높이는가
수학적 직관으로 이해해 보겠습니다.
단일 실행에서 정답을 낼 확률이 70%인 문제가 있다고 가정합니다. 이 문제를 5번 독립적으로 실행하고 다수결을 취했을 때의 정확도는 얼마일까요?
다수결이 틀리려면 5번 중 3번 이상이 틀려야 합니다. 이 확률을 계산하면:
P(다수결 오류) = P(3번 이상 오류)
= C(5,3)×(0.3)³×(0.7)² + C(5,4)×(0.3)⁴×(0.7)¹ + C(5,5)×(0.3)⁵
= 0.0837 + 0.0284 + 0.0024
≈ 0.163
즉 단일 실행의 정확도 70%가 5회 다수결을 통해 약 84%로 향상됩니다. 실행 횟수를 10회로 늘리면 93%에 가까워집니다.
이 효과는 원래 정확도가 50%를 크게 넘는 태스크에서 작동합니다. 단일 실행에서 이미 틀릴 확률이 더 높은 문제라면 다수결도 틀린 쪽으로 수렴하기 때문입니다. 이것이 Self-Consistency를 적용할 수 있는 태스크와 없는 태스크를 구분해야 하는 이유입니다.
3. 언제 쓰고, 언제 버려야 하는가
Self-Consistency가 강력한 만큼, 무조건 적용하는 것은 비효율적입니다. 적합한 태스크와 부적합한 태스크를 명확히 구분해야 합니다.
3.1. 효과적인 태스크
Self-Consistency는 정답이 객관적으로 하나이거나 검증 가능한 기준이 있는 태스크에서 효과가 극대화됩니다.
| 태스크 유형 | 예시 | 효과 |
|---|---|---|
| 수학 계산 및 추론 | 다단계 연산, 확률 문제, 기하학 | 매우 높음 |
| 논리 추론 | 삼단논법, 조건부 추론, 퍼즐 | 매우 높음 |
| 사실 기반 분류 | 감정 분류, 카테고리 분류, 오류 감지 | 높음 |
| 코드 디버깅 | 버그 원인 특정, 수정 방향 결정 | 높음 |
| 의학적 진단 보조 | 증상 기반 가능성 추론 | 중간~높음 |
3.2. 효과 없거나 역효과인 태스크
| 태스크 유형 | 이유 |
|---|---|
| 창의적 글쓰기 | 정답이 없음. 다양성 자체가 가치임 |
| 주관적 평가 | 취향, 스타일은 다수결 대상이 아님 |
| 오픈 엔디드 질문 | "삶의 의미는 무엇인가" 류의 질문 |
| 단순 사실 조회 | 명백한 사실은 단일 실행으로 충분함 |
| 맥락 의존적 응답 | 이전 대화 내용을 기억해야 하는 경우 |
창의적 작업에 Self-Consistency를 적용하면 가장 '평균적인' 아이디어가 선택됩니다. 여러 결과 중 가장 독특하고 창의적인 것이 다수결에서 탈락하고, 가장 평범한 것이 선택되는 역효과가 납니다.
4. 실전 구현: 세 가지 패턴
4.1. 패턴 1 — 단순 다수결 (Majority Vote)
가장 기본적인 형태입니다. 같은 프롬프트를 N번 실행하고 가장 많이 나온 답을 선택합니다.
[Self-Consistency 프롬프트 템플릿]
너는 수학/논리 문제를 단계별로 풀어나가는 전문가야.
문제를 받으면 반드시 다음 절차를 따라줘:
1. 문제를 다시 읽고 핵심 조건을 정리한다
2. 단계별로 풀이 과정을 명시적으로 서술한다 (CoT)
3. 최종 답을 "정답: [답]" 형식으로 명확하게 마무리한다
문제: {{problem}}
이 프롬프트를 5~10회 실행한 뒤 "정답: ___" 뒤에 오는 값을 집계합니다. 가장 많이 등장한 값이 최종 답입니다.
실제 실행 예시:
실행 1: 정답: 4개
실행 2: 정답: 4개
실행 3: 정답: 2개 ← 오류 경로
실행 4: 정답: 4개
실행 5: 정답: 4개
→ 다수결: 4개 (4/5) ✅
4.2. 패턴 2 — 신뢰도 가중 집계 (Confidence-Weighted)
단순 다수결보다 정교한 방식입니다. 각 실행에서 모델 자신이 답에 대한 확신도를 함께 서술하게 만들고, 높은 확신도를 가진 답에 더 큰 가중치를 부여합니다.
[신뢰도 가중 프롬프트]
다음 문제를 풀어줘. 풀이 과정과 함께 반드시 아래 형식으로 마무리해줘:
정답: [값]
확신도: [낮음 / 보통 / 높음]
근거: [이 확신도를 선택한 이유 한 줄]
문제: {{problem}}
집계 시 "높음"은 가중치 3, "보통"은 2, "낮음"은 1을 적용합니다. 같은 답이 여러 번 나왔더라도 "낮음" 확신도를 가진 답들보다 "높음" 확신도를 가진 답 하나가 더 신뢰할 수 있습니다.
이 패턴은 모델이 자신의 불확실성을 잘 인식하는 경우에 특히 효과적입니다. 최신 모델(GPT-4o, Claude Opus 등)일수록 메타인지 능력이 뛰어나기 때문에 확신도 서술의 신뢰성이 높아집니다.
4.3. 패턴 3 — 메타 판사 패턴 (Meta-Judge)
가장 강력하지만 가장 비용이 많이 드는 방식입니다. 여러 번 실행한 결과를 모두 모아 별도의 프롬프트에 넘기고, AI 스스로 어떤 답이 가장 신뢰할 수 있는지 판단하게 만듭니다.
[메타 판사 프롬프트]
아래는 동일한 문제에 대해 독립적으로 수행된 5개의 풀이입니다.
각 풀이를 검토하고, 가장 논리적으로 타당한 답을 선택해줘.
문제: {{problem}}
풀이 1: {{solution_1}}
풀이 2: {{solution_2}}
풀이 3: {{solution_3}}
풀이 4: {{solution_4}}
풀이 5: {{solution_5}}
판단 기준:
- 각 단계의 논리적 연결이 일관된가
- 문제의 조건을 모두 올바르게 반영했는가
- 계산 오류가 없는가
최종 판단:
- 가장 신뢰할 수 있는 풀이: [번호]
- 선택 근거: [간략 설명]
- 최종 답: [값]
메타 판사 패턴은 단순 다수결과 달리 '왜 이 답이 더 신뢰할 수 있는가'에 대한 설명도 함께 제공합니다. 단순히 정답을 얻는 것에서 그치지 않고, 추론 과정의 품질 자체를 평가하고 싶을 때 특히 유용합니다.
5. Temperature와 실행 횟수 설정
Self-Consistency를 실전에 적용할 때 가장 많이 마주치는 질문이 두 가지입니다. Temperature를 얼마로 설정해야 하는가, 몇 번이나 실행해야 하는가.
5.1. Temperature 설정
temperature = 0으로 설정하면 모델은 항상 같은 답을 냅니다. Greedy Decoding에 가까워지기 때문입니다. 이 경우 여러 번 실행해도 모두 동일한 답이 나오므로 Self-Consistency의 의미가 없습니다.
반대로 temperature = 1.5 이상으로 너무 높게 설정하면 각 실행의 다양성은 높아지지만 동시에 노이즈도 커집니다. 모델이 너무 무작위적으로 작동해 정상적인 추론 경로를 유지하지 못하게 됩니다.
경험적으로 Self-Consistency에 최적인 Temperature 범위는 0.5 ~ 0.9입니다.
| Temperature | 특성 | Self-Consistency 적합성 |
|---|---|---|
| 0.0 | 결정론적, 다양성 없음 | ❌ 의미 없음 |
| 0.1 ~ 0.4 | 안정적이지만 다양성 낮음 | 🔺 제한적 효과 |
| 0.5 ~ 0.7 | 다양성과 안정성 균형 | ✅ 권장 (사실 기반 태스크) |
| 0.7 ~ 0.9 | 다양성 높음 | ✅ 권장 (논리 추론 태스크) |
| 1.0 이상 | 창의성 높음, 노이즈 증가 | ❌ 비권장 |
5.2. 실행 횟수 설정
실행 횟수가 많을수록 정확도가 높아지지만, 비용과 시간도 선형적으로 증가합니다.
원래 Self-Consistency 논문에서는 태스크에 따라 1040회 샘플링을 실험했습니다. 하지만 실제 적용에서는 **510회**가 비용 대비 효과의 최적 균형점입니다. 특히 난이도가 높지 않은 태스크라면 5회만으로도 충분한 수렴을 얻을 수 있습니다.
다음 기준으로 실행 횟수를 결정합니다.
- 3회: 탐색적 판단. 대략적인 경향을 파악할 때.
- 5회: 일반적인 추론 태스크에서 충분한 신뢰도.
- 10회: 높은 신뢰도가 요구되는 중요한 판단.
- 20회 이상: 의료, 법률 등 오류 비용이 극히 높은 태스크.
결론: 프롬프트가 아닌 실행 방식을 설계하다
Self-Consistency는 지금까지 다뤄온 기법들과 성격이 다릅니다. 프롬프트의 내용을 바꾸는 것이 아니라 프롬프트를 실행하는 방식을 바꿉니다. 같은 질문을 단 한 번 물어보는 것이 아니라 여러 경로로 탐색하고, 그 경로들이 공통으로 가리키는 답을 선택하는 것입니다.
이것이 중요한 이유는 신뢰도의 출처가 달라지기 때문입니다. 단일 실행에서 AI가 "정답은 4개입니다"라고 말할 때, 그 신뢰도는 모델의 가중치 안에 인코딩된 내부 확신입니다. 직접 검증할 방법이 없습니다. 반면 Self-Consistency에서 10번 중 9번이 "4개"로 수렴했다는 사실은 외부에서 관측 가능한 신뢰도입니다. 수치로 나타낼 수 있고, 재현할 수 있고, 비교할 수 있습니다.
이 관점에서 Self-Consistency는 단순한 정확도 향상 기법을 넘어, AI 출력의 신뢰도를 정량화하는 방법론입니다.
7편과의 연결: 템플릿으로 자동화하기
7편에서 배운 변수와 템플릿을 활용하면 Self-Consistency 파이프라인을 구조화할 수 있습니다. 샘플링 프롬프트, 집계 로직, 메타 판사 프롬프트를 각각 독립적인 모듈로 만들고 조합하면, 반복적으로 사용 가능한 Self-Consistency 시스템이 완성됩니다.
9편을 향하여: Structured Output
Self-Consistency의 집계 단계에서 한 가지 현실적인 문제가 있습니다. 각 실행의 최종 답을 어떻게 파싱하느냐입니다. 모델이 자유로운 문장 형식으로 답을 내면 집계 스크립트를 작성하기 어렵고, 오류가 생기기 쉽습니다.
이어지는 **[9편: Structured Output – JSON을 99% 안정적으로 받는 법]**에서는 AI의 출력 형식을 JSON이나 정해진 스키마로 고정하는 기법을 다룹니다. Self-Consistency뿐 아니라 AI 출력을 코드로 처리해야 하는 모든 상황에서 필수적인 기술입니다.
