AI Agent Fast Learning · 첫 성공까지의 단계 수
실패 뒤 다음 성공확률을 늘 40%로 가정하면, 첫 성공까지 평균 2.5단계를 기다린다. 하지만 3단계 안에 반드시 성공한다는 뜻은 아니다. 같은 모형에서 3단계 내내 성공하지 못할 확률은 21.6%다. 평균 단계 수, 제한 안에서의 성공확률, 특정 시점의 실패확률은 서로 다른 질문이다.
앞선 글은 현재 실패 상태에서 몇 단계 뒤 실패할 확률을 계산했다. 이번에는 “처음으로 성공을 만나기까지 몇 단계가 필요한가?”를 묻는다. 실제 AI 성능을 측정한 글이 아니라, 동일한 가상 전이표에서 질문을 바꾸면 답이 어떻게 달라지는지 계산하는 수업이다.

한 단계와 첫 성공을 먼저 정의한다
S는 결과를 확인한 성공, F는 종료 실패다. 한 단계는 순서대로 실행한 다음 사용자 요청 한 건이다. 현재 상태 F를 0단계로 놓고, 앞으로 처음 S가 나타나는 단계 번호를 T라고 하자. 다음 요청에서 S가 나오면 T=1이다. 이미 관측한 현재 실패는 T에 더하지 않는다.
| 현재 상태 | 다음 S | 다음 F |
|---|---|---|
| S | 90% | 10% |
| F | 40% | 60% |
이 표는 이전 글과 같다. 현재 상태를 알면 더 오래된 이력이 다음 결과에 추가 정보를 주지 않는 마르코프 성질과, 모든 단계에서 전이확률이 같다는 조건을 가정한다. 첫 S를 만나기 전에는 줄곧 F에 있으므로 이 계산에는 F 행만 필요하다. S를 만난 뒤 다시 실패할 가능성은 첫 도착 시점 T를 바꾸지 않는다.
여기서 다음 요청의 성공은 앞선 실패 요청의 복구를 뜻하지 않는다. 다른 요청을 순서대로 처리하는 모형이다. 동일 요청을 반복 실행해도 같은 확률이 적용된다고 확인한 적이 없으며, 자동 재시도 횟수를 추천하는 예제도 아니다.
“3단계째 성공”과 “3단계 안에 성공”은 다르다
첫 성공이 n단계째 나오려면 그 앞의 n−1단계는 모두 실패하고 마지막에 성공해야 한다. 따라서 P(T=n)=0.6^(n−1)×0.4다. n단계까지 한 번도 성공하지 못하는 사건은 F만 n번 이어지는 것이므로 P(T>n)=0.6^n이다. 지수의 시작점이 서로 다르다.
| 단계 n | 그 단계에서 첫 성공 | n단계 내 성공 없음 | n단계 내 첫 성공 |
|---|---|---|---|
| 1 | 40% | 60% | 40% |
| 2 | 24% | 36% | 64% |
| 3 | 14.4% | 21.6% | 78.4% |
3단계째 첫 성공할 확률 14.4%는 F→F→F→S 경로의 확률이다. 0단계의 현재 F를 제외하면 앞으로 두 번 실패한 뒤 성공한다. 3단계 안에 첫 성공할 확률 78.4%는 40%+24%+14.4%로 계산한다. “3번째”와 “3번 안에”를 같은 말로 쓰면 표의 다른 열을 읽게 된다.
3단계 뒤 실패 30%와 성공 없음 21.6%
이전 글의 표로 3단계 뒤 F일 확률을 구하면 30%다. 여기에는 중간에 S를 거친 뒤 다시 F로 돌아오는 경로도 들어간다. 반면 3단계 안에 S가 한 번도 없을 확률 21.6%에는 F→F→F→F 경로만 들어간다. 따라서 정확히 3단계째 S일 확률은 70%지만, 3단계 안에 S를 한 번이라도 만날 확률은 78.4%다. 출발점과 전이표가 같아도 사건을 다르게 세면 숫자가 달라진다.
“마지막 요청이 실패했는가?”를 보고할 때는 30%에 해당하는 사건을, “그동안 성공을 한 번이라도 만났는가?”를 보고할 때는 78.4%에 해당하는 사건을 계산한다. 후자를 성공률로 부르려면 요청별 성공 비율이 아니라 관측 구간 내 첫 성공 도달 비율이라는 분모와 조건을 함께 적어야 한다.
평균 2.5단계는 보장된 마감이 아니다
이 T는 1부터 세는 기하분포다. 처음 성공할 확률이 매 단계 p=0.4로 유지되므로 E[T]=1/p=2.5다. 실제 T는 1, 2, 3처럼 정수지만, 그 확률가중평균은 소수가 될 수 있다. 2.5를 반올림해 “3번이면 된다”고 쓰지 않는다.
다른 방식으로도 확인할 수 있다. 첫 단계는 반드시 관측한다. 2단계까지 가려면 첫 단계에 실패해야 하므로 확률은 0.6, 3단계까지 가려면 앞의 두 단계에 실패해야 하므로 0.36이다. 제한이 없을 때 평균은 1+0.6+0.36+…=2.5가 된다. 이 급수는 p가 0보다 크고 같은 확률이 계속 유지된다는 조건에 기대고 있다.
이 예제처럼 0<p<1이면, 언젠가 S를 만날 확률은 1이어도 유한한 특정 단계 안의 성공은 보장되지 않는다. p=1이면 다음 1단계에서 반드시 S다. 현실에서 영구 장애가 있거나 요청 유형·정책이 바뀌면 이 결론의 조건부터 어긋난다. p=0이면 처음 S에 도달하지 못하므로 유한한 평균을 계산할 수 없다.
3단계까지만 관측하면 평균은 1.96단계
첫 S를 만나거나 3단계에 도달하면 관측을 멈춘다고 하자. 관측한 단계 수는 min(T,3)이고 평균은 1+0.6+0.36=1.96이다. 이것을 “첫 성공까지 평균 1.96단계”라고 쓰면 틀린다. 21.6%는 성공 없이 제한에 도달했기 때문이다.
| 질문 | 계산 결과 | 해석 주의 |
|---|---|---|
| 제한 없이 첫 S까지 평균 | 2.5단계 | 일정 단계 안 성공 보장 아님 |
| 최대 3단계 관측한 평균 | 1.96단계 | 성공 없이 끝난 관측도 포함 |
| 3단계 안 첫 S 도달 | 78.4% | 개별 요청 성공률과 다름 |
| 3단계까지 S 없음 | 21.6% | 미도달 사례를 제외하지 않음 |
단계당 처리 시간과 비용이 같다는 조건은 넣지 않았다. 1.96단계를 1.96초나 특정 비용으로 바꿀 수 없다. 대기 시간·실행 시간·실패 종류에 따라 소요가 다르면 별도 시간·비용 모형이 필요하다. 성공한 관측만 골라 평균을 내는 것도 여기서 계산한 1.96이나 2.5와 다른 통계다.
분수로 확인하는 복사 코드
아래 내용을 first_success.py로 저장하고 python first_success.py로 실행한다. Python 표준 라이브러리만 사용하고 파일·네트워크·실제 AI 요청을 호출하지 않는다. p는 Fraction, 제한은 양의 정수로 받는다. p=0의 무한 대기를 유한 숫자로 표시하지 않도록 거부한다.
from fractions import Fraction as F
def waiting_summary(p, cap):
"""p: constant F->S probability; cap: positive future-step limit."""
if not isinstance(p, F):
raise TypeError("p must be a Fraction")
if not 0 < p <= 1:
raise ValueError("p must satisfy 0 < p <= 1")
if isinstance(cap, bool) or not isinstance(cap, int) or cap < 1:
raise ValueError("cap must be a positive integer")
q = 1 - p
first_at = [q ** (n - 1) * p for n in range(1, cap + 1)]
not_yet = q ** cap
capped_mean = sum((q ** n for n in range(cap)), F(0))
return first_at, not_yet, 1 / p, capped_mean
if __name__ == "__main__":
first, tail, mean, capped = waiting_summary(F(2, 5), 3)
assert first == [F(2, 5), F(6, 25), F(18, 125)]
assert tail == F(27, 125)
assert sum(first) + tail == 1
assert mean == F(5, 2)
assert capped == F(49, 25)
assert capped == sum((n * v for n, v in enumerate(first, 1)), F(0)) + 3 * tail
# Contrast: marginal probability of F after three steps, allowing S->F.
f = F(1)
for _ in range(3):
f = F(1, 10) * (1 - f) + F(3, 5) * f
assert f == F(3, 10) and f != tail
assert waiting_summary(F(1), 3) == ([F(1), F(0), F(0)], F(0), F(1), F(1))
rejected = 0
for p, cap in [(F(0), 3), (F(-1, 5), 3), (F(6, 5), 3),
(F(2, 5), 0), (F(2, 5), True), (0.4, 3)]:
try:
waiting_summary(p, cap)
except (TypeError, ValueError):
rejected += 1
assert rejected == 6
print("first success at steps 1..3:", first)
print("no success within 3 steps:", tail)
print("uncapped mean steps:", mean)
print("mean steps observed with cap 3:", capped)
print("F at step 3 (different event):", f)
print("checks passed")
2026-10-25 Python 3.12.14에서 위 코드를 실제 실행했다. 첫 성공 확률 2/5·6/25·18/125, 미도달 27/125, 제한 없는 평균 5/2, 제한 평균 49/25, 3단계 뒤 F 확률 3/10을 확인했다. p=1 경계값과 잘못된 입력 6개에 대한 검사도 통과했다. 이는 합성 모형의 산술·입력 검증이며 AI 서비스 재현 시험이나 정책 효과 검증이 아니다.
실제 기록에 적용하기 전에 적을 네 가지
시작과 끝: 현재 실패부터 세는지 다음 요청부터 세는지, 첫 성공 뒤 관측을 멈추는지 정한다. 성공은 응답 수신이 아니라 필요한 결과가 확인된 상태로 정의한다.
동일한 조건: 오류 종류, 요청 난이도, 모델·도구 버전, 시간대에 따라 F→S 비율이 달라지는지 본다. 오래 실패할수록 다음 성공확률이 변한다면 일정한 p의 기하분포로 묶기 어렵다. 작은 관측에서 얻은 비율을 확정 확률로 취급하지 않는다.
미도달 사례: 관측 제한과 제한에 도달한 수를 남긴다. 성공하지 못한 기록을 빼고 “평균 회복이 빨라졌다”고 말하지 않는다. 이 글의 코드는 실측 추정, 불확실성 구간, 중도 종료 자료 분석을 하지 않는다.
실행 안전: 관측 모형을 재시도 정책으로 곧장 옮기지 않는다. 쓰기 요청은 실패 응답 뒤에도 실제 처리가 끝났을 수 있다. 처리 상태와 중복 방지 조건을 확인하지 않은 채 숫자만 보고 반복하면, 처음 실패를 해결하는 대신 중복 변경을 만들 수 있다.
복사 양식: 출발 상태 / 단계 단위 / 성공 판정 / 첫 성공 뒤 종료 여부 / 관측 상한 / 미도달 수 / F→S 비율의 자료·분모 / 일정 확률 가정 / 시간·비용 별도 측정 / 중복 실행 방지 조건. 고객 원문·인증값 대신 비식별 상태와 집계값을 기록한다.
출처와 적용 범위
ProbabilityCourse, Special Discrete Distributions의 1부터 세는 기하분포 정의와 Expectation의 기하분포 평균을 대조했다. 확인일은 2026-10-25다. 교재의 일반 공식과 이 글에서 정한 가상 전이표·관측 제한 예제는 구분한다. 전체 S·F 연쇄를 독립 시행으로 가정한 것이 아니라, 첫 S 이전에 F에서 빠져나올 조건부 확률이 일정하다는 조건을 사용했다.
다음 성공을 기다리는 길이를 보고하려면 평균 하나로 끝내지 않는다. 어떤 단계에서 출발해 무엇을 성공으로 세었는지, 어디서 관측을 멈췄고 그때까지 성공하지 못한 비중은 얼마인지를 함께 적는다.
이어 읽기
장기 실패율과 현재 상태: 정상분포가 답하지 않는 질문
전이 횟수와 조건부 비율: 관측 자료에서 표 만들기
같은 성공률에서 연속 실패 길이가 달라지는 이유