자기 일관성(Self-Consistency) 프롬프팅은 모델에게 같은 추론 문제를 여러 번 묻고 가장 자주 나온 답을 고르는 방법입니다. 생각의 사슬(CoT) 프롬프팅처럼 실행마다 자기 추론을 쓰는데, 모델은 단어를 어느 정도 무작위로 샘플링하므로 실행마다 다른 경로를 갑니다. 올바른 경로는 같은 답에 도달하는 경향이 있고, 실수는 서로 다른 오답으로 흩어지는 경향이 있습니다. 다수결은 이 차이를 이용합니다.
이 기법은 Wang 등의 2022년 논문 "Self-Consistency Improves Chain of Thought Reasoning in Language Models"에서 나왔습니다. 이 논문은 여러 추론 경로를 샘플링해 투표하는 방식과 탐욕적으로 고른 답 하나를 비교했고, 투표가 산수와 상식 추론 벤치마크에서 정확도를 높인다는 것을 발견했습니다.
아래 블록은 같은 프롬프트를 세 번 실행한 결과입니다. 탭 하나가 한 번의 실행이고 각자의 답변이 있습니다. 두 번은 올바르게 셌고, 한 번은 저지르기 쉬운 실수를 했습니다.
자리별로 7을 세어 보겠습니다.
- 일의 자리: 7, 17, 27, 37, 47, 57, 67, 77, 87, 97. 7이 10개입니다.
- 십의 자리: 70부터 79까지. 7이 10개 더 있습니다.
- 백의 자리: 세 자리 수는 100뿐이고, 7이 없습니다.
77은 두 목록에 모두 들어 있는데, 7이 두 개 있으므로 맞게 센 것입니다.
정답: 20
2번 실행은 조금 다른 질문에 답했습니다. 숫자 7이 몇 번 나오는지가 아니라, 7이 들어 있는 수가 몇 개인지에 답한 것입니다. 이 추론도 다른 두 개만큼 자신 있게 읽히고, 이것만 봤다면 의심할 이유가 없었을 것입니다. 세 번의 실행에서 투표 결과는 20, 19, 20이고, 다수의 답이 정답입니다.
자기 일관성의 원리
- 답의 줄이 정해진 생각의 사슬 프롬프트를 쓰세요. 추론을 먼저, 최종 답을 마지막에, "정답: N"처럼 찾을 수 있는 형식으로 요청하세요. 정해진 줄이 없으면 각 실행의 답을 찾으려고 모든 실행을 읽어야 합니다.
- 무작위성을 켜고 여러 번 샘플링하세요. 각 실행이 다른 경로를 갈 수 있어야 합니다. API에서는 0보다 큰 temperature가 이 역할을 합니다. temperature 0에서는 대부분의 실행이 같은 추론을 반복할 것이고, 실수를 다섯 번 반복하는 것은 증거가 아닙니다.
- 각 실행에서 최종 답을 뽑으세요. 이 단계에서는 추론을 무시하세요. 서로 다른 경로로 20에 도달한 두 실행은 20에 대한 두 표입니다.
- 가장 흔한 답을 고르세요. 세기 전에 정규화해서 "20", "20.", "스무 번"이 같은 답으로 세어지게 하세요.
일치 정도 자체도 쓸모 있는 정보입니다. 다섯 실행이 모두 일치하면 우연한 실수일 가능성은 낮습니다. 표가 세 갈래로 갈리면 그 문제는 모델에게 어렵다는 뜻이고, 답을 직접 확인하거나 프롬프트를 다시 쓰라는 신호입니다. 논문은 샘플 간 일치도가 높은 질문일수록 정답일 가능성이 높다는 것도 보고했습니다.
손으로 하는 자기 일관성
어떤 채팅 앱에서든 이 기법을 쓸 수 있습니다. 프롬프트를 보내고, 마지막 줄을 적어 둔 다음, 또 하나의 독립적인 실행을 얻으세요. 다시 생성 버튼을 누르거나 같은 프롬프트를 새 대화에 붙여 넣으면 됩니다. 답이 세 개나 다섯 개가 될 때까지 반복하세요.
같은 대화에서 "확실해?"나 "다시 해 봐"라고 다시 묻지 마세요. 모델은 이전 답변을 볼 수 있으므로 새 답은 독립적이지 않습니다. 첫 답을 반복하거나, 여러분이 의심하는 것처럼 보였다는 이유만으로 답을 바꾸는 경향이 있습니다. 어느 쪽도 투표가 아닙니다.
아래 프롬프트는 투표를 위해 준비되어 있습니다. 여러분의 질문과 답 형식을 넣고 여러 번 실행해 보세요.
펜 12자루는 12 ÷ 3 = 4묶음입니다.
4묶음의 가격은 4 × 2,000원 = 8,000원입니다.
10,000원에서 거스름돈: 10,000원에서 8,000원을 빼면 2,000원입니다.
정답: 2,000원
투표를 가능하게 하는 것은 형식 부분입니다. 이 부분을 끄면 실행마다 답을 다르게 표현하는 경향이 있고, 흔히 텍스트 중간 어딘가에 답을 쓰기 때문에, 간단한 세기가 꼼꼼한 읽기로 바뀝니다.
코드로 하는 자기 일관성
코드에서는 반복문이 짧습니다. 같은 프롬프트를 N번 실행하고, 답의 줄을 뽑고, 개수를 셉니다. 이 버전은 OpenAI Python SDK를 쓰고, temperature를 설정할 수 있는 API라면 어디서든 같은 방식으로 동작합니다.
import re
from collections import Counter
from openai import OpenAI
client = OpenAI()
MODEL = "your-model-id" # e.g. from your provider's model list
PROMPT = (
"How many times does the digit 7 appear when you write out all the whole "
"numbers from 1 to 100? Think it through step by step, then give the final "
'answer on the last line in the form "Answer: N".'
)
def final_answer(text):
# Also matches "**Answer: 20**", since chat models often bold the last line.
lines = re.findall(r"^\**Answer:\**\s*(.+)$", text, re.MULTILINE)
return lines[-1].strip(" *.") if lines else None
answers = []
for _ in range(5):
response = client.chat.completions.create(
model=MODEL,
temperature=0.8,
messages=[{"role": "user", "content": PROMPT}],
)
answers.append(final_answer(response.choices[0].message.content))
votes = Counter(a for a in answers if a is not None)
if votes:
best, count = votes.most_common(1)[0]
print(f"{best} ({count} of {len(answers)} runs agree)")
else:
print("No run gave an answer line.")
실행들은 서로 독립적이므로 실제 서비스에서는 하나씩 차례로 보내지 않고 병렬로 보낼 것입니다. 일부 추론 모델은 기본 temperature만 받고, 값을 설정하면 오류를 돌려줍니다. 그런 모델에는 temperature를 빼세요. 기본값이 이미 샘플링을 하므로 실행 결과는 여전히 달라집니다.
언제 쓰고, 비용은 얼마인가
자기 일관성은 세 가지가 참일 때 값어치를 합니다. 답이 짧고 비교할 수 있으며(숫자, 라벨, 선택지), 틀린 답의 대가가 호출 몇 번보다 크고, 모델이 그 작업에서 아직 믿을 만하지 않을 때입니다. 수학 문장제, 까다로운 경계 사례가 있는 분류, 객관식 문제가 잘 맞습니다.
비용은 답 하나의 대략 N배 토큰이고, 모델이 모든 실행에서 같은 오해를 공유할 때는 도움이 되지 않습니다. 다섯 실행이 모두 같은 실수를 하면 투표는 만장일치로 틀립니다. 투표는 우연한 실수를 줄일 뿐 체계적인 오류는 줄이지 못하므로, 가끔 알려진 결과와 답을 대조하는 확인을 대신할 수 없습니다.
답하기 전에 내부적으로 추론하는 모델은 실행마다 이미 문제를 길게 풀기 때문에, 투표로 얻는 이득이 줄어드는 경향이 있습니다. 그래도 실행 결과가 엇갈리는 어려운 문제에서는 여전히 효과가 있을 수 있습니다.
자기 일관성은 완성된 답에만 투표합니다. 생각의 나무(ToT) 프롬프팅은 한 걸음 더 나아가 문제를 푸는 도중에 부분 추론을 비교하고, 유망한 가지는 남기고 약한 가지는 답에 이르기 전에 버립니다.
자주 묻는 질문
자기 일관성 프롬프팅이란 무엇인가요?
자기 일관성 프롬프팅은 Wang 등(2022)이 제안한 기법입니다. 샘플링을 켠 상태에서 같은 생각의 사슬 프롬프트를 여러 번 보내 실행마다 다른 경로로 추론하게 한 다음, 가장 자주 나온 최종 답을 고릅니다. 추론 사슬 하나를 믿는 대신 여러 사슬의 투표로 바꾸는 것입니다.
자기 일관성에는 샘플을 몇 개 써야 하나요?
일상적인 용도라면 가끔 생기는 실수를 투표로 이기기에 3~5회면 충분하고, 홀수로 하면 두 답이 동점이 되는 일을 피할 수 있습니다. 원 논문은 질문마다 훨씬 많은 경로를 샘플링했고, 샘플이 많을수록 정확도가 계속 올라가지만 그 폭은 점점 작아진다는 것을 발견했습니다. 틀린 답의 대가가 크면 더 많이, 비용이나 속도가 중요하면 더 적게 실행하세요.
자기 일관성과 생각의 사슬은 어떻게 다른가요?
생각의 사슬은 모델이 답 앞에 추론을 쓰는 한 번의 실행입니다. 자기 일관성은 그 위에 쌓습니다. 생각의 사슬을 여러 번 실행하고 최종 답에 투표합니다. 생각의 사슬은 프롬프트를 바꾸고, 자기 일관성은 답을 몇 개 모으고 어떻게 고를지를 바꿉니다.
자기 일관성은 에세이나 열린 답변에도 통하나요?
바로는 안 됩니다. 투표하려면 같은지 비교할 수 있는 답이 필요하기 때문입니다. 숫자, 라벨, 객관식 보기, 짧은 사실 같은 것입니다. 열린 텍스트에서 흔히 쓰는 우회법은 여러 버전을 생성한 다음 다른 버전들과 가장 잘 맞는 것이 무엇인지 모델에게 묻는 것이지만, 이는 개수를 세는 것이 아니라 판단입니다.
ChatGPT나 Claude에서 자기 일관성을 쓸 수 있나요?
네, 손으로 할 수 있습니다. 새 대화 여러 개에 프롬프트를 보내거나 답변을 여러 번 다시 생성하고, 실행마다 최종 답을 적어 두세요. 같은 대화에서 다시 묻지 말고 새 대화나 다시 생성 버튼을 쓰세요. 이전 답을 볼 수 있는 모델은 그 답을 반복하는 경향이 있기 때문입니다.