신뢰도
TypeSafe가 확실성을 어떻게 보고하는지, 확률과 어떻게 다른지, 그리고 시스템 동작을 제어하는 데 어떻게 사용하는지 설명합니다.
TypeSafe의 모든 Score 및 Choice 답변에는 선택지(Choice) 또는 레벨(Score)에 걸친 확률 분포를 나타내는 probabilities 속성이 포함됩니다. 모델이 얼마나 확신하는지를 알려주는 것은 그 분포의 모양입니다. 하나의 결과에 집중되어 있으면 확신 있는 답변이고, 넓게 퍼져 있으면 불확실한 답변입니다.
답변의 confidence 속성은 그 모양을 0에서 1 사이의 단일 숫자로 압축하므로, 직접 계산하지 않고도 그 값에 임계값을 적용할 수 있습니다. 모든 확률이 하나의 결과에 실려 있으면 1이고, 확률이 고르게 퍼져 있으면 0입니다. (Noul 답변에는 이 값이 없습니다. 아래 Noul을 참고하십시오.)
신뢰도는 확률에서 도출됩니다
confidence는 답변이 이미 제공하는 확률 분포로부터 계산된 통계량입니다. TypeSafe가 이를 대신 계산하여 모든 Choice 및 Score 답변에 반환하므로, 일반적인 경우 여러분 쪽에서 별도의 작업이 필요하지 않습니다.
예시: 선택지 세 개짜리 choice 질문
확률 분포가 신뢰도를 어떻게 바꾸는지 보기
신뢰도
확률
슬라이더를 움직여 한 선택지의 확률을 바꿔 보세요. 나머지 확률이 자동으로 조정되어 합이 100%로 유지됩니다.
선택: 선택지 A
이 데모가 신뢰도를 계산하는 방법
TypeSafe는 확률이 선택지들에 퍼진 정도로 신뢰도를 계산합니다. 한 선택지에 전부 몰려 있으면 1.0이고, 고르게 퍼질수록 낮아집니다. 이 데모는 (3 × 최대 확률 − 1) / 2 로 선택지 세 개일 때의 신뢰도를 근사합니다.
Choice의 경우 분포는 선택지에 걸친 probabilities입니다. Score의 경우 레벨에 걸친 분포입니다. 두 경우 모두 분포가 평평할수록 신뢰도가 낮습니다. Choice에서 낮은 신뢰도는 흔히 어느 선택지도 다른 선택지보다 확실한 우위에 있지 않다는 뜻이고, Score에서 낮은 신뢰도는 흔히 레벨이 모호하거나 다차원적이거나, 상태에 판단할 근거가 충분히 담겨 있지 않다는 뜻입니다.
문제 유형별 정확한 공식은 신뢰도 계산 방법에 있으므로, confidence 값이 답변 자체의 probabilities에서 어떻게 나오는지 확인할 수 있습니다.
“모르겠습니다”는 유용한 신호입니다
지능형 시스템이, 인간이든 기계든, 솔직한 불확실성을 표현할 수 없다면 그 시스템은 신뢰할 수 없습니다.
신뢰도는 모델이 “이건 확실하지 않습니다”라고 말할 수 있는 내장 메커니즘을 제공합니다. 이를 통해 코드가 확실성 수준별로 다른 동작을 구현할 수 있으며, 이것이 실제로 의존할 수 있는 시스템을 구축하는 토대입니다.
코드에서 신뢰도를 사용하는 세 가지 경로
유용한 출발 패턴은 신뢰도를 세 구간으로 나누고, 각 구간이 서로 다른 시스템 동작을 낳도록 하는 것입니다.
높은 신뢰도: 자동으로 실행합니다. 모델이 명확하게 판단했으므로 사람의 개입 없이 진행할 수 있습니다.
중간 신뢰도: 주의하여 진행합니다. 모델이 합리적인 답변을 내놓았지만 확신하지는 못합니다. 상황에 따라 사용자에게 확인을 요청하거나, 검토 대상으로 표시하거나, 행동하기 전에 정보를 더 수집할 수 있습니다.
낮은 신뢰도: 행동하지 않습니다. 사람에게 넘기거나, 명확화를 요청하거나, 다른 시스템으로 폴백합니다. 모델이 정보가 충분하지 않거나 질문이 적합하지 않다고 알려주는 것입니다.
그 경계를 어디에 그을지는 위험도에 달려 있습니다.
임계값은 위험에 따라 달라집니다
신뢰도 임계값은 하나의 숫자가 아닙니다. 같은 시스템 안의 서로 다른 행동은 틀렸을 때의 결과에 따라 서로 다른 수준에서 게이팅되어야 합니다.
response = client.system_one(
state=user_message,
questions={
"action": Choice(
instructions="What is the user trying to do?",
criteria={
"check_balance": "View account balance",
"approve_transfer": "Approve the pending withdrawal request",
"support": "Get help with an issue",
},
),
},
)
action = response.answers["action"]
confidence = action.confidence
if confidence < 0.5:
# Model is genuinely unsure. Don't guess.
route_to_human(user_message)
elif action.choice == "check_balance":
# Low stakes. Showing the wrong screen is recoverable.
show_balance(account_id)
elif action.choice == "approve_transfer":
if confidence > 0.9:
# High stakes, high confidence. Proceed with confirmation.
confirm_then_execute(account_id)
else:
# High stakes, moderate confidence. Verify first.
ask_user_to_confirm(account_id)
0.5 신뢰도 하한은 모델이 진짜 불확실하다고 보고한 모든 것을 잡아냅니다. 그 위에서는 확인 없이 행동하기 위한 임계값이 읽기 전용 작업보다 파괴적 작업에서 더 높습니다. 위험 허용 범위는 여러분의 코드가 인코딩합니다.
신뢰도 계산 방법
문제 유형마다 분포를 요약하는 방식이 조금씩 다릅니다. Noul은 결과가 두 개이고, Choice는 순서가 없는 임의 개수의 선택지를 가지며, Score의 레벨은 순서가 있으므로, 아래의 각 공식은 앞의 공식 위에 쌓입니다.
TypeSafe의 confidence는 분포를 요약하는 하나의 합리적인 방식이며, 유일한 방식은 아닙니다. 우리가 고정된 척도를 반환하는 이유는 모든 답변에 합당한 기본값을 함께 제공하기 위해서입니다. 첫 호출부터 confidence로 게이팅할 수 있고, 모든 질문에 동일한 0에서 1 척도를 쓰며, 직접 통계량을 골라 검증할 필요가 없습니다. 아래 공식은 정확하고 모든 답변에 전체 probabilities가 담겨 있으므로, 대신 애플리케이션에 가장 중요한 척도를 계산할 수 있습니다.
Noul
Noul 답변은 답이 yes일 확률 $p$ 하나이며, TypeSafe는 그에 대해 별도의 confidence를 반환하지 않습니다. 그 확률 자체가 불확실성을 담고 있습니다. 0.5에 가까운 값은 모델이 확신하지 못한다는 뜻이며, 이를 직접 임계값으로 다루는 방법은 Noul 페이지에서 설명합니다.
그래도 신뢰도 형식의 숫자가 필요하다면, 예를 들어 같은 코드로 Noul과 Choice를 게이팅하려면, 0.5로부터의 거리를 사용합니다:
$$ \text{confidence} = |2p - 1| $$
이렇게 하면 $p = 0.5$일 때 0, $p = 0$ 또는 $p = 1$일 때 1이 됩니다. 이는 아래 Choice 공식을 yes/no Choice에 적용한 것이기도 하므로, Choice 신뢰도와 같은 척도에 놓입니다.
Choice
Choice는 같은 아이디어를 임의 개수의 선택지로 확장합니다. $n$개의 선택지를 가진 Choice에서 $p_{\max}$가 선택된 선택지의 확률일 때:
$$ \text{confidence} = \frac{p_{\max} - \frac{1}{n}}{1 - \frac{1}{n}} $$
이것은 최고 확률이 선택지별 균등 분할 $\frac{1}{n}$보다 얼마나 위에 있는지를, 균등 분할을 0, 확실성을 1로 하는 척도에서 측정합니다. 최고 확률만 반영되므로, $(0.6, 0.3, 0.1)$과 $(0.6, 0.2, 0.2)$는 모두 신뢰도 0.4입니다.
def choice_confidence(probabilities: list[float]) -> float:
n = len(probabilities)
return (max(probabilities) - 1 / n) / (1 - 1 / n)
choice_confidence(list(answer.probabilities.values()))
이 페이지 맨 위의 탐색기는 이 공식을 세 개의 선택지로 사용합니다.
같은 probabilities로 계산되는 두 가지 더 단순한 척도도 실제로 매우 효과적인 경우가 많아, confidence와 함께 시도해 볼 가치가 있습니다:
- 최고 확률, $p_{\max}$. “선택된 선택지가 얼마나 그럴듯한가”로 바로 읽히므로 임계값을 따지기 쉽습니다. 그 의미는 선택지 개수에 달려 있는데, 0.5는 선택지 두 개에서는 약한 답변이지만 열 개에서는 강한 답변이므로, 임계값은 질문마다 설정하십시오.
- 최고 대 두 번째 비율, $p_{\max} / p_{\text{second}}$. 선택된 선택지가 차점을 얼마나 명확히 앞서는지를 측정하고, 나머지가 어떻게 퍼져 있는지는 무시합니다. 많은 실제 의사 결정은 상위 두 후보로 귀결되며, 이 비율은 바로 그 점을 겨냥합니다.
Score
Score의 레벨은 순서가 있으므로, 그 공식은 확률이 가장 가능성 높은 레벨에서 얼마나 떨어져 있는지도 셉니다. $0$부터 $n - 1$까지 번호가 매겨진 $n$개의 레벨을 가진 Score에서 $p_i$가 레벨 $i$의 확률이고 $m$이 가장 가능성 높은 레벨일 때:
$$ \text{confidence} = \max\left(0,\ 1 - \frac{\sum_i p_i , |i - m|}{\text{MAD}{\text{unif}}}\right) \qquad \text{MAD}{\text{unif}} = \frac{1}{n} \sum_i \left| i - \frac{n - 1}{2} \right| $$
분자의 합은 답변과 가장 가능성 높은 레벨 사이의, 레벨 단위 확률 가중 평균 거리입니다. $\text{MAD}_{\text{unif}}$는 모든 레벨에 고르게 퍼졌을 때의 같은 종류의 평균 거리를 가운데 레벨에서 잰 것입니다. 신뢰도는 둘을 비교하며, 답변이 고른 분포만큼 또는 그보다 더 퍼져 있으면 0을 하한으로 둡니다.
이웃 레벨에 실린 확률은 더 먼 레벨의 같은 확률보다 신뢰도를 덜 낮춥니다. 레벨이 세 개일 때, $(0, 0.5, 0.5)$의 신뢰도는 0.25입니다. 모델이 인접한 두 레벨 사이에서 갈팡질팡하기 때문입니다. $(0.5, 0, 0.5)$의 신뢰도는 0입니다. 양 끝 사이에서 갈팡질팡하기 때문입니다. Choice 공식이라면 두 분포 모두 0.25가 됩니다.
5단계 점수 질문
단계 사이의 거리가 신뢰도를 어떻게 바꾸는지 보기
신뢰도
확률
슬라이더를 움직이면 해당 단계의 확률이 바뀌고, 나머지는 비율을 유지한 채 자동으로 조정됩니다. 합계는 항상 100%입니다.
- 점수
- 2.00
- 같은 확률에 Choice 공식을 적용한 값
- 0.88
이 데모가 신뢰도를 계산하는 방법
이 데모는 Score 공식을 씁니다. 확률로 가중한, 답과 최빈 단계 사이의 단계 수 평균을 구합니다. 그것을 1.2(5단계 균등 분포에서 가운데 단계부터 잰 같은 평균)으로 나누고, 1에서 빼되 0에서 멈춥니다. 최빈 단계 옆의 확률은 멀리 있는 확률보다 신뢰도를 덜 떨어뜨립니다. Choice 공식은 이를 고려하지 않습니다.
def score_confidence(probabilities: list[float]) -> float:
n = len(probabilities)
m = probabilities.index(max(probabilities))
spread = sum(p * abs(i - m) for i, p in enumerate(probabilities))
even_spread = sum(abs(i - (n - 1) / 2) for i in range(n)) / n
return max(0.0, 1 - spread / even_spread)
levels = sorted(answer.probabilities)
score_confidence([answer.probabilities[level] for level in levels])
Score 응답 예시의 bug_severity 답변은 확률이 $(0, 0.57, 0.43)$입니다. 가장 가능성 높은 레벨은 1이고, 거리는 $0.43$이며, 레벨 세 개의 $\text{MAD}_{\text{unif}}$는 $\frac{2}{3}$이므로 신뢰도는 $1 - 0.43 / \frac{2}{3} \approx 0.35$입니다.