AI 리뷰어가 통과시킨 버그, 팀이 설계해야 할 검증의 눈

AI 리뷰어가 통과시킨 버그, 팀이 설계해야 할 검증의 눈

두 개의 AI 코드 리뷰어가 '안전하다'고 승인한 PR 안에 2.35배 오버카운팅 버그가 살아 있었다—코드가 내부적으로 일관될수록 측정 없이는 읽을 수 없는 결함이 있다.

AI 코드 리뷰 Claude Code 버그 토큰 오버카운팅 코드 검증 AI-First 팀 리뷰 자동화 한계 개발자 역할 재정의
광고

30,000개 이상의 스타를 받은 Claude Code 템플릿 저장소가 토큰 사용량을 2.35배 부풀려 계산하고 있었다. 버그의 구조는 단순하다. Claude Code는 하나의 어시스턴트 메시지를 여러 JSONL 레코드로 기록한다—thinking, text, tool_use 블록마다 각각. 문제는 각 레코드에 동일한 message.id와 바이트 단위로 동일한 usage 객체가 반복된다는 점이다. calculateRealTokenUsage()는 이를 메시지 단위가 아닌 레코드 단위로 합산했고, 결과적으로 토큰 카운트는 평균 블록 수만큼 곱해진 수치가 됐다.

더 날카로운 사실은 따로 있다. Anthropic의 공식 SDK 문서에는 이 동작이 경고 박스로 명시돼 있다. "병렬 툴 호출은 동일한 id와 동일한 usage를 공유하는 여러 어시스턴트 메시지를 생성한다. 정확한 토큰 카운트를 얻으려면 항상 ID로 중복 제거하라." 문서는 seenIds 구현 예시까지 함께 제공한다. 버그는 숨어 있지 않았다. 문서가 경고했고, 관련 이슈(#6805)도 공개돼 있었고, 동일 문제를 해결한 다른 트래커 구현체도 있었다. 그럼에도 이 코드는 함수가 처음 작성된 날부터 틀린 숫자를 뱉고 있었다.

이 사례가 AI 코드 리뷰 논의에서 중요한 이유는 PR에 달린 두 AI 리뷰어의 반응 때문이다. Greptile는 "Confidence Score: 5/5, 머지해도 안전하다"고 승인했다. cubic은 두 번 실행됐고, 두 번째 패스에서는 이슈 1건으로 줄었다. 흥미롭게도 cubic이 잡아낸 것은 id 필드에 uuid가 혼입될 경우 발생할 수 있는 키 충돌 가능성이었다—실제로는 거의 발생하지 않는 엣지 케이스였지만, 리뷰어 입장에서는 정당한 지적이다. 두 도구 모두 몇 분 전에 작성된 코드의 가상 충돌 시나리오를 추론할 만큼 코드를 면밀히 읽었다. 하지만 함수가 처음 만들어진 날부터 실제 숫자를 2배 이상 틀리게 계산해왔다는 사실은 둘 다 언급하지 않았다.

이 결과는 AI 리뷰어의 실패가 아니다. 각 도구가 적용한 기준으로는 둘 다 정답을 냈다. diff 범위 리뷰어가 답해야 할 질문은 "이 변경사항이 안전하고 자기 일관성이 있는가"이다. 기존 버그는 diff에 없었고, 리뷰 컨텍스트 어디에도 올바른 숫자가 얼마인지를 알 수 있는 외부 측정값이 없었다. dev.to에 기고된 원문 분석이 정확히 짚듯, cubic의 지적은 코드 형태에 대한 가설이었고, 실제 버그는 숫자와 현실 사이의 불일치였다. 후자를 발견하려면 저장소 외부의 증거가 필요하다. 코드베이스 전체를 컨텍스트에 넣고 읽는 리뷰어라도 이 버그는 잡지 못한다. 코드는 내부적으로 완전히 일관성이 있기 때문이다—코드는 자신이 하겠다고 말한 것을 정확히 하고 있고, 그 말 자체가 틀렸을 뿐이다.

이 비대칭은 AI-First 팀이 코드 리뷰 자동화를 설계할 때 놓치기 가장 쉬운 지점이다. "AI 리뷰어를 붙였으니 됐다"는 판단은 리뷰어가 답할 수 있는 질문의 범위를 과대평가한 결과다. AI 리뷰어는 코드의 구조적 일관성, 변경의 안전성, 알려진 패턴으로부터의 일탈을 잘 탐지한다. 그러나 코드가 실제 세계에서 올바른 값을 생산하는지는 측정 없이 판단할 수 없다. 문서에 경고가 적혀 있어도 코드가 그 경고를 위반하고 있다는 사실을 읽어낼 수는 없다. 그 간격은 AI 리뷰어의 한계가 아니라, 우리가 AI 리뷰어에게 묻는 질문의 한계다.

그렇다면 팀이 설계해야 할 검증의 눈은 어디에 있는가. 원문 저자는 간결하게 답한다. messagesWithUsage는 고유한 message.id의 수와 같아야 한다. 이 단언은 코퍼스도, 픽스처도, 골든 파일도 필요 없다. 함수가 처음 작성된 날부터 존재할 수 있었던 어서션이다. 그리고 이 어서션은 AI 리뷰어가 아니라 사람이 설계해야 한다—외부 명세와 내부 계산 사이의 의미론적 갭을 이해하는 사람만이 무엇을 측정해야 하는지 알 수 있기 때문이다. 2026년 개발 트렌드를 다룬 분석이 말하듯, 엔지니어의 역할은 코드를 생산하는 것에서 시스템을 감사하는 것으로 이동하고 있다. 이 사례는 그 명제의 가장 구체적인 예시다.

AI-First 팀 리빌딩 관점에서 이 사례가 주는 설계 지침은 세 가지로 정리된다. 첫째, AI 코드 리뷰어를 PR 게이트로 설정할 때는 그 도구가 답할 수 있는 질문의 범위를 팀이 명시적으로 정의해야 한다. 구조적 일관성 검사와 의미론적 정확성 검사는 다른 계층이다. 둘째, AI가 생성하거나 AI가 리뷰한 코드에서 수치를 다루는 함수가 있다면, 그 함수의 출력이 외부 정의와 일치하는지를 검증하는 어서션을 사람이 설계해야 한다. 문서를 읽고, 명세를 이해하고, 측정 기준을 정의하는 것은 여전히 사람의 몫이다. 셋째, PR 게이트에 테스트 스위트가 없다면 AI 리뷰어 승인은 안전 신호가 아니다. 원문이 지적하듯 해당 저장소는 PR에 테스트를 실행하지 않았고, AI 리뷰어 두 개가 승인 도장을 찍었으며, 10일이 지나도록 인간 리뷰어는 응답하지 않았다. 그 침묵도 하나의 정보였다.

"코드는 내부적으로 일관성이 있다—코드는 자신이 하겠다고 말한 것을 정확히 하고 있고, 그 말 자체가 틀렸을 뿐이다." AI 생성물과 AI 리뷰어가 함께 작동하는 워크플로우에서 가장 위험한 버그는 이 유형이다. 아무도 거짓말하지 않았고, 모든 도구가 제 역할을 했으며, 숫자만 2배 이상 틀렸다. 팀이 설계해야 할 검증의 눈은 코드를 더 꼼꼼히 읽는 능력이 아니라, 코드 바깥에서 코드에게 올바른 질문을 던지는 능력이다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요