결함은 81.4% 유발했는데 검출은 0.7%: AI 테스트의 오라클 간극
1. 실행한 코드와 맞다고 판정한 동작은 다르다
AI가 코드를 만들고 테스트까지 작성하면 초록색 결과가 금방 나타난다. 그런데 테스트가 구현의 현재 동작을 그대로 정답으로 받아들였다면 어떨까. 잘못된 계산을 실행했는데도 단언문이 그 값을 기대하고 있으면 테스트는 통과한다. 이때 부족한 것은 실행 횟수만이 아니다. 무엇이 올바른 결과인지 판정하는 테스트 오라클, 즉 기대값과 단언의 근거가 빠져 있다.
2026년 9월 8일 처음 제출된 Asma Hamidi, Michael Konstantinou, Renzo Degiovanni, Mike Papadakis의 논문은 이 간극을 분리해 조사했다. 제목의 두 숫자는 논문 표 IV에서 GPT-5-mini가 만든 결함 구현을 BigCodeBench에서 평가하고, 분기 커버리지 기준으로 테스트를 골랐을 때의 평균이다. 결함 유발률은 81.4%, 실제 검출률은 0.7%였다. 모든 AI 코드의 오류율도, GPT-5-mini 전체 정확도도 아니다. 선택된 결함 구현과 해당 테스트 선택 절차에 한정된 결과다.
논문의 질문은 “테스트가 몇 줄을 실행했는가”에서 한 걸음 더 나아간다. 같은 입력으로 기준 구현과 다른 출력을 만들었는가, 그리고 생성된 단언문이 그 차이를 실제 실패로 잡았는가를 따로 센다. 둘을 합쳐 성공률 하나로 보고하면, 유용한 입력은 이미 찾았지만 잘못된 기대값 때문에 놓친 결함이 보이지 않는다. 이 연구는 새 모델의 순위보다 테스트의 두 역할을 분리해 관측하는 방법으로 읽는 편이 유익하다.
2. 6,066개는 전체 코드가 아니라 어려운 결함을 골라낸 집합이다
연구진은 파이썬 벤치마크 네 개와 모델 다섯 개를 사용했다. HumanEval 계열, MBPP, BigCodeBench, NaturalCodeBench의 과제 설명에 원래 프롬프트와 불충분하게 기술된 변형을 적용하고, 모델별로 열 번씩 구현을 생성했다. 논문이 보고한 전체 구현은 233,300개다. 기준 구현과 동일 입력에서 다른 결과를 내는지 비교해 73,785개를 결함 구현으로 분류했다. 기준 구현이 옳다는 가정이 이 판단의 출발점이다.
여기서 곧바로 모델의 일반 오류율을 계산해 배포 판단에 쓰면 안 된다. 결함을 다양하게 수집하려고 의도적으로 불충분한 설명을 포함했고, 다음 단계에서는 쉽게 발견되는 결함까지 제외했기 때문이다. 논문의 난이도는 증강 테스트 가운데 결함을 유발하는 비율의 여집합이다. 본문은 난이도 0.75 미만을 제외한 뒤, 같은 과제에 여러 후보가 있으면 더 어려운 구현을 남기는 방식으로 최종 6,066개를 골랐다고 설명한다. 다만 수집 도식은 엄격한 부등호를 사용하므로 정확히 0.75인 사례의 처리까지 구현으로 확인한 것은 아니다. 표 II는 이 수를 모델과 벤치마크별로 나누어 제시한다. 서로 독립적인 과제 6,066개라는 뜻이 아니라 선택된 결함 구현 6,066개다.
최종 집합에는 BigCodeBench 구현 3,925개가 포함된다. 작은 함수 위주의 과제와 라이브러리 활용 과제가 함께 있지만, 실제 서비스 전체나 장기간 운영 장애를 대표하는 표본은 아니다. 쉬운 결함을 제거한 집합의 낮은 검출률을 “일반 테스트는 모든 버그의 거의 전부를 놓친다”로 바꾸면 선택 조건을 지워 버린다. 반대로 어려운 결함만 남겼으니 아무 의미가 없다는 결론도 성급하다. 자동 생성 테스트가 통과한 뒤 남을 수 있는 위험을 살펴보려는 통제 실험으로 이해해야 한다.
논문 보고 구현 수. 의도적으로 어려운 결함을 골랐으며 전체 코드의 일반 오류율이 아니다. 출처: arxiv.org/html/2609.09315v1.
3. 같은 기준을 채워도 유발과 검출 사이에 큰 간격이 남았다
실험은 테스트 생성 자체와 테스트 선택을 구분한다. 연구진은 커버리지 피드백 없이 생성한 테스트 풀에서 문장 커버리지, 분기 커버리지, 변이 테스트 점수를 각각 높이는 테스트를 무작위로 선택했다. 어떤 테스트가 목표 점수를 높이면 남기고, 아니면 버린다. 선택된 묶음의 점수가 원래 풀과 같아지면 멈춘다. 모든 코드의 절대 커버리지 100%를 보장하는 절차가 아니라, 주어진 풀의 도달 수준을 맞추는 절차다.
이 선택을 결함별·기준별로 100번 반복했다. 표 IV의 숫자는 그 반복을 반영한 평균이므로 반올림된 비율에 결함 개수를 곱해 정확한 적발 건수를 복원할 수는 없다. 제목에 사용한 BigCodeBench·GPT-5-mini 행의 대상 결함 구현은 표 II에서 845개다. 여기서 GPT-5-mini는 결함 구현을 생성한 모델 구분이며, 해당 행을 그 모델이 코드와 테스트를 모두 작성한 종단 간 성적이라고 확대하지 않는다.
같은 행을 세 기준으로 나란히 보면 차이가 더 명확하다. 변이 기준은 유발 77.4%와 검출 1.0%, 분기 기준은 유발 81.4%와 검출 0.7%, 문장 기준은 유발 79.3%와 검출 0.8%다. 변이 점수가 이 사례에서 검출률은 조금 높지만, 분기 기준의 유발률이 더 높다. 어느 기준이 모든 상황에서 우세하다는 결론은 나오지 않는다. 가장 눈에 띄는 차이는 기준끼리의 순위보다 같은 기준 안에서 출력 차이를 만드는 능력과 그 차이를 실패로 판정하는 능력 사이에 있다.
동일 행의 평균 유발률과 검출률. 결함 생성 모델별 845개 구현, 기준별 100회 반복이며 반올림된 비율이다. 출처: arxiv.org/html/2609.09315v1.
숫자를 인용할 때 본문 요약도 그대로 믿지 않았다. 결과 설명에는 유발률을 25~78%라고 요약한 부분이 있지만, 표 IV에는 그 밖의 값이 있다. 표 전체의 유발률 범위는 5.6~81.4%, 검출률은 0~11%다. 이 글은 HTML과 PDF의 열 배치를 대조한 특정 행을 사용했다. 범위는 서로 다른 모델·벤치마크·선택 기준의 셀을 훑은 값이지, 신뢰구간이나 사용자 환경의 예상 구간이 아니다. 원시 실행 기록을 재채점하거나 모델을 다시 실행한 결과로 소개하지도 않는다.
4. 작은 배송비 예제에서 단언문의 차이를 직접 확인했다
이 메커니즘은 간단한 예제로도 구별할 수 있다. 다음은 논문의 실험 데이터가 아니라 설명을 위해 직접 만든 의도적 오류다. 업무 규칙은 “주문 합계가 100 이상이면 배송비 0, 아니면 5”인데, 구현을 실수로 total > 100으로 작성했다고 하자. 입력 99, 100, 101을 넣으면 현재 구현의 출력은 5, 5, 0이다. 그 출력 그대로 기대값을 적으면 세 테스트가 모두 통과한다.
같은 입력을 그대로 두고 규칙에서 기대값을 도출하면 5, 0, 0이 된다. 이제 합계 100에서만 실패가 드러난다. 별도 설명용 파이썬 함수로 이 순서를 실행했고, coverage.py 7.16.0에서 함수의 분기 두 개가 모두 실행됐음을 확인했다. 그런데 구현을 따라 적은 단언문은 모두 통과했고, 명세를 따라 적은 단언문은 경계 입력 하나에서 실제값 5와 기대값 0의 차이를 잡았다. 분기 실행 여부가 같아도 검출 결과는 달라질 수 있다.
이 예제는 논문의 어려운 결함 분포를 재현한 것이 아니며, 특정 모델이 이런 테스트를 만들었다는 관측도 아니다. 커버리지와 오라클이 별개의 관측 대상이라는 점만 확인하는 작은 기능 실험이다. 테스트를 더 추가하는 일이 언제나 무의미하다는 의미도 없다. 아직 잘못된 동작을 유발하는 입력을 찾지 못했다면 입력 탐색이 필요하다. 이미 유발한 오류를 통과시키고 있다면 기대값의 근거를 먼저 검토해야 한다.
논문 메커니즘을 설명하는 직접 작성·실행한 예제. 의도적인 > 오류이며 특정 모델의 실험 성적이 아니다. 출처: arxiv.org/html/2609.09315v1.
5. 코드를 가리는 처방보다 정답 근거를 분리하는 절차가 먼저다
연구진은 기존 구현을 프롬프트에서 빼고 자연어 명세와 결함을 유발하는 입력을 주어 단언문을 다시 생성하는 실험도 했다. 잘못된 구현이 기대값을 끌고 가는 문제를 줄이려는 시도다. 다만 이것은 실무에서 아무 입력이나 넣으면 얻는 개선율이 아니다. 연구에서는 기준 구현을 이용해 이미 결함 유발 입력을 골랐으며, 런타임 오류가 있으면 최대 다섯 번의 수정 과정도 거쳤다.
그 결과를 간단한 성공 처방으로 압축하기도 어렵다. 표 VI에는 개선뿐 아니라 악화된 셀도 있고, 분기·문장 기준의 검출률은 그대로인 것으로 보고된다. 본문은 입력이 같다는 점을 설명으로 들지만, 입력이 같더라도 단언을 바꾸면 검출률은 달라질 수 있으므로 그 이유만으로 결과를 일반화할 수는 없다. 이 글은 “코드를 숨기면 몇 퍼센트 좋아진다”를 권장 효과로 채택하지 않는다. 새 연구의 공개 원시 결과와 구현을 연결할 수 있는 주소도 확인하지 못해, 이 부분의 재계산이나 실행 경로를 독립적으로 확인하지 못했다.
대신 팀에서 적용할 수 있는 절차를 구분해 제안한다. 첫째, 테스트를 생성하기 전에 업무 규칙과 중요한 경계 조건을 구현과 별도로 남긴다. 둘째, 입력을 찾는 작업과 기대값을 작성하는 작업을 구별한다. 셋째, 실패한 테스트가 나오면 코드를 고치기 전에 기대값이 명세에서 나온 것인지 확인한다. 넷째, 회귀 방지를 위해 현재 동작을 기록한 테스트와 요구사항 충족을 확인하는 테스트를 같은 것으로 취급하지 않는다. 이는 논문의 실험 효과를 그대로 보장하는 정책이 아니라, 관측된 간극에서 도출한 운영 제안이다.
기준 구현이 없는 서비스에서는 승인된 예시, 명시적 불변식, 독립 계산, 도메인 검토처럼 정답 근거를 별도로 마련할 수 있다. 어느 방법이 적절한지는 업무 규칙에 달려 있다. 또 다른 모델에게 “맞나요?”라고 묻는 것만으로 독립된 오라클을 확보했다고 볼 수는 없다. 무엇을 정답으로 삼았고 그 판단을 누가 또는 어떤 절차가 검증했는지 기록해야 한다.
6. 초록색 배지는 보증서가 아니라 서로 다른 신호의 묶음이다
이 연구의 한계는 분명하다. 파이썬 함수와 선택된 벤치마크에 집중했고, 어려운 결함을 선별했으며, 기준 구현의 정확성에 의존한다. 비용 비교도 주로 분석하는 테스트 수를 노력의 대리 지표로 삼는다. 따라서 변이 테스트의 실제 서버 비용이나 사람의 검토 시간을 이 표에서 직접 산출할 수 없다. 모델과 프롬프트가 달라지면 결과 역시 달라질 수 있다. 논문은 프리프린트 v1이며, 이 글에서 확인한 범위는 공개 HTML·PDF·표와 별도의 설명용 예제다.
그럼에도 실무적인 질문은 남는다. 코드가 실행됐는가, 다른 동작이 나타났는가, 그 차이가 실패로 잡혔는가를 하나의 “테스트 통과”로 묶고 있지 않은가. 커버리지는 유용한 실행 관측이다. 하지만 기대값의 출처까지 대신 보증하지는 않는다. AI가 만든 테스트를 검토할 때 더 긴 테스트 목록을 먼저 요구하기보다, 중요한 단언 몇 개가 구현을 복사한 답인지, 요구사항에서 나온 답인지 확인하는 데서 시작해 보자.



댓글
댓글 쓰기