AI Agent Fast Learning · 실행 결과 읽기
성공률이 같아도 실패가 연달아 발생하는 정도는 다를 수 있다. 전체 성공률과 함께 실행 순서대로 놓은 결과, 최장 연속 실패 횟수, 실패 묶음 수를 확인하자. 다만 연속 실패가 길다는 사실만으로 공통 장애 원인이나 통계적 의존성이 입증되지는 않는다.
“둘 다 성공률이 75%인데, 왜 한쪽은 한동안 아무 일도 못 하는 것처럼 보일까?” 성공과 실패의 총개수에는 순서 정보가 없다. 이번 글은 실패를 집계에서 빼지 않는 데서 한 걸음 더 나아가, 실패가 어디에 모였는지 읽는 방법을 다룬다.

같은 20회, 다른 실패 배열
완전히 관측이 끝난 순차 실행 20회를 가정한다. 한 실행이 끝난 뒤 다음 실행을 시작하며, 성공 판정 기준도 같다. S는 검증된 성공, F는 그 실행이 실패로 끝났다는 뜻이다. 도중에 오류가 났지만 복구해 성공한 실행을 F로 세지는 않는다. A와 B는 제품 이름이 아닌 가상 배열이다.
A: SSSF SSSF SSSF SSSF SSSFB: SSSSS SSSSS SSSSS FFFFF
두 배열 모두 성공 15회와 실패 5회로 성공률은 75%다. A는 실패 사이에 성공이 있고, B는 마지막 다섯 실행이 모두 실패다. 순서만 다르지만 연속해서 작업을 넘기는 사람이 겪을 수 있는 중단 양상은 달라진다. 여기에는 실제 사용자 관측이나 AI 성능 측정 결과가 들어 있지 않다.
| 집계 항목 | A | B |
|---|---|---|
| 전체 성공률 | 75% | 75% |
| 최장 연속 실패 | 1회 | 5회 |
| 실패 묶음 수 | 5개 | 1개 |
| 성공·실패 전체 런 수 | 10개 | 2개 |
실패 묶음과 전체 런을 구별한다
여기서 실패 묶음은 F가 끊기지 않고 이어진 부분이다. F 하나도 묶음 하나다. 최장 연속 실패는 그 묶음 중 가장 긴 길이이며 단위는 실행 횟수다. 성공과 실패를 모두 포함해 같은 기호가 이어진 묶음을 세면 전체 런(run) 수가 된다. 예를 들어 SSFFS는 실패 묶음 1개, 전체 런 3개다.
NIST의 런 검정 설명도 두 종류로 구분한 자료에서 연속되는 같은 종류의 묶음을 다룬다. 이 글은 그 묶음 개념만 활용한다. 런 검정의 유의확률을 계산하거나, 위의 20개 배열로 무작위성 여부를 판정하지 않는다. NIST: Runs Test for Detecting Non-randomness, 확인 2026-10-23.
집계하기 전에 순서와 경계를 정한다
첫째, 무엇을 한 실행으로 셀지 정한다. 사용자 요청 한 건인지, 재시도 하나인지에 따라 같은 기록에서도 연속 실패가 달라진다. 한 요청에서 나온 다섯 재시도를 서로 다른 사용자 요청 다섯 건처럼 해석하지 않는다. Anthropic의 평가 설명은 과제(task), 그에 대한 시도(trial), 최종 환경 상태인 결과(outcome)를 구별한다. 이 구별을 로그의 집계 단위에도 유지하자는 것이 여기서의 적용 제안이다. Anthropic: Demystifying evals for AI agents, 확인 2026-10-23.
둘째, 순서 기준을 고정한다. 이 예제는 겹치지 않는 순차 실행이라 시작 순서와 종료 순서가 같다. 동시 실행에서는 둘이 다를 수 있다. 사용자별 요청 순서가 필요한지, 서비스 전체의 완료 순서가 필요한지 먼저 정하고 동률 처리 규칙도 기록한다. 결과가 더 좋아 보이는 순서를 나중에 고르면 안 된다.
셋째, 관측 경계를 남긴다. 아직 진행 중이거나 결과가 없는 실행을 삭제해 양쪽 실패를 이어 붙이지 않는다. F ? F는 확인된 세 번 연속 실패가 아니다. 아래 코드는 미확인 기호를 만나면 계산을 거부한다. 운영에서는 상태를 별도로 보존하고, 완결된 구간을 나누어 집계할 수 있다. 구간을 나눴다면 전체 관측 건수와 제외·미완결 건수도 따로 보고한다.
넷째, 다른 사용자·세션·버전·관측일을 이어 붙일지 미리 정한다. 서로 다른 세션의 마지막 실패와 첫 실패를 붙이면 그 누구도 경험하지 않은 긴 실패 묶음이 생길 수 있다. 반대로 유리한 구간만 잘라내면 실제로 이어진 실패를 숨긴다. 경계는 결과를 보기 전에 정하고 보존한다.
복사해 실행하는 최소 예제
아래 코드는 외부 API나 패키지 없이 가상 문자열만 계산한다. 파일을 check_streaks.py로 저장한 뒤 python check_streaks.py로 실행한다. Python 3.12.14에서 2026-10-23에 직접 실행했고, 두 배열의 결과와 전부 성공·전부 실패·빈 입력·미확인 상태에 대한 검사를 통과했다. 모델이나 에이전트 SDK를 실행한 시험은 아니다.
from itertools import groupby
def summarize(sequence):
if not sequence or any(x not in {'S', 'F'} for x in sequence):
raise ValueError('Use a nonempty, fully observed S/F sequence')
groups = [(key, len(list(items))) for key, items in groupby(sequence)]
failures = [size for key, size in groups if key == 'F']
return {
'n': len(sequence),
'success_rate': sequence.count('S') / len(sequence),
'failure_blocks': len(failures),
'max_failure_streak': max(failures, default=0),
'all_runs': len(groups),
}
examples = {'A': 'SSSF' * 5, 'B': 'S' * 15 + 'F' * 5}
for name, sequence in examples.items():
print(name, summarize(sequence))
assert summarize(examples['A']) == dict(n=20, success_rate=.75, failure_blocks=5, max_failure_streak=1, all_runs=10)
assert summarize(examples['B']) == dict(n=20, success_rate=.75, failure_blocks=1, max_failure_streak=5, all_runs=2)
assert summarize('SSS')['max_failure_streak'] == 0
assert summarize('FFF')['max_failure_streak'] == 3
for invalid in ['', 'SF?F', 'SFPF']:
try:
summarize(invalid)
except ValueError:
pass
else:
raise AssertionError('Invalid sequence was accepted')
print('Assertions passed')
출력에서 A의 max_failure_streak는 1, B는 5다. failure_blocks는 각각 5와 1이고, all_runs는 10과 2다. 이 값들은 두 배열의 구조를 설명할 뿐 어느 제품의 신뢰성을 추정한 수치가 아니다.
긴 실패 묶음을 찾았다면 무엇을 확인할까
권장 진단 순서는 해당 구간의 실행 ID와 시각을 확인하고, 입력 유형·버전·도구 응답 상태가 함께 달라졌는지 비교한 뒤, 허가된 시험 환경에서 후보 원인을 분리하는 것이다. 예를 들어 어려운 과제가 뒤쪽에 몰렸을 수도 있고 같은 외부 도구의 오류가 이어졌을 수도 있다. 둘 다 가능한 가설이지 배열만 보고 확정할 수 있는 원인은 아니다.
최장 연속 실패 5회를 “5분 장애”로 바꾸어 읽지 않는다. 각 실행에 걸린 시간과 실행 사이 간격이 없기 때문이다. 장애 지속 시간이나 영향을 받은 사용자 수가 목적이라면 별도의 시각 기록과 사용자별 집계가 필요하다. 원문 요청이나 인증값을 복사하는 대신 필요한 식별자와 비식별 요약만 진단 기록에 남긴다.
비교하는 관측 길이도 같아야 해석이 쉽다. 20회에서의 최장 실패와 2만 회에서의 최장 실패를 숫자만으로 순위 매기지 않는다. 성공률, 관측 횟수, 대상 구간을 함께 제시한다. 연속 실패 임계값 하나를 이 예제에서 가져와 자동 중지 규칙으로 쓰는 것도 피한다. 업무 피해, 오탐 비용, 복구 절차에 맞춰 별도로 검증해야 한다.
평가표에 추가할 네 가지
전체 성공률 옆에 ① 집계 단위와 순서 기준 ② 전체·미완결 관측 건수 ③ 최장 연속 실패와 실패 묶음 수 ④ 가장 긴 실패 구간의 시작·끝 실행 ID를 적어 보자. 평균을 바꾸지 않고도 어디를 먼저 조사해야 할지 구체적으로 말할 수 있다. 단, 조사할 구간을 찾았다는 것과 원인을 해결했다는 것은 구별해서 기록한다.
이어 읽기와 확인 범위
종료 실패와 진행 중 상태를 분리해 성공률 읽기
비교 실험의 실행 순서를 미리 설계하기
이 글은 관측된 결과 배열을 읽는 교육용 실습이다. 앞선 실행 순서 설계 글이 비교 실험을 어떻게 배치할지 다뤘다면, 이번 글은 이미 기록된 순서를 보존해 실패 묶음을 계산한다. 공식 자료의 개념 설명, 운영 진단 제안, 가상 배열의 실제 코드 실행을 구분했다. 확인일은 2026-10-23이며 특정 모델·MCP 프로토콜·SDK 버전의 동작을 보증하지 않는다.