본문 바로가기
성공지식백과 로고성공지식백과

AI가 같은 오류를 계속 고칠 때: 재현·로그·원인을 나누는 법

오류 화면만 보여 주며 수정을 반복하면 코드와 가설이 함께 바뀌어 원인을 놓치기 쉽습니다. 실패 입력과 관측 사실을 고정하고, 원인이 갈라지는 지점에서 시험하는 과정을 설명합니다.

바이브 코딩디버깅오류 재현가설 검증
글 정성준 7분 읽기
공유:

“삭제한 메모가 다시 나타납니다”라는 증상만으로는 AI가 어느 코드를 고칠지 정하기 어렵습니다. 화면 상태만 바뀌었는지, 서버가 요청을 거부했는지, 새로 읽은 데이터의 경로가 다른지부터 갈립니다. 구글 SRE의 문제 해결 절차는 관찰과 시스템 구조를 바탕으로 원인 가설을 세우고, 증거와 통제한 시험으로 가설을 확인하거나 반박하는 과정을 설명합니다.

디버깅 요청도 같은 구조로 바꿀 수 있습니다. 코드를 더 많이 고치기 전에 같은 실패를 다시 만들 수 있는 조건과, 아직 모르는 사실을 분리하면 다음 관측을 정할 수 있습니다.

실패 입력과 기대 결과를 한 보고서에 고정하기

Mozilla의 버그 작성 지침은 정확한 재현 단계와 기대 결과, 실제 결과를 적고 관측한 사실과 추측을 구분하도록 합니다. 브라우저 버그 보고를 위한 지침이지만, 문제를 전달하는 이 구조는 AI에게 앱 수정을 맡길 때도 쓸 수 있습니다. “작동하지 않는다”보다 특정 입력과 결과의 차이를 보여 주는 보고서가 조사 범위를 좁힙니다.

다음은 가상의 메모 앱에서 영구 삭제 기능을 조사하기 위한 보고서 예시입니다. 테스트 계정 A와 메모 N-17은 설명용 식별자입니다. 삭제 후 새로고침하면 메모가 돌아온다는 증상을 가정했으며, 네트워크 요청과 저장 상태는 아직 관측하지 않은 것으로 남깁니다.

항목기록 예시
조사 대상자신의 메모를 영구 삭제하는 기능
기대하는 계약삭제가 확정된 메모는 같은 계정으로 목록과 상세를 다시 읽어도 보이지 않는다
실행 환경실제 작업 커밋, 실행 명령, 브라우저·런타임 버전, 연결한 테스트 환경을 기록한다
초기 데이터테스트 계정 A가 소유한 메모 N-17 한 건이 있고 목록에서 보인다
재현 단계A로 로그인한다; N-17을 한 번 삭제한다; 목록에서 사라진 것을 본다; 같은 계정으로 새로고침한다
가정한 실제 증상새로고침한 목록에 N-17이 다시 나타난다
아직 모르는 사실삭제 HTTP 요청 발생 여부, 서버 응답, 실제 저장 데이터, 새로고침의 읽기 경로
반복 여부직접 시험한 횟수와 발생 횟수를 기록한다; 이 예시에서는 미실행이다
비교할 기준마지막 정상 동작이 확인된 커밋과 동일 조건의 실행 기록을 찾는다

재현 단계에서 불필요한 클릭과 데이터는 줄이되 실패를 만드는 조건은 남깁니다. 로그인 상태나 다른 탭의 동작을 없앴더니 실패가 사라진다면 그 조건도 원인 후보입니다. 최소 사례는 같은 실패를 유지하면서 관련 없는 요소를 덜어 낸 사례로 잡습니다.

기대 결과는 기능의 계약에서 가져옵니다. 삭제가 검토 대기로 접수되는 앱과 즉시 영구 삭제되는 앱은 완료 조건이 다릅니다. 성공 알림만 보고 기대를 정하면 원래 설계와 다른 동작을 버그로 판단할 수 있습니다.

증상, 관측 사실, 원인 가설을 다른 칸에 놓기

증상은 새로고침 뒤 메모가 보인다는 현상입니다. 관측 사실은 해당 실행에서 실제로 확인한 요청·응답·데이터입니다. “캐시가 문제다”는 관측한 증상을 설명하기 위한 가설이며, 로그 제목에 쓸 때도 확인 전에는 가설로 표시합니다.

가상 증상에는 여러 설명이 가능합니다. 삭제 버튼이 화면에서 항목만 지웠을 수도 있고, 삭제 요청이 거부됐는데 성공처럼 처리했을 수도 있습니다. 저장소에서는 지워졌지만 읽기 경로가 오래된 복사본을 반환했을 가능성도 남아 있습니다. 증상이 같다는 이유로 하나의 원인과 수정 방법을 먼저 고정하면 나머지 경로를 놓칩니다.

AI가 제안한 원인을 기록할 때는 관측과의 연결을 요구합니다. 어떤 사실을 설명하는지, 참이라면 어느 지점에서 어떤 값이 보여야 하는지, 어떤 결과가 나오면 그 가설을 버릴지를 함께 적습니다. 가설마다 다른 예상 결과가 있으면 다음 시험에서 어느 설명이 관측과 맞는지 비교할 수 있습니다.

이미 실패한 가설도 남깁니다. 같은 입력에서 요청이 전송됐다고 확인했다면 “버튼이 요청을 보내지 않는다”는 설명은 그 실행의 원인에서 제외합니다. 다음 AI 세션에 실패 이력을 전달하면 이미 확인한 조건을 다시 추측하는 일을 줄일 수 있습니다.

로그는 가설이 갈라지는 지점에 추가하기

구글 SRE의 가설 검증 설명은 관측 상태와 예상 상태를 비교하거나 시스템을 통제해 바꾸는 방식으로 가설을 시험합니다. 모든 경로에 로그를 늘리는 작업에 앞서, 서로 다른 원인이 다른 결과를 만들 지점을 고릅니다.

메모 삭제의 경우 브라우저 요청, 서버의 처리 결과, 저장소 상태, 다음 읽기 경로를 이어 보면 세 가설을 구분할 수 있습니다. 아래 표는 조사 계획이며 각 행의 결과는 아직 측정하지 않았습니다.

원인 가설관측할 지점가설을 지지하는 예상 증거가설에 맞지 않는 예상 증거
화면에서만 지우고 삭제 요청을 보내지 않는다클릭 처리와 브라우저 네트워크 기록항목은 사라지지만 해당 삭제 요청이 발생하지 않는다같은 실행의 삭제 요청이 서버에 도착했다
서버가 거부했는데 화면은 성공으로 처리한다요청 식별자가 같은 서버 응답과 클라이언트 분기서버가 실패를 반환했고 화면은 그 실패를 무시했다서버가 삭제 대상과 적용 결과를 확인했고 화면도 그 결과를 처리했다
삭제 뒤 읽기 경로가 이전 데이터를 보여 준다삭제 결과, 판정 기준 저장소의 상태, 새로고침 조회 경로저장 상태에는 대상이 없는데 조회 응답에 같은 대상이 포함된다확인한 저장 상태에도 대상이 그대로 남아 있다

실제 로그에는 시각과 시간대, 요청을 연결할 식별자, 대상 테스트 데이터, 실행 환경을 남깁니다. delete_start, delete_result, list_result처럼 단계 이름을 구분하면 같은 요청의 전후를 이어 볼 수 있습니다. 서로 다른 계정이나 다른 실행의 로그를 붙이면 존재하지 않는 흐름을 만들 수 있어 연결 기준을 함께 기록합니다.

응답 상태 코드 하나만으로 저장 결과를 확정하지 않습니다. 애플리케이션이 반환한 삭제 대상과 처리 결과, 테스트 환경에서 다시 읽은 상태를 함께 대조합니다. 인증 토큰이나 실제 개인 데이터 대신 가짜 자료의 식별자와 필요한 필드만 남겨도 이 경로를 조사할 수 있습니다.

판정 기준으로 삼을 저장소도 지정합니다. 테스트 서비스의 실제 저장소를 조회한 것인지, 서버 캐시를 거친 응답을 다시 본 것인지가 다릅니다. 모든 관측이 같은 오래된 읽기 경로를 거치면 삭제와 조회 사이의 차이를 구분하기 어렵습니다.

한 가설을 시험한 뒤 같은 입력으로 다시 비교하기

첫 시험은 원인을 구분하는 데 필요한 관측만 추가할 수 있습니다. 관측 전에 캐시, 요청 형식, 상태 관리, 권한 설정을 한꺼번에 바꾸면 오류가 사라져도 어느 변경이 영향을 줬는지 알기 어렵습니다. 검증할 가설 하나와 그 가설을 가를 변경·관측을 한 묶음으로 정합니다.

가상 사례에서 “실패 응답을 성공으로 처리한다”를 확인했다면 실패 응답을 받았을 때의 화면 처리부터 고칩니다. 이어 같은 재현 입력에서 실패가 표시되고 항목 상태가 어떻게 남는지 비교합니다. 요청이 거부되는 별도 원인이 있다면 그 원인을 또 다른 과제로 나눕니다. 오류 표시를 바로잡는 일과 삭제 요청이 성공하게 만드는 일은 검증할 결과가 다릅니다.

다음은 가설 검증 기록 양식입니다. 실제 결과가 없는 칸을 예상으로 채워 넣지 않고 미실행·확인 못 함을 그대로 남깁니다.

기록할 항목적을 내용
시험할 가설어떤 원인이 관측한 증상을 만든다고 보는지 한 문장으로 적는다
근거와 반대 근거실행 기록의 위치, 지지한 사실, 맞지 않는 사실을 각각 연결한다
바꿀 조건이번에 추가할 로그나 수정할 동작과 그대로 둘 조건을 적는다
재현 입력계정·테스트 데이터·실행 순서·환경이 고정된 보고서를 연결한다
예상 결과가설이 참일 때와 맞지 않을 때 관측할 차이를 미리 적는다
실제 결과실행 시각과 로그를 연결한다; 미실행이면 미실행으로 둔다
다음 판단지지됨·반박됨·확인 부족을 기록하고 다음 관측 또는 변경을 정한다

원인을 확인한 뒤에는 수정 전 실패를 드러내고 수정 뒤 기대 결과를 확인하는 검사를 남깁니다. 삭제의 성공 경로와 거부 경로처럼 이번 수정이 영향을 주는 조건을 함께 비교합니다. 코드를 바꾼 AI가 “해결했습니다”라고 말한 것과 실제 재현 절차가 통과한 결과를 구분합니다.

재현되지 않거나 회귀 시점이 모호할 때

간헐적으로만 실패하면 재현 성공 여부와 함께 시도 횟수, 발생 횟수, 계정·데이터·시간 순서를 남깁니다. 새로고침 간격, 동시 요청, 탭 수를 바꿀 때는 바꾼 조건을 표시합니다. 재현되지 않은 한 번을 해결로 기록하면 다음 수정과 비교할 기준이 사라집니다.

이전 버전에서는 되고 이후 버전부터 실패한다면 변경 이력이 조사 범위가 됩니다. Git의 git bisect 문서는 정상 커밋과 문제 커밋을 기준으로 중간 커밋을 검사하며 문제를 도입한 변경을 좁히는 이진 탐색을 설명합니다. 각 커밋에서 같은 재현 기준으로 정상·문제를 판정할 수 있을 때 쓸 수 있습니다.

커밋마다 연결한 데이터나 의존성, 환경 변수가 달라지면 코드 변경의 효과와 환경 차이가 섞입니다. 빌드가 안 되어 해당 증상을 시험하지 못한 커밋은 증상이 재현된 커밋과 구분합니다. Git 문서도 시험할 수 없는 커밋을 건너뛰는 경로를 제공하며, 확인할 수 없는 구간이 남으면 원인 커밋을 하나로 확정하지 못할 수 있습니다.

수정이 반복될수록 재현 보고서와 검증 기록을 최신 코드에 맞춰 갱신하는 편이 좋습니다. 새 세션에는 현상, 고정한 입력, 확인한 사실, 반박한 가설, 아직 필요한 관측을 전달합니다. 다음 수정이 해결할 과제와 그 결과를 판정할 기준이 같은 자료에 남습니다.

자료 확인 기준: 2026년 10월 28일. 메모 앱의 증상과 가설 표는 설명용 가정이며 실제 앱 재현·로그 수집·코드 수정·회귀 탐색은 수행하지 않았습니다.

관련 글