왜 "확신에 찬 오답"이 문제인가

LLM은 틀린 답도 매끄럽고 단정적인 문장으로 출력한다. 문제는 이 자신감이 실제 정답 확률과 무관하다는 점이다. 잘 캘리브레이션된 모델이라면 "확신도 0.9"라고 말할 때 실제로 90% 맞아야 한다. 하지만 RLHF를 거친 대화형 모델은 대체로 과신(overconfidence) 경향이 강해, 자기평가 점수를 그대로 임계값으로 쓰면 위험하다. 자동 승인, 문서 추출, 분류 파이프라인처럼 사람이 매번 확인하지 않는 곳일수록 "언제 모델을 믿지 않을지"를 정량적으로 정하는 일이 핵심이 된다.

세 가지 신뢰도 소스

실무에서 쓸 수 있는 신뢰도 신호는 크게 세 가지다. 각각 비용과 신뢰성이 다르다.

방식비용특징
자기평가 (0~1 점수 요청)낮음편향 심함, 과신, 단독 사용 비권장
로그 확률 (logprobs)없음토큰 단위 실제 분포, 분류·추출에 강함
샘플 일관성 (self-consistency)높음N회 샘플링 후 다수결, 추론 문제에 강함

로그 확률로 토큰 신뢰도 뽑기

분류나 라벨링처럼 출력이 짧고 정해진 경우, 해당 토큰의 로그 확률이 가장 저렴하고 정직한 신호다. API에서 logprobs를 켜고 선택된 토큰의 확률을 확인한다.

from anthropic import Anthropic
import math

client = Anthropic()

resp = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=5,
    messages=[{
        "role": "user",
        "content": "다음 리뷰의 감성을 positive/negative 중 하나로만 답하라: "
                   "'배송은 느렸지만 품질은 만족스럽다'"
    }],
)

# 응답 텍스트와 함께 토큰별 확률을 확인해
# 선택 토큰의 logprob이 -0.02이면 확률 ~0.98, -1.6이면 ~0.20
label = resp.content[0].text.strip()
print(label)

로그 확률을 확률로 되돌릴 때는 p = math.exp(logprob)를 쓴다. 여러 토큰으로 이뤄진 답이면 토큰 확률의 곱(=로그 확률의 합)을 길이로 정규화해 평균을 내야 짧은 답이 유리해지는 편향을 막을 수 있다.

캘리브레이션 곡선으로 임계값 정하기

모델이 말한 확신도가 실제 정확도와 얼마나 일치하는지는 라벨된 검증셋으로 직접 측정해야 한다. 확신도를 구간으로 나눠, 각 구간의 실제 정답률을 그려보면(reliability diagram) 과신 여부가 바로 드러난다.

import numpy as np

def ece(confidences, correct, n_bins=10):
    """Expected Calibration Error: 낮을수록 잘 보정됨"""
    bins = np.linspace(0, 1, n_bins + 1)
    err = 0.0
    for lo, hi in zip(bins[:-1], bins[1:]):
        mask = (confidences > lo) & (confidences <= hi)
        if mask.sum() == 0:
            continue
        acc = correct[mask].mean()      # 구간 실제 정확도
        conf = confidences[mask].mean() # 구간 평균 확신도
        err += (mask.sum() / len(confidences)) * abs(acc - conf)
    return err

conf = np.array([0.95, 0.80, 0.99, 0.60, 0.75])
correct = np.array([1, 1, 0, 0, 1])
print(f"ECE = {ece(conf, correct):.3f}")

ECE가 크면 확신도를 그대로 쓸 수 없다. 이때 온도 스케일링(temperature scaling)이나 단순 이소토닉 회귀로 후처리하면 순위는 유지한 채 절대값만 실제 정확도에 맞게 재보정할 수 있다.

임계값 기반 라우팅과 폴백

보정된 확신도가 있으면 파이프라인 정책은 단순해진다. 검증셋에서 목표 정밀도(예: 99%)를 만족하는 임계값 τ를 찾고, 그 이하는 자동 처리하지 않는다. 낮은 확신 케이스만 더 큰 모델·사람 검토·self-consistency로 라우팅하면, 전체 비용은 낮추면서 위험 구간만 집중 방어할 수 있다. 핵심은 "정확도"가 아니라 "커버리지 대 정밀도" 곡선으로 의사결정하는 것이다.

주의점

  • 자기평가 점수 단독 사용 금지. 과신이 심하고 프롬프트 문구에 민감하다.
  • 로그 확률은 같은 모델·같은 프롬프트 형식 안에서만 비교 가능하다. 모델을 바꾸면 임계값을 다시 캘리브레이션해야 한다.
  • 자유형 장문 생성에는 토큰 확률이 사실 정확성과 약하게만 연결된다. 이 경우 self-consistency나 근거 검증(retrieval 대조)이 더 낫다.
  • 캘리브레이션은 데이터 분포에 의존한다. 입력 도메인이 바뀌면 ECE를 재측정해 임계값이 여전히 유효한지 확인해야 한다.